Files
Mindustry/core/src/mindustry/entities/comp/MinerComp.java
2022-05-01 23:50:49 -04:00

154 lines
5.1 KiB
Java

package mindustry.entities.comp;
import arc.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.input.*;
import mindustry.type.*;
import mindustry.world.*;
import static mindustry.Vars.*;
@Component
abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc{
@Import float x, y, rotation, hitSize;
@Import UnitType type;
transient float mineTimer;
@Nullable @SyncLocal Tile mineTile;
public boolean canMine(@Nullable Item item){
if(item == null) return false;
return type.mineTier >= item.hardness;
}
public boolean offloadImmediately(){
return this.<Unit>self().isPlayer();
}
boolean mining(){
return mineTile != null && !this.<Unit>self().activelyBuilding();
}
public @Nullable Item getMineResult(@Nullable Tile tile){
if(tile == null) return null;
Item result;
if(type.mineFloor && tile.block() == Blocks.air){
result = tile.drop();
}else if(type.mineWalls){
result = tile.wallDrop();
}else{
return null;
}
return canMine(result) ? result : null;
}
public boolean validMine(Tile tile, boolean checkDst){
if(tile == null) return false;
if(checkDst && !within(tile.worldx(), tile.worldy(), type.mineRange)){
return false;
}
return getMineResult(tile) != null;
}
public boolean validMine(Tile tile){
return validMine(tile, true);
}
public boolean canMine(){
return type.mineSpeed > 0 && type.mineTier >= 0;
}
@Override
public void update(){
if(mineTile == null) return;
Building core = closestCore();
Item item = getMineResult(mineTile);
if(core != null && item != null && !acceptsItem(item) && within(core, mineTransferRange) && !offloadImmediately()){
int accepted = core.acceptStack(item(), stack().amount, this);
if(accepted > 0){
Call.transferItemTo(self(), item(), accepted,
mineTile.worldx() + Mathf.range(tilesize / 2f),
mineTile.worldy() + Mathf.range(tilesize / 2f), core);
clearItem();
}
}
if((!net.client() || isLocal()) && !validMine(mineTile)){
mineTile = null;
mineTimer = 0f;
}else if(mining() && item != null){
mineTimer += Time.delta * type.mineSpeed;
if(Mathf.chance(0.06 * Time.delta)){
Fx.pulverizeSmall.at(mineTile.worldx() + Mathf.range(tilesize / 2f), mineTile.worldy() + Mathf.range(tilesize / 2f), 0f, item.color);
}
if(mineTimer >= 50f + (type.mineHardnessScaling ? item.hardness*15f : 15f)){
mineTimer = 0;
if(state.rules.sector != null && team() == state.rules.defaultTeam) state.rules.sector.info.handleProduction(item, 1);
if(core != null && within(core, mineTransferRange) && core.acceptStack(item, 1, this) == 1 && offloadImmediately()){
//add item to inventory before it is transferred
if(item() == item && !net.client()) addItem(item);
Call.transferItemTo(self(), item, 1,
mineTile.worldx() + Mathf.range(tilesize / 2f),
mineTile.worldy() + Mathf.range(tilesize / 2f), core);
}else if(acceptsItem(item)){
//this is clientside, since items are synced anyway
InputHandler.transferItemToUnit(item,
mineTile.worldx() + Mathf.range(tilesize / 2f),
mineTile.worldy() + Mathf.range(tilesize / 2f),
this);
}else{
mineTile = null;
mineTimer = 0f;
}
}
if(!headless){
control.sound.loop(type.mineSound, this, type.mineSoundVolume);
}
}
}
@Override
public void draw(){
if(!mining()) return;
float focusLen = hitSize / 2f + Mathf.absin(Time.time, 1.1f, 0.5f);
float swingScl = 12f, swingMag = tilesize / 8f;
float flashScl = 0.3f;
float px = x + Angles.trnsx(rotation, focusLen);
float py = y + Angles.trnsy(rotation, focusLen);
float ex = mineTile.worldx() + Mathf.sin(Time.time + 48, swingScl, swingMag);
float ey = mineTile.worldy() + Mathf.sin(Time.time + 48, swingScl + 2f, swingMag);
Draw.z(Layer.flyingUnit + 0.1f);
Draw.color(Color.lightGray, Color.white, 1f - flashScl + Mathf.absin(Time.time, 0.5f, flashScl));
Drawf.laser(Core.atlas.find("minelaser"), Core.atlas.find("minelaser-end"), px, py, ex, ey, 0.75f);
if(isLocal()){
Lines.stroke(1f, Pal.accent);
Lines.poly(mineTile.worldx(), mineTile.worldy(), 4, tilesize / 2f * Mathf.sqrt2, Time.time);
}
Draw.color();
}
}