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