Fixed most errors in block package
This commit is contained in:
@@ -10,7 +10,6 @@ uniform vec3 u_ambientColor;
|
|||||||
varying vec4 v_col;
|
varying vec4 v_col;
|
||||||
|
|
||||||
const vec3 ambientColor = vec3(1.0);
|
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 diffuse = vec3(0.2);
|
||||||
const vec3 v1 = vec3(1.0, 0.0, 1.0);
|
const vec3 v1 = vec3(1.0, 0.0, 1.0);
|
||||||
const vec3 v2 = vec3(1.0, 0.5, 0.0);
|
const vec3 v2 = vec3(1.0, 0.5, 0.0);
|
||||||
|
|||||||
@@ -409,6 +409,7 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{
|
|||||||
public void offloadNear(Item item){
|
public void offloadNear(Item item){
|
||||||
Array<Tilec> proximity = proximity();
|
Array<Tilec> proximity = proximity();
|
||||||
int dump = rotation();
|
int dump = rotation();
|
||||||
|
useContent(item);
|
||||||
|
|
||||||
for(int i = 0; i < proximity.size; i++){
|
for(int i = 0; i < proximity.size; i++){
|
||||||
incrementDump(proximity.size);
|
incrementDump(proximity.size);
|
||||||
@@ -544,8 +545,8 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getProgressIncrease(Tilec entity, float baseTime){
|
public float getProgressIncrease(float baseTime){
|
||||||
return 1f / baseTime * entity.delta() * entity.efficiency();
|
return 1f / baseTime * delta() * efficiency();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return whether this block should play its active sound.*/
|
/** @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. */
|
/** Called when arbitrary configuration is applied to a tile. */
|
||||||
public void configured(@Nullable Playerc player, @Nullable Object value){
|
public void configured(@Nullable Playerc player, @Nullable Object value){
|
||||||
//null is of type Void.class; anonymous classes use their superclass.
|
//null is of type Void.class; anonymous classes use their superclass.
|
||||||
|
|||||||
@@ -51,10 +51,10 @@ public class EventType{
|
|||||||
public static class MapPublishEvent{}
|
public static class MapPublishEvent{}
|
||||||
|
|
||||||
public static class CommandIssueEvent{
|
public static class CommandIssueEvent{
|
||||||
public final Tile tile;
|
public final Tilec tile;
|
||||||
public final UnitCommand command;
|
public final UnitCommand command;
|
||||||
|
|
||||||
public CommandIssueEvent(Tile tile, UnitCommand command){
|
public CommandIssueEvent(Tilec tile, UnitCommand command){
|
||||||
this.tile = tile;
|
this.tile = tile;
|
||||||
this.command = command;
|
this.command = command;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ public class Block extends UnlockableContent{
|
|||||||
//TODO move
|
//TODO move
|
||||||
public static TextureRegion[][] cracks;
|
public static TextureRegion[][] cracks;
|
||||||
protected static final Array<Tile> tempTiles = new Array<>();
|
protected static final Array<Tile> tempTiles = new Array<>();
|
||||||
|
protected static final Array<Tilec> tempTileEnts = new Array<>();
|
||||||
|
|
||||||
/** Dump timer ID.*/
|
/** Dump timer ID.*/
|
||||||
protected final int timerDump = timers++;
|
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){
|
public void drawLayer(Tile tile){
|
||||||
if(tile.entity != null) tile.entity.drawLayer();
|
if(tile.entity != null) tile.entity.drawLayer();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public interface Autotiler{
|
|||||||
return buildBlending(req.tile(), req.rotation, directionals, req.worldContext);
|
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;
|
int[] blendresult = AutotilerHolder.blendresult;
|
||||||
blendresult[0] = 0;
|
blendresult[0] = 0;
|
||||||
blendresult[1] = blendresult[2] = 1;
|
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);
|
int realDir = Mathf.mod(rotation - direction, 4);
|
||||||
if(directional != null && directional[realDir] != null){
|
if(directional != null && directional[realDir] != null){
|
||||||
BuildRequest req = directional[realDir];
|
BuildRequest req = directional[realDir];
|
||||||
@@ -82,21 +82,21 @@ public interface Autotiler{
|
|||||||
return checkWorld && blends(tile, rotation, direction);
|
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));
|
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)
|
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 &&
|
|| ((!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))));
|
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)
|
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)));
|
|| (!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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,27 +49,27 @@ public class BuildBlock extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Remote(called = Loc.server)
|
@Remote(called = Loc.server)
|
||||||
public static void onDeconstructFinish(Block block, int builderID){
|
public static void onDeconstructFinish(Tile tile, Block block, int builderID){
|
||||||
Team team = team;
|
Team team = tile.team();
|
||||||
Fx.breakBlock.at(x, y, block.size);
|
Fx.breakBlock.at(tile.drawx(), tile.drawy(), block.size);
|
||||||
Events.fire(new BlockBuildEndEvent(tile, Groups.unit.getByID(builderID), team, true));
|
Events.fire(new BlockBuildEndEvent(tile, Groups.unit.getByID(builderID), team, true));
|
||||||
tile.remove();
|
tile.remove();
|
||||||
if(shouldPlay()) Sounds.breaks.at(tile, calcPitch(false));
|
if(shouldPlay()) Sounds.breaks.at(tile, calcPitch(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Remote(called = Loc.server)
|
@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;
|
if(tile == null) return;
|
||||||
float healthf = tile.healthf();
|
float healthf = tile.entity.healthf();
|
||||||
tile.setBlock(block, team, (int)rotation);
|
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()
|
//last builder was this local client player, call placed()
|
||||||
if(!headless && builderID == player.unit().id()){
|
if(!headless && builderID == player.unit().id()){
|
||||||
if(!skipConfig){
|
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(){
|
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);
|
Call.onConstructFinish(tile, block, builderID, rotation, team, skipConfig);
|
||||||
tile.placed();
|
tile.entity.placed();
|
||||||
|
|
||||||
Events.fire(new BlockBuildEndEvent(tile, Groups.unit.getByID(builderID), team, false));
|
Events.fire(new BlockBuildEndEvent(tile, Groups.unit.getByID(builderID), team, false));
|
||||||
if(shouldPlay()) Sounds.place.at(tile, calcPitch(true));
|
if(shouldPlay()) Sounds.place.at(tile, calcPitch(true));
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ public class ArmoredConveyor extends Conveyor{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean blends(int rotation, int otherx, int othery, int otherrot, Block otherblock) {
|
public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock) {
|
||||||
return otherblock.outputsItems() && blendsArmored(rotation, otherx, othery, otherrot, otherblock);
|
return otherblock.outputsItems() && blendsArmored(tile, rotation, otherx, othery, otherrot, otherblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ArmoredConveyorEntity extends ConveyorEntity{
|
public class ArmoredConveyorEntity extends ConveyorEntity{
|
||||||
|
|||||||
@@ -76,8 +76,8 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean blends(int rotation, int otherx, int othery, int otherrot, Block otherblock){
|
public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){
|
||||||
return otherblock.outputsItems() && lookingAt(rotation, otherx, othery, otherrot, otherblock);
|
return otherblock.outputsItems() && lookingAt(tile, rotation, otherx, othery, otherrot, otherblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -138,7 +138,7 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
public void onProximityUpdate(){
|
public void onProximityUpdate(){
|
||||||
super.onProximityUpdate();
|
super.onProximityUpdate();
|
||||||
|
|
||||||
int[] bits = buildBlending(rotation(), null, true);
|
int[] bits = buildBlending(tile, rotation(), null, true);
|
||||||
blendbits = bits[0];
|
blendbits = bits[0];
|
||||||
blendsclx = bits[1];
|
blendsclx = bits[1];
|
||||||
blendscly = bits[2];
|
blendscly = bits[2];
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ public class MassDriver extends Block{
|
|||||||
hasPower = true;
|
hasPower = true;
|
||||||
outlineIcon = true;
|
outlineIcon = true;
|
||||||
//point2 is relative
|
//point2 is relative
|
||||||
config(Point2.class, (tile, point) -> tile.<MassDriverEntity>ent().link = Point2.pack(point.x + tile.x, point.y + tile.y));
|
config(Point2.class, (tile, point) -> ((MassDriverEntity)tile).link = Point2.pack(point.x + tile.tileX(), point.y + tile.tileY()));
|
||||||
config(Integer.class, (tile, point) -> tile.<MassDriverEntity>ent().link = point);
|
config(Integer.class, (tile, point) -> ((MassDriverEntity)tile).link = point);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -57,114 +57,20 @@ public class MassDriver extends Block{
|
|||||||
baseRegion = Core.atlas.find(name + "-base");
|
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
|
@Override
|
||||||
public void drawPlace(int x, int y, int rotation, boolean valid){
|
public void drawPlace(int x, int y, int rotation, boolean valid){
|
||||||
Drawf.dashCircle(x * tilesize, y*tilesize, range, Pal.accent);
|
Drawf.dashCircle(x * tilesize, y*tilesize, range, Pal.accent);
|
||||||
|
|
||||||
//check if a mass driver is selected while placing this driver
|
//check if a mass driver is selected while placing this driver
|
||||||
if(!control.input.frag.config.isShown()) return;
|
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(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
|
//if so, draw a dotted line towards it while it is in range
|
||||||
float sin = Mathf.absin(Time.time(), 6f, 1f);
|
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,
|
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);
|
int segs = (int)(selected.dst(x * tilesize, y * tilesize) / tilesize);
|
||||||
|
|
||||||
Lines.stroke(4f, Pal.gray);
|
Lines.stroke(4f, Pal.gray);
|
||||||
@@ -174,119 +80,6 @@ public class MassDriver extends Block{
|
|||||||
Draw.reset();
|
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 class DriverBulletData implements Poolable{
|
||||||
public MassDriverEntity from, to;
|
public MassDriverEntity from, to;
|
||||||
public int[] items = new int[content.items().size];
|
public int[] items = new int[content.items().size];
|
||||||
@@ -309,8 +102,209 @@ public class MassDriver extends Block{
|
|||||||
return waitingShooters.isEmpty() ? null : waitingShooters.first();
|
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){
|
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
|
@Override
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ public class ArmoredConduit extends Conduit{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean blends(int rotation, int otherx, int othery, int otherrot, Block otherblock){
|
public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){
|
||||||
return otherblock.outputsLiquid && blendsArmored(rotation, otherx, othery, otherrot, otherblock);
|
return otherblock.outputsLiquid && blendsArmored(tile, rotation, otherx, othery, otherrot, otherblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ArmoredConduitEntity extends TileEntity{
|
public class ArmoredConduitEntity extends TileEntity{
|
||||||
|
|||||||
@@ -74,8 +74,8 @@ public class Conduit extends LiquidBlock implements Autotiler{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean blends(int rotation, int otherx, int othery, int otherrot, Block otherblock){
|
public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){
|
||||||
return otherblock.hasLiquids && otherblock.outputsLiquid && lookingAt(rotation, otherx, othery, otherrot, otherblock);
|
return otherblock.hasLiquids && otherblock.outputsLiquid && lookingAt(tile, rotation, otherx, othery, otherrot, otherblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -106,7 +106,7 @@ public class Conduit extends LiquidBlock implements Autotiler{
|
|||||||
public void onProximityUpdate(){
|
public void onProximityUpdate(){
|
||||||
super.onProximityUpdate();
|
super.onProximityUpdate();
|
||||||
|
|
||||||
blendbits = buildBlending(rotation(), null, true)[0];
|
blendbits = buildBlending(tile, rotation(), null, true)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -128,10 +128,10 @@ public class PowerNode extends PowerBlock{
|
|||||||
Drawf.circles(x * tilesize + offset(), y * tilesize + offset(), laserRange * tilesize);
|
Drawf.circles(x * tilesize + offset(), y * tilesize + offset(), laserRange * tilesize);
|
||||||
|
|
||||||
getPotentialLinks(tile, other -> {
|
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 -> {
|
insulators(tile.x, tile.y, other.tileX(), other.tileY(), cause -> {
|
||||||
Drawf.square(cause.drawx(), cause.drawy(), cause.block().size * tilesize / 2f + 2f, Pal.plastanium);
|
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));
|
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){
|
protected boolean overlaps(Tile src, Tile other, float range){
|
||||||
return overlaps(src.drawx(), src.drawy(), other, range);
|
return overlaps(src.drawx(), src.drawy(), other, range);
|
||||||
}
|
}
|
||||||
@@ -177,26 +181,26 @@ public class PowerNode extends PowerBlock{
|
|||||||
protected void getPotentialLinks(Tile tile, Cons<Tilec> others){
|
protected void getPotentialLinks(Tile tile, Cons<Tilec> others){
|
||||||
Boolf<Tilec> valid = other -> other != null && other.tile() != tile && other.power() != null &&
|
Boolf<Tilec> 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) &&
|
((!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()
|
overlaps(tile.x * tilesize + offset(), tile.y * tilesize + offset(), other.tile(), laserRange * tilesize) && other.team() == player.team()
|
||||||
&& !other.proximity().contains(tile) && !graphs.contains(other.power().graph);
|
&& !other.proximity().contains(e -> e.tile() == tile) && !graphs.contains(other.power().graph);
|
||||||
|
|
||||||
tempTiles.clear();
|
tempTileEnts.clear();
|
||||||
graphs.clear();
|
graphs.clear();
|
||||||
Geometry.circle(tile.x, tile.y, (int)(laserRange + 2), (x, y) -> {
|
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) && !tempTiles.contains(other)){
|
if(valid.get(other) && !tempTileEnts.contains(other)){
|
||||||
tempTiles.add(other);
|
tempTileEnts.add(other);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
tempTiles.sort((a, b) -> {
|
tempTileEnts.sort((a, b) -> {
|
||||||
int type = -Boolean.compare(a.block() instanceof PowerNode, b.block() instanceof PowerNode);
|
int type = -Boolean.compare(a.block() instanceof PowerNode, b.block() instanceof PowerNode);
|
||||||
if(type != 0) return type;
|
if(type != 0) return type;
|
||||||
return Float.compare(a.dst2(tile), b.dst2(tile));
|
return Float.compare(a.dst2(tile), b.dst2(tile));
|
||||||
});
|
});
|
||||||
|
|
||||||
tempTiles.each(valid, t -> {
|
tempTileEnts.each(valid, t -> {
|
||||||
graphs.add(t.power.graph);
|
graphs.add(t.power().graph);
|
||||||
others.get(t);
|
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){
|
public static boolean insulated(Tilec tile, Tilec other){
|
||||||
return insulated(tile.tileX(), tile.tileY(), other.tileX(), other.tileY());
|
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.block().outputsPower && !other.block().consumesPower) || other.block() instanceof PowerNode) && linkValid(this, other)
|
||||||
&& !other.proximity().contains(this) && other.power().graph != power.graph;
|
&& !other.proximity().contains(this) && other.power().graph != power.graph;
|
||||||
|
|
||||||
tempTiles.clear();
|
tempTileEnts.clear();
|
||||||
Geometry.circle(tile.x, tile.y, (int)(laserRange + 2), (x, y) -> {
|
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(valid.get(other)){
|
||||||
if(!insulated(tile, other)){
|
if(!insulated(this, other)){
|
||||||
tempTiles.add(other);
|
tempTileEnts.add(other);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
tempTiles.sort((a, b) -> {
|
tempTileEnts.sort((a, b) -> {
|
||||||
int type = -Boolean.compare(a.block() instanceof PowerNode, b.block() instanceof PowerNode);
|
int type = -Boolean.compare(a.block() instanceof PowerNode, b.block() instanceof PowerNode);
|
||||||
if(type != 0) return type;
|
if(type != 0) return type;
|
||||||
return Float.compare(a.dst2(tile), b.dst2(tile));
|
return Float.compare(a.dst2(tile), b.dst2(tile));
|
||||||
});
|
});
|
||||||
tempTiles.each(valid, other -> {
|
tempTileEnts.each(valid, other -> {
|
||||||
if(!tile.power.links.contains(other.pos())){
|
if(!power.links.contains(other.pos())){
|
||||||
tile.configureAny(other.pos());
|
tile.configureAny(other.pos());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -277,24 +301,21 @@ public class PowerNode extends PowerBlock{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateTile(){
|
public void updateTile(){
|
||||||
tile.power.graph.update();
|
power.graph.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onConfigureTileTapped(Tile other){
|
public boolean onConfigureTileTapped(Tilec other){
|
||||||
Tilec entity = tile.ent();
|
if(linkValid(this, other)){
|
||||||
other = other.link();
|
|
||||||
|
|
||||||
if(linkValid(tile, other)){
|
|
||||||
tile.configure(other.pos());
|
tile.configure(other.pos());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tile == other){
|
if(this == other){
|
||||||
if(other.power.links.size == 0){
|
if(other.power().links.size == 0){
|
||||||
int[] total = {0};
|
int[] total = {0};
|
||||||
getPotentialLinks(tile, link -> {
|
getPotentialLinks(tile, link -> {
|
||||||
if(!insulated(tile, link) && total[0]++ < maxNodes){
|
if(!insulated(this, link) && total[0]++ < maxNodes){
|
||||||
tile.configure(link.pos());
|
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 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++){
|
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)){
|
if(link != this && linkValid(this, link, false)){
|
||||||
boolean linked = linked(tile, link);
|
boolean linked = linked(link);
|
||||||
|
|
||||||
if(linked){
|
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();
|
Tilec entity = tile.ent();
|
||||||
|
|
||||||
for(int i = 0; i < power.links.size; i++){
|
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;
|
if(link.block() instanceof PowerNode && !(link.pos() < tile.pos())) continue;
|
||||||
|
|
||||||
drawLaser(tile, link);
|
drawLaserTo(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean linked(Tile other){
|
protected boolean linked(Tilec other){
|
||||||
return tile.power.links.contains(other.pos());
|
return power.links.contains(other.pos());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean linkValid(Tilec tile, Tilec link){
|
protected void drawLaserTo(Tilec target){
|
||||||
return linkValid(tile, link, true);
|
drawLaser(x, y, target.x(), target.y(), power.graph.getSatisfaction(), size, target.block().size);
|
||||||
}
|
|
||||||
|
|
||||||
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.<PowerNode>cblock().laserRange * tilesize))){
|
|
||||||
if(checkMaxNodes && link.block() instanceof PowerNode){
|
|
||||||
return link.power.links.size < link.<PowerNode>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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -7,14 +7,10 @@ import arc.math.*;
|
|||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.io.*;
|
import arc.util.io.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.gen.*;
|
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
import mindustry.world.*;
|
|
||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
|
|
||||||
public class Cultivator extends GenericCrafter{
|
public class Cultivator extends GenericCrafter{
|
||||||
public Color plantColor = Color.valueOf("5541b1");
|
public Color plantColor = Color.valueOf("5541b1");
|
||||||
public Color plantColorLight = Color.valueOf("7457ce");
|
public Color plantColorLight = Color.valueOf("7457ce");
|
||||||
@@ -38,13 +34,6 @@ public class Cultivator extends GenericCrafter{
|
|||||||
topRegion = Core.atlas.find(name + "-top");
|
topRegion = Core.atlas.find(name + "-top");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateTile(){
|
|
||||||
super.updateTile();
|
|
||||||
|
|
||||||
warmup = Mathf.lerpDelta(warmup, consValid() ? 1f : 0f, 0.015f);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBars(){
|
public void setBars(){
|
||||||
super.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);
|
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
|
@Override
|
||||||
public TextureRegion[] generateIcons(){
|
public TextureRegion[] generateIcons(){
|
||||||
return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-top"),};
|
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 class CultivatorEntity extends GenericCrafterEntity{
|
||||||
public float warmup;
|
public float warmup;
|
||||||
public float boost;
|
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
|
@Override
|
||||||
public void write(Writes write){
|
public void write(Writes write){
|
||||||
super.write(write);
|
super.write(write);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package mindustry.world.blocks.production;
|
package mindustry.world.blocks.production;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.struct.*;
|
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
@@ -62,7 +62,7 @@ public class Drill extends Block{
|
|||||||
hasLiquids = true;
|
hasLiquids = true;
|
||||||
liquidCapacity = 5f;
|
liquidCapacity = 5f;
|
||||||
hasItems = true;
|
hasItems = true;
|
||||||
idleSound = Sounds.drill;
|
idleSound = Sounds.drill;
|
||||||
idleSoundVolume = 0.003f;
|
idleSoundVolume = 0.003f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ public class Drill extends Block{
|
|||||||
bars.add("drillspeed", e -> {
|
bars.add("drillspeed", e -> {
|
||||||
DrillEntity entity = (DrillEntity)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");
|
topRegion = Core.atlas.find(name + "-top");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public Item getDrop(Tile tile){
|
||||||
public void drawCracks(){}
|
return tile.drop();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(){
|
public boolean canPlaceOn(Tile tile){
|
||||||
float s = 0.3f;
|
if(isMultiblock()){
|
||||||
float ts = 0.6f;
|
for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){
|
||||||
|
if(canMine(other)){
|
||||||
Draw.rect(region, x, y);
|
return true;
|
||||||
super.drawCracks();
|
}
|
||||||
|
}
|
||||||
if(drawRim){
|
return false;
|
||||||
Draw.color(heatColor);
|
}else{
|
||||||
Draw.alpha(warmup * ts * (1f - s + Mathf.absin(Time.time(), 3f, s)));
|
return canMine(tile);
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@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
|
@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
|
@Override
|
||||||
public void setStats(){
|
public void setStats(){
|
||||||
super.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;
|
returnItem = null;
|
||||||
returnCount = 0;
|
returnCount = 0;
|
||||||
|
|
||||||
@@ -203,7 +169,7 @@ public class Drill extends Block{
|
|||||||
itemArray.clear();
|
itemArray.clear();
|
||||||
|
|
||||||
for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){
|
for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){
|
||||||
if(isValid(other)){
|
if(canMine(other)){
|
||||||
oreCount.getAndIncrement(getDrop(other), 0, 1);
|
oreCount.getAndIncrement(getDrop(other), 0, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,84 +194,7 @@ public class Drill extends Block{
|
|||||||
returnCount = oreCount.get(itemArray.peek(), 0);
|
returnCount = oreCount.get(itemArray.peek(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public boolean canMine(Tile tile){
|
||||||
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(){
|
|
||||||
if(tile == null) return false;
|
if(tile == null) return false;
|
||||||
Item drops = tile.drop();
|
Item drops = tile.drop();
|
||||||
return drops != null && drops.hardness <= tier;
|
return drops != null && drops.hardness <= tier;
|
||||||
@@ -320,6 +209,112 @@ public class Drill extends Block{
|
|||||||
|
|
||||||
int dominantItems;
|
int dominantItems;
|
||||||
Item dominantItem;
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package mindustry.world.blocks.production;
|
|||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import mindustry.world.*;
|
|
||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
|
|
||||||
public class Fracker extends SolidPump{
|
public class Fracker extends SolidPump{
|
||||||
@@ -38,54 +37,54 @@ public class Fracker extends SolidPump{
|
|||||||
return false;
|
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
|
@Override
|
||||||
public TextureRegion[] generateIcons(){
|
public TextureRegion[] generateIcons(){
|
||||||
return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-rotator"), Core.atlas.find(name + "-top")};
|
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 class FrackerEntity extends SolidPumpEntity{
|
||||||
public float accumulator;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,97 +55,97 @@ public class GenericCrafter extends Block{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean shouldIdleSound(Tilec tile){
|
|
||||||
return tile.cons().valid();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(){
|
public void init(){
|
||||||
outputsLiquid = outputLiquid != null;
|
outputsLiquid = outputLiquid != null;
|
||||||
super.init();
|
super.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw(){
|
|
||||||
if(drawer == null){
|
|
||||||
super.draw();
|
|
||||||
}else{
|
|
||||||
drawer.get(tile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TextureRegion[] generateIcons(){
|
public TextureRegion[] generateIcons(){
|
||||||
return drawIcons == null ? super.generateIcons() : drawIcons.get();
|
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
|
@Override
|
||||||
public boolean outputsItems(){
|
public boolean outputsItems(){
|
||||||
return outputItem != null;
|
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 class GenericCrafterEntity extends TileEntity{
|
||||||
public float progress;
|
public float progress;
|
||||||
public float totalProgress;
|
public float totalProgress;
|
||||||
public float warmup;
|
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
|
@Override
|
||||||
public void write(Writes write){
|
public void write(Writes write){
|
||||||
super.write(write);
|
super.write(write);
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import arc.graphics.*;
|
|||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.world.*;
|
|
||||||
|
|
||||||
import static mindustry.Vars.renderer;
|
import static mindustry.Vars.renderer;
|
||||||
|
|
||||||
@@ -24,30 +23,32 @@ public class GenericSmelter extends GenericCrafter{
|
|||||||
topRegion = Core.atlas.find(name + "-top");
|
topRegion = Core.atlas.find(name + "-top");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public class SmelterEntity extends GenericCrafterEntity{
|
||||||
public void draw(){
|
@Override
|
||||||
super.draw();
|
public void draw(){
|
||||||
|
super.draw();
|
||||||
|
|
||||||
//draw glowing center
|
//draw glowing center
|
||||||
if(warmup > 0f && flameColor.a > 0.001f){
|
if(warmup > 0f && flameColor.a > 0.001f){
|
||||||
float g = 0.3f;
|
float g = 0.3f;
|
||||||
float r = 0.06f;
|
float r = 0.06f;
|
||||||
float cr = Mathf.random(0.1f);
|
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);
|
Draw.tint(flameColor);
|
||||||
Fill.circle(x, y, 3f + Mathf.absin(Time.time(), 5f, 2f) + cr);
|
Fill.circle(x, y, 3f + Mathf.absin(Time.time(), 5f, 2f) + cr);
|
||||||
Draw.color(1f, 1f, 1f, warmup);
|
Draw.color(1f, 1f, 1f, warmup);
|
||||||
Draw.rect(topRegion, x, y);
|
Draw.rect(topRegion, x, y);
|
||||||
Fill.circle(x, y, 1.9f + Mathf.absin(Time.time(), 5f, 1f) + cr);
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,14 @@
|
|||||||
package mindustry.world.blocks.production;
|
package mindustry.world.blocks.production;
|
||||||
|
|
||||||
import arc.graphics.Color;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.Draw;
|
import arc.graphics.g2d.*;
|
||||||
import arc.graphics.g2d.Fill;
|
import arc.math.*;
|
||||||
import arc.math.Mathf;
|
import arc.util.*;
|
||||||
import arc.util.Time;
|
import mindustry.content.*;
|
||||||
import mindustry.content.Fx;
|
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.type.Item;
|
import mindustry.type.*;
|
||||||
import mindustry.type.Liquid;
|
import mindustry.world.*;
|
||||||
import mindustry.world.Block;
|
|
||||||
import mindustry.world.Tile;
|
|
||||||
|
|
||||||
public class Incinerator extends Block{
|
public class Incinerator extends Block{
|
||||||
public Effect effect = Fx.fuelburn;
|
public Effect effect = Fx.fuelburn;
|
||||||
@@ -25,59 +22,59 @@ public class Incinerator extends Block{
|
|||||||
solid = true;
|
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 class IncineratorEntity extends TileEntity{
|
||||||
public float heat;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
package mindustry.world.blocks.production;
|
package mindustry.world.blocks.production;
|
||||||
|
|
||||||
import mindustry.world.Tile;
|
import mindustry.world.consumers.*;
|
||||||
import mindustry.world.consumers.ConsumeLiquidBase;
|
import mindustry.world.meta.*;
|
||||||
import mindustry.world.consumers.ConsumeType;
|
|
||||||
import mindustry.world.meta.BlockStat;
|
|
||||||
|
|
||||||
public class LiquidConverter extends GenericCrafter{
|
public class LiquidConverter extends GenericCrafter{
|
||||||
|
|
||||||
@@ -32,29 +30,31 @@ public class LiquidConverter extends GenericCrafter{
|
|||||||
stats.add(BlockStat.output, outputLiquid.liquid, outputLiquid.amount * craftTime, false);
|
stats.add(BlockStat.output, outputLiquid.liquid, outputLiquid.amount * craftTime, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public class LiquidConverterEntity extends GenericCrafterEntity{
|
||||||
public void drawLight(){
|
@Override
|
||||||
if(hasLiquids && drawLiquidLight && outputLiquid.liquid.lightColor.a > 0.001f){
|
public void drawLight(){
|
||||||
drawLiquidLight(tile, outputLiquid.liquid, tile.liquids.get(outputLiquid.liquid));
|
if(hasLiquids && drawLiquidLight && outputLiquid.liquid.lightColor.a > 0.001f){
|
||||||
}
|
drawLiquidLight(outputLiquid.liquid, 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,18 @@
|
|||||||
package mindustry.world.blocks.production;
|
package mindustry.world.blocks.production;
|
||||||
|
|
||||||
import arc.Core;
|
import arc.*;
|
||||||
import arc.struct.Array;
|
import arc.graphics.*;
|
||||||
import arc.graphics.Color;
|
import arc.graphics.g2d.*;
|
||||||
import arc.graphics.g2d.Draw;
|
import mindustry.graphics.*;
|
||||||
import arc.graphics.g2d.TextureRegion;
|
import mindustry.type.*;
|
||||||
import mindustry.graphics.Layer;
|
import mindustry.ui.*;
|
||||||
import mindustry.type.Liquid;
|
import mindustry.world.*;
|
||||||
import mindustry.ui.Cicon;
|
import mindustry.world.blocks.liquid.*;
|
||||||
import mindustry.world.Tile;
|
|
||||||
import mindustry.world.blocks.liquid.LiquidBlock;
|
|
||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
|
|
||||||
import static mindustry.Vars.tilesize;
|
import static mindustry.Vars.*;
|
||||||
import static mindustry.Vars.world;
|
|
||||||
|
|
||||||
public class Pump extends LiquidBlock{
|
public class Pump extends LiquidBlock{
|
||||||
protected final Array<Tile> drawTiles = new Array<>();
|
|
||||||
protected final Array<Tile> updateTiles = new Array<>();
|
|
||||||
|
|
||||||
public final int timerContentCheck = timers++;
|
public final int timerContentCheck = timers++;
|
||||||
|
|
||||||
/** Pump amount, total. */
|
/** Pump amount, total. */
|
||||||
@@ -44,16 +38,6 @@ public class Pump extends LiquidBlock{
|
|||||||
stats.add(BlockStat.output, 60f * pumpAmount, StatUnit.liquidSecond);
|
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
|
@Override
|
||||||
public void drawPlace(int x, int y, int rotation, boolean valid) {
|
public void drawPlace(int x, int y, int rotation, boolean valid) {
|
||||||
Tile tile = world.tile(x, y);
|
Tile tile = world.tile(x, y);
|
||||||
@@ -63,7 +47,7 @@ public class Pump extends LiquidBlock{
|
|||||||
Liquid liquidDrop = null;
|
Liquid liquidDrop = null;
|
||||||
|
|
||||||
for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){
|
for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){
|
||||||
if(isValid(other)){
|
if(canPump(other)){
|
||||||
liquidDrop = other.floor().liquidDrop;
|
liquidDrop = other.floor().liquidDrop;
|
||||||
tiles++;
|
tiles++;
|
||||||
}
|
}
|
||||||
@@ -85,10 +69,10 @@ public class Pump extends LiquidBlock{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canPlaceOn(){
|
public boolean canPlaceOn(Tile tile){
|
||||||
if(isMultiblock()){
|
if(isMultiblock()){
|
||||||
Liquid last = null;
|
Liquid last = null;
|
||||||
for(Tile other : tile.getLinkedTilesAs(this, drawTiles)){
|
for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){
|
||||||
if(other.floor().liquidDrop == null)
|
if(other.floor().liquidDrop == null)
|
||||||
continue;
|
continue;
|
||||||
if(other.floor().liquidDrop != last && last != null)
|
if(other.floor().liquidDrop != last && last != null)
|
||||||
@@ -97,41 +81,54 @@ public class Pump extends LiquidBlock{
|
|||||||
}
|
}
|
||||||
return last != null;
|
return last != null;
|
||||||
}else{
|
}else{
|
||||||
return isValid(tile);
|
return canPump(tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected boolean canPump(Tile tile){
|
||||||
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(){
|
|
||||||
return tile != null && tile.floor().liquidDrop != null;
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ import arc.*;
|
|||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
|
import arc.util.io.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.production.GenericCrafter.*;
|
|
||||||
import mindustry.world.consumers.*;
|
import mindustry.world.consumers.*;
|
||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
import mindustry.world.meta.values.*;
|
import mindustry.world.meta.values.*;
|
||||||
@@ -51,64 +52,88 @@ public class Separator extends Block{
|
|||||||
stats.add(BlockStat.productionTime, craftTime / 60f, StatUnit.seconds);
|
stats.add(BlockStat.productionTime, craftTime / 60f, StatUnit.seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public class SeparatorEntity extends TileEntity{
|
||||||
public boolean shouldConsume(){
|
public float progress;
|
||||||
return tile.items.total() < itemCapacity;
|
public float totalProgress;
|
||||||
}
|
public float warmup;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(){
|
public boolean shouldIdleSound(){
|
||||||
super.draw();
|
return cons.valid();
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(progress >= 1f){
|
@Override
|
||||||
progress = 0f;
|
public boolean shouldConsume(){
|
||||||
int sum = 0;
|
return items.total() < itemCapacity;
|
||||||
for(ItemStack stack : results) sum += stack.amount;
|
}
|
||||||
|
|
||||||
int i = Mathf.random(sum);
|
@Override
|
||||||
int count = 0;
|
public void draw(){
|
||||||
Item item = null;
|
super.draw();
|
||||||
|
|
||||||
//TODO guaranteed desync since items are random
|
Draw.color(liquids.current().color);
|
||||||
for(ItemStack stack : results){
|
Draw.alpha(liquids.total() / liquidCapacity);
|
||||||
if(i >= count && i < count + stack.amount){
|
Draw.rect(reg(liquidRegion), x, y);
|
||||||
item = stack.item;
|
|
||||||
break;
|
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(timer(timerDump, dumpTime)){
|
||||||
|
dump();
|
||||||
if(item != null && items.get(item) < itemCapacity){
|
|
||||||
useContent(tile, item);
|
|
||||||
offloadNear(tile, item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(timer(timerDump, dumpTime)){
|
@Override
|
||||||
tryDump(tile);
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,17 @@
|
|||||||
package mindustry.world.blocks.production;
|
package mindustry.world.blocks.production;
|
||||||
|
|
||||||
import arc.Core;
|
import arc.*;
|
||||||
import arc.graphics.g2d.Draw;
|
import arc.graphics.g2d.*;
|
||||||
import arc.graphics.g2d.TextureRegion;
|
import arc.math.*;
|
||||||
import arc.math.Mathf;
|
|
||||||
import arc.util.*;
|
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
import mindustry.content.Fx;
|
import arc.util.*;
|
||||||
import mindustry.content.Liquids;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.graphics.Pal;
|
import mindustry.type.*;
|
||||||
import mindustry.type.Liquid;
|
import mindustry.ui.*;
|
||||||
import mindustry.ui.Bar;
|
import mindustry.world.*;
|
||||||
import mindustry.world.Tile;
|
import mindustry.world.meta.*;
|
||||||
import mindustry.world.meta.Attribute;
|
|
||||||
import mindustry.world.meta.BlockStat;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pump that makes liquid from solids and takes in power. Only works on solid floor blocks.
|
* 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
|
@Override
|
||||||
public void draw(){
|
public boolean canPlaceOn(Tile tile){
|
||||||
Draw.rect(region, x, y);
|
if(isMultiblock()){
|
||||||
Draw.color(tile.liquids.current().color);
|
for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){
|
||||||
Draw.alpha(tile.liquids.total() / liquidCapacity);
|
if(canPump(other)){
|
||||||
Draw.rect(liquidRegion, x, y);
|
return true;
|
||||||
Draw.color();
|
}
|
||||||
Draw.rect(name + "-rotator", x, y, pumpTime * rotateSpeed);
|
}
|
||||||
Draw.rect(name + "-top", x, y);
|
return false;
|
||||||
|
}else{
|
||||||
|
return canPump(tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canPump(Tile tile){
|
||||||
|
return tile != null && !tile.floor().isLiquid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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")};
|
return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-rotator"), Core.atlas.find(name + "-top")};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public class SolidPumpEntity extends PumpEntity{
|
||||||
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 float warmup;
|
public float warmup;
|
||||||
public float pumpTime;
|
public float pumpTime;
|
||||||
public float boost;
|
public float boost;
|
||||||
public float lastPump;
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ public class CoreBlock extends StorageBlock{
|
|||||||
storageCapacity = itemCapacity + proximity().sum(e -> isContainer(e) ? e.block().itemCapacity : 0);
|
storageCapacity = itemCapacity + proximity().sum(e -> isContainer(e) ? e.block().itemCapacity : 0);
|
||||||
proximity.each(this::isContainer, t -> {
|
proximity.each(this::isContainer, t -> {
|
||||||
t.items(items);
|
t.items(items);
|
||||||
((StorageBlockEntity)t).linkedCore = tile;
|
((StorageBlockEntity)t).linkedCore = this;
|
||||||
});
|
});
|
||||||
|
|
||||||
for(Tilec other : state.teams.cores(team)){
|
for(Tilec other : state.teams.cores(team)){
|
||||||
|
|||||||
@@ -1,20 +1,16 @@
|
|||||||
package mindustry.world.blocks.storage;
|
package mindustry.world.blocks.storage;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.graphics.g2d.Draw;
|
import arc.graphics.g2d.*;
|
||||||
import arc.graphics.g2d.Lines;
|
import arc.math.*;
|
||||||
import arc.math.Mathf;
|
import arc.util.*;
|
||||||
import arc.util.Time;
|
import mindustry.*;
|
||||||
import mindustry.Vars;
|
import mindustry.content.*;
|
||||||
import mindustry.content.Fx;
|
|
||||||
import mindustry.gen.*;
|
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.graphics.Pal;
|
import mindustry.gen.*;
|
||||||
import mindustry.type.Item;
|
import mindustry.graphics.*;
|
||||||
import mindustry.type.ItemType;
|
import mindustry.type.*;
|
||||||
import mindustry.world.Tile;
|
import mindustry.world.meta.*;
|
||||||
import mindustry.world.meta.BlockStat;
|
|
||||||
import mindustry.world.meta.StatUnit;
|
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -37,49 +33,50 @@ public class LaunchPad extends StorageBlock{
|
|||||||
stats.add(BlockStat.launchTime, launchTime / 60f, StatUnit.seconds);
|
stats.add(BlockStat.launchTime, launchTime / 60f, StatUnit.seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public class LaunchPadEntity extends StorageBlockEntity{
|
||||||
public boolean acceptItem(Tilec source, Item item){
|
@Override
|
||||||
return item.type == ItemType.material && tile.items.total() < itemCapacity;
|
public void draw(){
|
||||||
}
|
super.draw();
|
||||||
|
|
||||||
@Override
|
//TODO broken
|
||||||
public void draw(){
|
float progress = Mathf.clamp(Mathf.clamp((items.total() / (float)itemCapacity)) * ((timer().getTime(timerLaunch) / (launchTime / timeScale()))));
|
||||||
super.draw();
|
float scale = size / 3f;
|
||||||
|
|
||||||
//TODO broken
|
Lines.stroke(2f);
|
||||||
float progress = Mathf.clamp(Mathf.clamp((tile.items.total() / (float)itemCapacity)) * ((timer().getTime(timerLaunch) / (launchTime / tile.timeScale()))));
|
Draw.color(Pal.accentBack);
|
||||||
float scale = size / 3f;
|
Lines.poly(x, y, 4, scale * 10f * (1f - progress), 45 + 360f * progress);
|
||||||
|
|
||||||
Lines.stroke(2f);
|
Draw.color(Pal.accent);
|
||||||
Draw.color(Pal.accentBack);
|
|
||||||
Lines.poly(x, y, 4, scale * 10f * (1f - progress), 45 + 360f * progress);
|
|
||||||
|
|
||||||
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()){
|
Lines.stroke(((2f * (2f - Math.abs(0.5f - f) * 2f)) - 2f + 0.2f));
|
||||||
for(int i = 0; i < 3; i++){
|
Lines.poly(x, y, 4, (1f - f) * 10f * scale);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Draw.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
Draw.reset();
|
@Override
|
||||||
}
|
public boolean acceptItem(Tilec source, Item item){
|
||||||
|
return item.type == ItemType.material && items.total() < itemCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateTile(){
|
public void updateTile(){
|
||||||
Tilec entity = tile.entity;
|
|
||||||
|
|
||||||
if(state.isCampaign() && consValid() && items.total() >= itemCapacity && timer(timerLaunch, launchTime / timeScale())){
|
if(state.isCampaign() && consValid() && items.total() >= itemCapacity && timer(timerLaunch, launchTime / timeScale())){
|
||||||
for(Item item : Vars.content.items()){
|
for(Item item : Vars.content.items()){
|
||||||
Events.fire(Trigger.itemLaunch);
|
Events.fire(Trigger.itemLaunch);
|
||||||
Fx.padlaunch.at(tile);
|
Fx.padlaunch.at(tile);
|
||||||
int used = Math.min(items.get(item), itemCapacity);
|
int used = Math.min(items.get(item), itemCapacity);
|
||||||
data.addItem(item, used);
|
data.addItem(item, used);
|
||||||
items.remove(item, used);
|
items.remove(item, used);
|
||||||
Events.fire(new LaunchItemEvent(item, used));
|
Events.fire(new LaunchItemEvent(item, used));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,32 +2,17 @@ package mindustry.world.blocks.storage;
|
|||||||
|
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.type.Item;
|
import mindustry.type.*;
|
||||||
import mindustry.world.Block;
|
import mindustry.world.*;
|
||||||
import mindustry.world.Tile;
|
|
||||||
|
|
||||||
public abstract class StorageBlock extends Block{
|
public abstract class StorageBlock extends Block{
|
||||||
|
|
||||||
public StorageBlock(String name){
|
public StorageBlock(String name){
|
||||||
super(name);
|
super(name);
|
||||||
hasItems = true;
|
hasItems = true;
|
||||||
}
|
solid = true;
|
||||||
|
update = false;
|
||||||
@Override
|
destructible = true;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -35,40 +20,54 @@ public abstract class StorageBlock extends Block{
|
|||||||
return false;
|
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{
|
public class StorageBlockEntity extends TileEntity{
|
||||||
protected @Nullable
|
protected @Nullable Tilec linkedCore;
|
||||||
Tile 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ public class Unloader extends Block{
|
|||||||
health = 70;
|
health = 70;
|
||||||
hasItems = true;
|
hasItems = true;
|
||||||
configurable = true;
|
configurable = true;
|
||||||
config(Item.class, (tile, item) -> {
|
config(Item.class, (tile, item) -> {
|
||||||
tile.items.clear();
|
tile.items().clear();
|
||||||
tile.<UnloaderEntity>ent().sortItem = item;
|
((UnloaderEntity)tile).sortItem = item;
|
||||||
});
|
});
|
||||||
|
|
||||||
configClear(tile -> tile.<UnloaderEntity>ent().sortItem = null);
|
configClear(tile -> ((UnloaderEntity)tile).sortItem = null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -39,89 +39,76 @@ public class Unloader extends Block{
|
|||||||
drawRequestConfigCenter(req, (Item)req.config, "unloader-center");
|
drawRequestConfigCenter(req, (Item)req.config, "unloader-center");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canDump(Tile to, Item item){
|
|
||||||
return !(to.block() instanceof StorageBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBars(){
|
public void setBars(){
|
||||||
super.setBars();
|
super.setBars();
|
||||||
bars.remove("items");
|
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.<UnloaderEntity>ent().sortItem, item -> tile.configure(lastItem = item));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class UnloaderEntity extends TileEntity{
|
public class UnloaderEntity extends TileEntity{
|
||||||
public Item sortItem = null;
|
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.<UnloaderEntity>ent().sortItem, item -> tile.configure(lastItem = item));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canDump(Tilec to, Item item){
|
||||||
|
return !(to.block() instanceof StorageBlock);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Item config(){
|
public Item config(){
|
||||||
return sortItem;
|
return sortItem;
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -34,44 +34,22 @@ public class CommandCenter extends Block{
|
|||||||
destructible = true;
|
destructible = true;
|
||||||
solid = true;
|
solid = true;
|
||||||
configurable = true;
|
configurable = true;
|
||||||
config(Integer.class, (tile, value) -> {
|
config(Integer.class, (tile, value) -> {
|
||||||
UnitCommand command = UnitCommand.all[value];
|
UnitCommand command = UnitCommand.all[value];
|
||||||
((CommandCenter)tile.block()).effect.at(tile);
|
((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){
|
if(center.block() instanceof CommandCenter){
|
||||||
CommandCenterEntity entity = center.ent();
|
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));
|
Events.fire(new CommandIssueEvent(tile, command));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void placed(){
|
|
||||||
super.placed();
|
|
||||||
ObjectSet<Tile> 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<Tile> 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
|
@Override
|
||||||
public void load(){
|
public void load(){
|
||||||
super.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<ImageButton> 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 class CommandCenterEntity extends TileEntity{
|
||||||
public UnitCommand command = UnitCommand.attack;
|
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<ImageButton> 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<Tile> 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<Tile> 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
|
@Override
|
||||||
public Integer config(){
|
public Integer config(){
|
||||||
return command.ordinal();
|
return command.ordinal();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,16 @@
|
|||||||
package mindustry.world.blocks.units;
|
package mindustry.world.blocks.units;
|
||||||
|
|
||||||
import arc.Core;
|
import arc.*;
|
||||||
import arc.struct.EnumSet;
|
import arc.graphics.*;
|
||||||
import arc.graphics.Color;
|
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.Angles;
|
import arc.math.*;
|
||||||
import arc.math.Mathf;
|
import arc.math.geom.*;
|
||||||
import arc.math.geom.Rect;
|
import arc.struct.*;
|
||||||
import arc.util.Time;
|
import arc.util.*;
|
||||||
import mindustry.entities.Units;
|
import mindustry.entities.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.world.Block;
|
import mindustry.world.*;
|
||||||
import mindustry.world.Tile;
|
|
||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
|
|
||||||
import static mindustry.Vars.tilesize;
|
import static mindustry.Vars.tilesize;
|
||||||
@@ -60,76 +58,76 @@ public class RepairPoint extends Block{
|
|||||||
super.init();
|
super.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void drawSelect(){
|
|
||||||
Drawf.dashCircle(x, y, repairRadius, Pal.accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawPlace(int x, int y, int rotation, boolean valid){
|
public void drawPlace(int x, int y, int rotation, boolean valid){
|
||||||
Drawf.dashCircle(x * tilesize + offset(), y * tilesize + offset(), repairRadius, Pal.accent);
|
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
|
@Override
|
||||||
public TextureRegion[] generateIcons(){
|
public TextureRegion[] generateIcons(){
|
||||||
return new TextureRegion[]{Core.atlas.find(name + "-base"), Core.atlas.find(name)};
|
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 class RepairPointEntity extends TileEntity{
|
||||||
public Unitc target;
|
public Unitc target;
|
||||||
public float strength, rotation = 90;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -18,8 +18,6 @@ import mindustry.world.*;
|
|||||||
import mindustry.world.consumers.*;
|
import mindustry.world.consumers.*;
|
||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
|
|
||||||
import static mindustry.Vars.net;
|
import static mindustry.Vars.net;
|
||||||
|
|
||||||
public class UnitFactory extends Block{
|
public class UnitFactory extends Block{
|
||||||
@@ -40,20 +38,21 @@ public class UnitFactory extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Remote(called = Loc.server)
|
@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;
|
if(!(tile.entity instanceof UnitFactoryEntity) || !(tile.block() instanceof UnitFactory)) return;
|
||||||
|
|
||||||
UnitFactory factory = (UnitFactory)tile.block();
|
UnitFactory factory = (UnitFactory)tile.block();
|
||||||
|
UnitFactoryEntity entity = tile.ent();
|
||||||
|
|
||||||
buildTime = 0f;
|
entity.buildTime = 0f;
|
||||||
spawned = spawns;
|
entity.spawned = spawns;
|
||||||
|
|
||||||
Effects.shake(2f, 3f, entity);
|
Effects.shake(2f, 3f, entity);
|
||||||
Fx.producesmoke.at(x, y);
|
Fx.producesmoke.at(entity);
|
||||||
|
|
||||||
if(!net.client()){
|
if(!net.client()){
|
||||||
Unitc unit = factory.unitType.create(team);
|
Unitc unit = factory.unitType.create(entity.team());
|
||||||
unit.set(x + Mathf.range(4), y + Mathf.range(4));
|
unit.set(entity.x() + Mathf.range(4), entity.y() + Mathf.range(4));
|
||||||
unit.add();
|
unit.add();
|
||||||
unit.vel().y = factory.launchVelocity;
|
unit.vel().y = factory.launchVelocity;
|
||||||
Events.fire(new UnitCreateEvent(unit));
|
Events.fire(new UnitCreateEvent(unit));
|
||||||
@@ -101,87 +100,81 @@ public class UnitFactory extends Block{
|
|||||||
stats.add(BlockStat.maxUnits, maxSpawn, StatUnit.none);
|
stats.add(BlockStat.maxUnits, maxSpawn, StatUnit.none);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unitRemoved(Unitc unit){
|
|
||||||
spawned--;
|
|
||||||
spawned = Math.max(spawned, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TextureRegion[] generateIcons(){
|
public TextureRegion[] generateIcons(){
|
||||||
return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-top")};
|
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{
|
public class UnitFactoryEntity extends TileEntity{
|
||||||
float buildTime;
|
float buildTime;
|
||||||
float time;
|
float time;
|
||||||
float speedScl;
|
float speedScl;
|
||||||
int spawned;
|
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
|
@Override
|
||||||
public void write(Writes write){
|
public void write(Writes write){
|
||||||
super.write(write);
|
super.write(write);
|
||||||
|
|||||||
Reference in New Issue
Block a user