Merging changes from private branch
This commit is contained in:
@@ -156,6 +156,8 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
public boolean updateInUnits = true;
|
||||
/** if true, this block updates in payloads in units regardless of the experimental game rule */
|
||||
public boolean alwaysUpdateInUnits = false;
|
||||
/** if true, this block can be picked up in payloads */
|
||||
public boolean canPickup = true;
|
||||
/** if false, only incinerable liquids are dropped when deconstructing; otherwise, all liquids are dropped. */
|
||||
public boolean deconstructDropAllLiquid = false;
|
||||
/** Whether to use this block's color in the minimap. Only used for overlays. */
|
||||
@@ -174,6 +176,8 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
public float armor = 0f;
|
||||
/** base block explosiveness */
|
||||
public float baseExplosiveness = 0f;
|
||||
/** base value for screen shake upon destruction */
|
||||
public float baseShake = 3f;
|
||||
/** bullet that this block spawns when destroyed */
|
||||
public @Nullable BulletType destroyBullet = null;
|
||||
/** if true, destroyBullet is spawned on the block's team instead of Derelict team */
|
||||
@@ -194,6 +198,8 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
public int sizeOffset = 0;
|
||||
/** Clipping size of this block. Should be as large as the block will draw. */
|
||||
public float clipSize = -1f;
|
||||
/** Clipping size for lights only. */
|
||||
public float lightClipSize;
|
||||
/** When placeRangeCheck is enabled, this is the range checked for enemy blocks. */
|
||||
public float placeOverlapRange = 50f;
|
||||
/** Multiplier of damage dealt to this block by tanks. Does not apply to crawlers. */
|
||||
@@ -290,13 +296,13 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
public Sound breakSound = Sounds.breaks;
|
||||
/** Sounds made when this block is destroyed.*/
|
||||
public Sound destroySound = Sounds.boom;
|
||||
/** Range of destroy sound. */
|
||||
public float destroyPitchMin = 1f, destroyPitchMax = 1f;
|
||||
/** How reflective this block is. */
|
||||
public float albedo = 0f;
|
||||
/** Environmental passive light color. */
|
||||
public Color lightColor = Color.white.cpy();
|
||||
/**
|
||||
* Whether this environmental block passively emits light.
|
||||
* Does not change behavior for non-environmental blocks, but still updates clipSize. */
|
||||
/** If true, drawLight() will be called for this block. */
|
||||
public boolean emitLight = false;
|
||||
/** Radius of the light emitted by this block. */
|
||||
public float lightRadius = 60f;
|
||||
@@ -304,11 +310,6 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
/** How much fog this block uncovers, in tiles. Cannot be dynamic. <= 0 to disable. */
|
||||
public int fogRadius = -1;
|
||||
|
||||
/** The sound that this block makes while active. One sound loop. Do not overuse. */
|
||||
public Sound loopSound = Sounds.none;
|
||||
/** Active sound base volume. */
|
||||
public float loopSoundVolume = 0.5f;
|
||||
|
||||
/** The sound that this block makes while idle. Uses one sound loop for all blocks. */
|
||||
public Sound ambientSound = Sounds.none;
|
||||
/** Idle sound base volume. */
|
||||
@@ -344,6 +345,8 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
public ObjectFloatMap<Item> researchCostMultipliers = new ObjectFloatMap<>();
|
||||
/** Override for research cost. Uses multipliers above and building requirements if not set. */
|
||||
public @Nullable ItemStack[] researchCost;
|
||||
/** If set, all blocks will be forced to be this team. */
|
||||
public @Nullable Team forceTeam;
|
||||
/** Whether this block has instant transfer.*/
|
||||
public boolean instantTransfer = false;
|
||||
/** Whether you can rotate this block after it is placed. */
|
||||
@@ -434,6 +437,18 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
drawOverlay(x * tilesize + offset, y * tilesize + offset, rotation);
|
||||
}
|
||||
|
||||
/** Draws a region to overlay a specific side of this block. This method makes sure it is placed at the edge of the side. */
|
||||
public void drawSideRegion(TextureRegion region, float x, float y, int rotation){
|
||||
var p = Geometry.d4[Mathf.mod(rotation, 4)];
|
||||
float s = size * tilesize/2f;
|
||||
|
||||
Draw.rect(region,
|
||||
x + p.x * (s - region.width/2f * region.scl()),
|
||||
y + p.y * (s - region.width/2f * region.scl()),
|
||||
rotation * 90f
|
||||
);
|
||||
}
|
||||
|
||||
public void drawPotentialLinks(int x, int y){
|
||||
if((consumesPower || outputsPower) && hasPower && connectedPower){
|
||||
Tile tile = world.tile(x, y);
|
||||
@@ -492,6 +507,10 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
public void drawOverlay(float x, float y, int rotation){
|
||||
}
|
||||
|
||||
public boolean displayShadow(Tile tile){
|
||||
return hasShadow;
|
||||
}
|
||||
|
||||
public float sumAttribute(@Nullable Attribute attr, int x, int y){
|
||||
if(attr == null) return 0;
|
||||
Tile tile = world.tile(x, y);
|
||||
@@ -887,8 +906,8 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
return buildType.get();
|
||||
}
|
||||
|
||||
public void updateClipRadius(float size){
|
||||
clipSize = Math.max(clipSize, size * tilesize + size * 2f);
|
||||
public void updateClipRadius(float radiusInWorldUnits){
|
||||
clipSize = Math.max(clipSize, this.size * tilesize + radiusInWorldUnits * 2f);
|
||||
}
|
||||
|
||||
public Rect bounds(int x, int y, Rect rect){
|
||||
@@ -1196,6 +1215,10 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
hasShadow = false;
|
||||
}
|
||||
|
||||
if(underBullets){
|
||||
priority = TargetPriority.under;
|
||||
}
|
||||
|
||||
if(fogRadius > 0){
|
||||
flags = flags.with(BlockFlag.hasFogRadius);
|
||||
}
|
||||
@@ -1222,12 +1245,15 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
|
||||
clipSize = Math.max(clipSize, size * tilesize);
|
||||
|
||||
lightClipSize = Math.max(lightClipSize, clipSize);
|
||||
|
||||
if(hasLiquids && drawLiquidLight){
|
||||
clipSize = Math.max(size * 30f * 2f, clipSize);
|
||||
emitLight = true;
|
||||
lightClipSize = Math.max(lightClipSize, size * 30f * 2f);
|
||||
}
|
||||
|
||||
if(emitLight){
|
||||
clipSize = Math.max(clipSize, lightRadius * 2f);
|
||||
lightClipSize = Math.max(lightClipSize, lightRadius * 2f);
|
||||
}
|
||||
|
||||
if(group == BlockGroup.transportation || category == Category.distribution){
|
||||
|
||||
@@ -164,7 +164,12 @@ public class Build{
|
||||
|
||||
/** @return whether a tile can be placed at this location by this team. */
|
||||
public static boolean validPlace(Block type, Team team, int x, int y, int rotation, boolean checkVisible){
|
||||
return validPlaceIgnoreUnits(type, team, x, y, rotation, checkVisible) && checkNoUnitOverlap(type, x, y);
|
||||
return validPlace(type, team, x, y, rotation, checkVisible, true);
|
||||
}
|
||||
|
||||
/** @return whether a tile can be placed at this location by this team. */
|
||||
public static boolean validPlace(Block type, Team team, int x, int y, int rotation, boolean checkVisible, boolean ignoreCoreRadius){
|
||||
return validPlaceIgnoreUnits(type, team, x, y, rotation, checkVisible, ignoreCoreRadius) && checkNoUnitOverlap(type, x, y);
|
||||
}
|
||||
|
||||
/** @return whether a tile can be placed at this location by this team. */
|
||||
@@ -172,14 +177,14 @@ public class Build{
|
||||
return (!type.solid && !type.solidifes) || !Units.anyEntities(x * tilesize + type.offset - type.size * tilesize / 2f, y * tilesize + type.offset - type.size * tilesize / 2f, type.size * tilesize, type.size * tilesize);
|
||||
}
|
||||
|
||||
/** Returns whether a tile can be placed at this location by this team. Ignores units at this location. */
|
||||
public static boolean validPlaceIgnoreUnits(Block type, Team team, int x, int y, int rotation, boolean checkVisible){
|
||||
/** @return whether a tile can be placed at this location by this team. Ignores units at this location. */
|
||||
public static boolean validPlaceIgnoreUnits(Block type, Team team, int x, int y, int rotation, boolean checkVisible, boolean checkCoreRadius){
|
||||
//the wave team can build whatever they want as long as it's visible - banned blocks are not applicable
|
||||
if(type == null || (!state.rules.editor && (checkVisible && (!type.environmentBuildable() || (!type.isPlaceable() && !(state.rules.waves && team == state.rules.waveTeam && type.isVisible())))))){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!state.rules.editor){
|
||||
if(!state.rules.editor && checkCoreRadius){
|
||||
//find closest core, if it doesn't match the team, placing is not legal
|
||||
if(state.rules.polygonCoreProtection){
|
||||
float mindst = Float.MAX_VALUE;
|
||||
@@ -240,8 +245,9 @@ public class Build{
|
||||
(type == check.block() && check.build != null && rotation == check.build.rotation && type.rotate && !((type == check.block && team != Team.derelict && check.team() == Team.derelict))) || //same block, same rotation
|
||||
!check.interactable(team) || //cannot interact
|
||||
!check.floor().placeableOn && !type.ignoreBuildDarkness || //solid floor
|
||||
(!checkVisible && !check.block().alwaysReplace) || //replacing a block that should be replaced (e.g. payload placement)
|
||||
!(((type.canReplace(check.block()) || (type == check.block && team != Team.derelict && state.rules.derelictRepair && check.team() == Team.derelict)) || //can replace type OR can replace derelict block of same type
|
||||
//when you have a payload, you cannot place blocks on things, even if normal placement rules allow it. this is a hack that assumes checkVisible = true means it's coming from a payload
|
||||
(!checkVisible && checkCoreRadius && !check.block().alwaysReplace) || //replacing a block that should be replaced (e.g. payload placement)
|
||||
!(((type.canReplace(check.block()) || (check.build != null && check.build.canBeReplaced(type)) || (type == check.block && team != Team.derelict && state.rules.derelictRepair && check.team() == Team.derelict)) || //can replace type OR can replace derelict block of same type
|
||||
(check.build instanceof ConstructBuild build && build.current == type && check.centerX() == tile.x && check.centerY() == tile.y)) && //same type in construction
|
||||
type.bounds(tile.x, tile.y, Tmp.r1).grow(0.01f).contains(check.block.bounds(check.centerX(), check.centerY(), Tmp.r2))) || //no replacement
|
||||
(type.requiresWater && check.floor().liquidDrop != Liquids.water) //requires water but none found
|
||||
@@ -249,7 +255,7 @@ public class Build{
|
||||
}
|
||||
}
|
||||
|
||||
if(state.rules.placeRangeCheck && !state.isEditor() && getEnemyOverlap(type, team, x, y) != null){
|
||||
if(state.rules.placeRangeCheck && checkCoreRadius && !state.isEditor() && getEnemyOverlap(type, team, x, y) != null){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,11 +28,11 @@ public class CachedTile extends Tile{
|
||||
|
||||
if(block.hasBuilding()){
|
||||
Building n = entityprov.get();
|
||||
n.tile(this);
|
||||
n.tile = this;
|
||||
n.block = block;
|
||||
if(block.hasItems) n.items = new ItemModule();
|
||||
if(block.hasLiquids) n.liquids(new LiquidModule());
|
||||
if(block.hasPower) n.power(new PowerModule());
|
||||
if(block.hasLiquids) n.liquids = new LiquidModule();
|
||||
if(block.hasPower) n.power = new PowerModule();
|
||||
build = n;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public class Edges{
|
||||
}
|
||||
|
||||
public static Tile getFacingEdge(Building tile, Building other){
|
||||
Tile res = getFacingEdge(tile.block, tile.tileX(), tile.tileY(), other.tile());
|
||||
Tile res = getFacingEdge(tile.block, tile.tileX(), tile.tileY(), other.tile);
|
||||
return res == null ? tile.tile : res;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import static mindustry.Vars.*;
|
||||
public class Tile implements Position, QuadTreeObject, Displayable{
|
||||
private static final TileChangeEvent tileChange = new TileChangeEvent();
|
||||
private static final TilePreChangeEvent preChange = new TilePreChangeEvent();
|
||||
private static final TileFloorChangeEvent floorChange = new TileFloorChangeEvent();
|
||||
private static final ObjectSet<Building> tileSet = new ObjectSet<>();
|
||||
|
||||
/** Extra data for very specific blocks. */
|
||||
@@ -223,6 +224,8 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
||||
recacheWall();
|
||||
}
|
||||
|
||||
if(type.forceTeam != null) team = type.forceTeam;
|
||||
|
||||
preChanged();
|
||||
|
||||
this.block = type;
|
||||
@@ -282,6 +285,7 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
||||
|
||||
/** This resets the overlay! */
|
||||
public void setFloor(Floor type){
|
||||
var prev = this.floor;
|
||||
this.floor = type;
|
||||
this.overlay = (Floor)Blocks.air;
|
||||
|
||||
@@ -293,9 +297,13 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
||||
if(build != null){
|
||||
build.onProximityUpdate();
|
||||
}
|
||||
if(!world.isGenerating() && pathfinder != null){
|
||||
if(!world.isGenerating() && pathfinder != null && !state.isEditor()){
|
||||
pathfinder.updateTile(this);
|
||||
}
|
||||
|
||||
if(!world.isGenerating() && prev != type){
|
||||
Events.fire(floorChange.set(this, prev, type));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEditorTile(){
|
||||
|
||||
@@ -40,7 +40,6 @@ public class Tiles implements Iterable<Tile>{
|
||||
fires[pos] = f;
|
||||
}
|
||||
|
||||
|
||||
public void each(Intc2 cons){
|
||||
for(int x = 0; x < width; x++){
|
||||
for(int y = 0; y < height; y++){
|
||||
|
||||
@@ -342,7 +342,6 @@ public class LandingPad extends Block{
|
||||
@Override
|
||||
public void drawSelect(){
|
||||
if(config != null){
|
||||
drawItemSelection(config);
|
||||
|
||||
float dx = x - size * tilesize/2f, dy = y + size * tilesize/2f, s = iconSmall / 4f;
|
||||
Draw.mixcol(Color.darkGray, 1f);
|
||||
|
||||
@@ -52,7 +52,7 @@ public class Door extends Wall{
|
||||
|
||||
if(chainEffect) entity.effect();
|
||||
entity.open = open;
|
||||
if(!world.isGenerating()) pathfinder.updateTile(entity.tile());
|
||||
if(!world.isGenerating()) pathfinder.updateTile(entity.tile);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package mindustry.world.blocks.defense;
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.io.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
@@ -39,6 +40,7 @@ public class MendProjector extends Block{
|
||||
lightRadius = 50f;
|
||||
suppressable = true;
|
||||
envEnabled |= Env.space;
|
||||
flags = EnumSet.of(BlockFlag.blockRepair);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,9 +19,6 @@ import mindustry.world.meta.*;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class OverdriveProjector extends Block{
|
||||
@Deprecated
|
||||
public final int timerUse = timers++;
|
||||
|
||||
public @Load("@-top") TextureRegion topRegion;
|
||||
public float reload = 60f;
|
||||
public float range = 80f;
|
||||
|
||||
@@ -46,6 +46,7 @@ public class RegenProjector extends Block{
|
||||
suppressable = true;
|
||||
envEnabled |= Env.space;
|
||||
rotateDraw = false;
|
||||
flags = EnumSet.of(BlockFlag.blockRepair);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,8 +134,6 @@ public class RegenProjector extends Block{
|
||||
return;
|
||||
}
|
||||
|
||||
anyTargets = targets.contains(b -> b.damaged());
|
||||
|
||||
if(efficiency > 0){
|
||||
if((optionalTimer += Time.delta * optionalEfficiency) >= optionalUseTime){
|
||||
consume();
|
||||
@@ -148,6 +147,7 @@ public class RegenProjector extends Block{
|
||||
if(!build.damaged() || build.isHealSuppressed()) continue;
|
||||
|
||||
didRegen = true;
|
||||
anyTargets = true;
|
||||
|
||||
int pos = build.pos();
|
||||
//TODO periodic effect
|
||||
|
||||
@@ -10,6 +10,7 @@ import arc.math.geom.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.io.*;
|
||||
import mindustry.audio.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.core.*;
|
||||
import mindustry.entities.*;
|
||||
@@ -118,6 +119,10 @@ public class Turret extends ReloadTurret{
|
||||
public Sound shootSound = Sounds.shoot;
|
||||
/** Sound emitted when shoot.firstShotDelay is >0 and shooting begins. */
|
||||
public Sound chargeSound = Sounds.none;
|
||||
/** The sound that this block makes while active. One sound loop. Do not overuse. */
|
||||
public Sound loopSound = Sounds.none;
|
||||
/** Active sound base volume. */
|
||||
public float loopSoundVolume = 0.5f;
|
||||
/** Range for pitch of shoot sound. */
|
||||
public float soundPitchMin = 0.9f, soundPitchMax = 1.1f;
|
||||
/** Backwards Y offset of ammo eject effect. */
|
||||
@@ -254,8 +259,26 @@ public class Turret extends ReloadTurret{
|
||||
public float heatReq;
|
||||
public float[] sideHeat = new float[4];
|
||||
|
||||
public @Nullable SoundLoop soundLoop = (loopSound == Sounds.none ? null : new SoundLoop(loopSound, loopSoundVolume));
|
||||
|
||||
float lastRangeChange;
|
||||
|
||||
@Override
|
||||
public void remove(){
|
||||
super.remove();
|
||||
if(soundLoop != null){
|
||||
soundLoop.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyed(){
|
||||
super.onDestroyed();
|
||||
if(soundLoop != null){
|
||||
soundLoop.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float estimateDps(){
|
||||
if(!hasAmmo()) return 0f;
|
||||
@@ -410,6 +433,10 @@ public class Turret extends ReloadTurret{
|
||||
public void updateTile(){
|
||||
if(!validateTarget()) target = null;
|
||||
|
||||
if(soundLoop != null){
|
||||
soundLoop.update(x, y, shouldActiveSound(), activeSoundVolume());
|
||||
}
|
||||
|
||||
float warmupTarget = (isShooting() && canConsume()) || charging() ? 1f : 0f;
|
||||
if(warmupTarget > 0 && !isControlled()){
|
||||
warmupHold = 1f;
|
||||
@@ -705,12 +732,10 @@ public class Turret extends ReloadTurret{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public float activeSoundVolume(){
|
||||
return shootWarmup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldActiveSound(){
|
||||
return shootWarmup > 0.01f && loopSound != Sounds.none;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public class ArmoredConveyor extends Conveyor{
|
||||
public class ArmoredConveyorBuild extends ConveyorBuild{
|
||||
@Override
|
||||
public boolean acceptItem(Building source, Item item){
|
||||
return super.acceptItem(source, item) && (source.block instanceof Conveyor || Edges.getFacingEdge(source.tile(), tile).relativeTo(tile) == rotation);
|
||||
return super.acceptItem(source, item) && (source.block instanceof Conveyor || Edges.getFacingEdge(source.tile, tile).relativeTo(tile) == rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package mindustry.world.blocks.distribution;
|
||||
|
||||
import arc.*;
|
||||
import arc.func.*;
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
@@ -30,7 +31,7 @@ public class Duct extends Block implements Autotiler{
|
||||
public @Load(value = "@-top-#", length = 5) TextureRegion[] topRegions;
|
||||
public @Load(value = "@-bottom-#", length = 5, fallback = "duct-bottom-#") TextureRegion[] botRegions;
|
||||
|
||||
public @Nullable Block bridgeReplacement;
|
||||
public @Nullable Block bridgeReplacement, junctionReplacement;
|
||||
|
||||
public Duct(String name){
|
||||
super(name);
|
||||
@@ -63,6 +64,7 @@ public class Duct extends Block implements Autotiler{
|
||||
super.init();
|
||||
|
||||
if(bridgeReplacement == null || !(bridgeReplacement instanceof DuctBridge || bridgeReplacement instanceof ItemBridge)) bridgeReplacement = Blocks.ductBridge;
|
||||
//if(junctionReplacement == null) junctionReplacement = Blocks.ductJunction;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -103,11 +105,24 @@ public class Duct extends Block implements Autotiler{
|
||||
return new TextureRegion[]{Core.atlas.find("duct-bottom"), topRegions[0]};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getReplacement(BuildPlan req, Seq<BuildPlan> plans){
|
||||
if(junctionReplacement == null || !junctionReplacement.unlockedNow() || junctionReplacement.isHidden()) return this;
|
||||
|
||||
Boolf<Point2> cont = p -> plans.contains(o -> o.x == req.x + p.x && o.y == req.y + p.y && (req.block instanceof Duct || req.block instanceof DuctJunction));
|
||||
return cont.get(Geometry.d4(req.rotation)) &&
|
||||
cont.get(Geometry.d4(req.rotation - 2)) &&
|
||||
req.tile() != null &&
|
||||
req.tile().block() instanceof Duct &&
|
||||
Mathf.mod(req.tile().build.rotation - req.rotation, 2) == 1 ? junctionReplacement : this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePlacementLine(Seq<BuildPlan> plans){
|
||||
if(bridgeReplacement == null) return;
|
||||
if(bridgeReplacement instanceof ItemBridge bridge) Placement.calculateBridges(plans, bridge, false, b -> b instanceof Duct || b instanceof StackConveyor || b instanceof Conveyor);
|
||||
if(bridgeReplacement instanceof DuctBridge bridge) Placement.calculateBridges(plans, bridge, false, b -> b instanceof Duct || b instanceof StackConveyor || b instanceof Conveyor);
|
||||
boolean hasJunction = junctionReplacement != null && junctionReplacement.unlockedNow() && !junctionReplacement.isHidden();
|
||||
if(bridgeReplacement instanceof ItemBridge bridge) Placement.calculateBridges(plans, bridge, hasJunction, b -> b instanceof Duct || b instanceof StackConveyor || b instanceof Conveyor);
|
||||
if(bridgeReplacement instanceof DuctBridge bridge) Placement.calculateBridges(plans, bridge, hasJunction, b -> b instanceof Duct || b instanceof StackConveyor || b instanceof Conveyor);
|
||||
}
|
||||
|
||||
public class DuctBuild extends Building{
|
||||
@@ -137,7 +152,7 @@ public class Duct extends Block implements Autotiler{
|
||||
Draw.z(Layer.blockUnder + 0.1f);
|
||||
Tmp.v1.set(Geometry.d4x(recDir) * tilesize / 2f, Geometry.d4y(recDir) * tilesize / 2f)
|
||||
.lerp(Geometry.d4x(r) * tilesize / 2f, Geometry.d4y(r) * tilesize / 2f,
|
||||
Mathf.clamp((progress + 1f) / 2f));
|
||||
Mathf.clamp((progress + 1f) / (2f - 1f/speed)));
|
||||
|
||||
Draw.rect(current.fullIcon, x + Tmp.v1.x, y + Tmp.v1.y, itemSize, itemSize);
|
||||
}
|
||||
@@ -188,7 +203,7 @@ public class Duct extends Block implements Autotiler{
|
||||
(armored ?
|
||||
//armored acceptance
|
||||
((source.block.rotate && source.front() == this && source.block.hasItems && source.block.isDuct) ||
|
||||
Edges.getFacingEdge(source.tile(), tile).relativeTo(tile) == rotation) :
|
||||
Edges.getFacingEdge(source.tile, tile).relativeTo(tile) == rotation) :
|
||||
//standard acceptance - do not accept from front
|
||||
!(source.block.rotate && next == source) && Edges.getFacingEdge(source.tile, tile) != null && Math.abs(Edges.getFacingEdge(source.tile, tile).relativeTo(tile.x, tile.y) - rotation) != 2
|
||||
);
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
package mindustry.world.blocks.distribution;
|
||||
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.util.io.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.io.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.meta.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class DuctJunction extends Block{
|
||||
public Color transparentColor = new Color(0.4f, 0.4f, 0.4f, 0.1f);
|
||||
public @Load("@-bottom") TextureRegion bottomRegion;
|
||||
public @Load("@-top") TextureRegion topRegion;
|
||||
public float speed = 5f;
|
||||
|
||||
public DuctJunction(String name){
|
||||
super(name);
|
||||
update = true;
|
||||
solid = false;
|
||||
underBullets = true;
|
||||
group = BlockGroup.transportation;
|
||||
unloadable = false;
|
||||
floating = true;
|
||||
noUpdateDisabled = true;
|
||||
hasItems = true;
|
||||
|
||||
priority = TargetPriority.transport;
|
||||
envEnabled = Env.space | Env.terrestrial | Env.underwater;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStats(){
|
||||
super.setStats();
|
||||
//4 tems is misleading
|
||||
stats.remove(Stat.itemCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(){
|
||||
super.load();
|
||||
squareSprite = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean outputsItems(){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
itemCapacity = 4;
|
||||
super.init();
|
||||
}
|
||||
|
||||
public class DuctJunctionBuild extends Building{
|
||||
Item[] itemdata = new Item[4];
|
||||
float[] times = new float[4];
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
Draw.z(Layer.blockUnder);
|
||||
Draw.rect(bottomRegion, x, y);
|
||||
|
||||
Draw.z(Layer.blockUnder + 0.1f);
|
||||
|
||||
for(int i = 0; i < 4; i++){
|
||||
Item current = itemdata[i];
|
||||
|
||||
if(current != null){
|
||||
float progress = (Mathf.clamp((times[i] + 1f) / (2f - 1f/speed)) - 0.5f) * 2f;
|
||||
|
||||
Draw.rect(current.fullIcon,
|
||||
x + Geometry.d4x(i) * tilesize / 2f * progress,
|
||||
y + Geometry.d4y(i) * tilesize / 2f * progress,
|
||||
itemSize, itemSize
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Draw.color(transparentColor);
|
||||
Draw.rect(bottomRegion, x, y);
|
||||
Draw.color();
|
||||
|
||||
Draw.z(Layer.blockUnder + 0.2f);
|
||||
|
||||
Draw.rect(topRegion, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTile(){
|
||||
float inc = edelta() / speed * 2f;
|
||||
|
||||
for(int i = 0; i < 4; i++){
|
||||
Item item = itemdata[i];
|
||||
if(item != null){
|
||||
|
||||
times[i] += inc;
|
||||
if(times[i] >= (1f - 1f/speed)){
|
||||
Building next = nearby(i);
|
||||
|
||||
if(next != null && next.team == team && next.acceptItem(this, item)){
|
||||
next.handleItem(this, item);
|
||||
itemdata[i] = null;
|
||||
items.remove(item, 1);
|
||||
times[i] %= (1f - 1f/speed);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
//TODO: reset progress or not?
|
||||
times[i] = 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleItem(Building source, Item item){
|
||||
int relative = source.relativeTo(tile);
|
||||
if(relative == -1) return;
|
||||
itemdata[relative] = item;
|
||||
times[relative] = -1f;
|
||||
items.add(item, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptItem(Building source, Item item){
|
||||
int relative = source.relativeTo(tile);
|
||||
|
||||
if(relative == -1 || itemdata[relative] != null) return false;
|
||||
Building to = nearby(relative);
|
||||
return to != null && to.team == team;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int acceptStack(Item item, int amount, Teamc source){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int removeStack(Item item, int amount){
|
||||
int removed = 0;
|
||||
for(int i = 0; i < 4 && amount > 0; i++){
|
||||
if(itemdata[i] == item){
|
||||
amount --;
|
||||
removed ++;
|
||||
itemdata[i] = null;
|
||||
items.remove(item, 1);
|
||||
}
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(Writes write){
|
||||
super.write(write);
|
||||
for(int i = 0; i < 4; i++){
|
||||
write.f(times[i]);
|
||||
TypeIO.writeItem(write, itemdata[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(Reads read, byte revision){
|
||||
super.read(read, revision);
|
||||
for(int i = 0; i < 4; i++){
|
||||
times[i] = read.f();
|
||||
itemdata[i] = TypeIO.readItem(read);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,7 +147,7 @@ public class DuctRouter extends Block{
|
||||
@Override
|
||||
public boolean acceptItem(Building source, Item item){
|
||||
return current == null && items.total() == 0 &&
|
||||
(Edges.getFacingEdge(source.tile(), tile).relativeTo(tile) == rotation);
|
||||
(Edges.getFacingEdge(source.tile, tile).relativeTo(tile) == rotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -248,7 +248,7 @@ public class MassDriver extends Block{
|
||||
|
||||
if(linkValid()){
|
||||
Building target = world.build(link);
|
||||
Drawf.circles(target.x, target.y, (target.block().size / 2f + 1) * tilesize + sin - 2f, Pal.place);
|
||||
Drawf.circles(target.x, target.y, (target.block.size / 2f + 1) * tilesize + sin - 2f, Pal.place);
|
||||
Drawf.arrow(x, y, target.x, target.y, size * tilesize + sin, 4f + sin);
|
||||
}
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ public class OverflowDuct extends Block{
|
||||
@Override
|
||||
public boolean acceptItem(Building source, Item item){
|
||||
return current == null && items.total() == 0 &&
|
||||
(Edges.getFacingEdge(source.tile(), tile).relativeTo(tile) == rotation);
|
||||
(Edges.getFacingEdge(source.tile, tile).relativeTo(tile) == rotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -83,7 +83,7 @@ public class Router extends Block{
|
||||
items.add(item, 1);
|
||||
lastItem = item;
|
||||
time = 0f;
|
||||
lastInput = source.tile();
|
||||
lastInput = source.tile;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -85,7 +85,7 @@ public class StackRouter extends DuctRouter{
|
||||
@Override
|
||||
public boolean acceptItem(Building source, Item item){
|
||||
return !unloading && (current == null || item == current) && items.total() < itemCapacity &&
|
||||
(Edges.getFacingEdge(source.tile(), tile).relativeTo(tile) == rotation);
|
||||
(Edges.getFacingEdge(source.tile, tile).relativeTo(tile) == rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,6 +213,11 @@ public class Floor extends Block{
|
||||
return new TextureRegion[]{Core.atlas.find(Core.atlas.has(name) ? name : name + "1")};
|
||||
}
|
||||
|
||||
/** @return whether to index this floor by flag */
|
||||
public boolean shouldIndex(Tile tile){
|
||||
return true;
|
||||
}
|
||||
|
||||
//TODO currently broken for dynamically edited floor tiles
|
||||
/** @return true if this floor should be updated in the render loop, e.g. for effects. Do NOT overuse this! */
|
||||
public boolean updateRender(Tile tile){
|
||||
@@ -319,11 +324,6 @@ public class Floor extends Block{
|
||||
return edges(x, y)[rx][2 - ry];
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
protected TextureRegion[][] edges(){
|
||||
return edges(0, 0);
|
||||
}
|
||||
|
||||
/** @return whether the edges from {@param other} should be drawn onto this tile **/
|
||||
protected boolean doEdge(Tile tile, Tile otherTile, Floor other){
|
||||
return (other.realBlendId(otherTile) > realBlendId(tile) || edges(tile.x, tile.y) == null);
|
||||
|
||||
@@ -4,12 +4,14 @@ import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.meta.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
@@ -41,6 +43,7 @@ public class SteamVent extends Floor{
|
||||
public SteamVent(String name){
|
||||
super(name);
|
||||
variants = 2;
|
||||
flags = EnumSet.of(BlockFlag.steamVent);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,6 +61,16 @@ public class SteamVent extends Floor{
|
||||
return checkAdjacent(tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldIndex(Tile tile){
|
||||
return isCenterVent(tile);
|
||||
}
|
||||
|
||||
public boolean isCenterVent(Tile tile){
|
||||
Tile topRight = tile.nearby(1, 1);
|
||||
return topRight != null && topRight.floor() == tile.floor() && checkAdjacent(topRight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderUpdate(UpdateRenderState state){
|
||||
if(state.tile.nearby(-1, -1) != null && state.tile.nearby(-1, -1).block() == Blocks.air && (state.data += Time.delta) >= effectSpacing){
|
||||
@@ -66,6 +79,7 @@ public class SteamVent extends Floor{
|
||||
}
|
||||
}
|
||||
|
||||
//note that only the top right tile works for this; render order reasons.
|
||||
public boolean checkAdjacent(Tile tile){
|
||||
for(var point : offsets){
|
||||
Tile other = Vars.world.tile(tile.x + point.x, tile.y + point.y);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package mindustry.world.blocks.heat;
|
||||
|
||||
import arc.math.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.io.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.ui.*;
|
||||
@@ -20,6 +21,8 @@ public class HeatProducer extends GenericCrafter{
|
||||
rotate = true;
|
||||
canOverdrive = false;
|
||||
drawArrow = true;
|
||||
//it doesn't count as a standard crafter
|
||||
flags = EnumSet.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -88,7 +88,7 @@ public class MessageBlock extends Block{
|
||||
Draw.color(0f, 0f, 0f, 0.2f);
|
||||
Fill.rect(x, y - tilesize/2f - l.height/2f - offset, l.width + offset*2f, l.height + offset*2f);
|
||||
Draw.color();
|
||||
font.setColor(Color.white);
|
||||
font.setColor(message.length() == 0 ? Color.lightGray : Color.white);
|
||||
font.draw(text, x - l.width/2f, y - tilesize/2f - offset, 90f, Align.left, true);
|
||||
font.setUseIntegerPositions(ints);
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ public class BuildPayload implements Payload{
|
||||
|
||||
@Override
|
||||
public void remove(){
|
||||
build.stopSound();
|
||||
build.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -207,7 +207,7 @@ public class PayloadBlock extends Block{
|
||||
payVector.approach(dest, payloadSpeed * delta());
|
||||
|
||||
Building front = front();
|
||||
boolean canDump = front == null || !front.tile().solid();
|
||||
boolean canDump = front == null || !front.tile.solid();
|
||||
boolean canMove = front != null && (front.block.outputsPayload || front.block.acceptsPayload);
|
||||
|
||||
if(canDump && !canMove){
|
||||
|
||||
@@ -94,7 +94,7 @@ public class PayloadLoader extends PayloadBlock{
|
||||
//item container
|
||||
(build.build.block.hasItems && build.block().unloadable && build.block().itemCapacity >= 10 && build.block().size <= maxBlockSize) ||
|
||||
//liquid container
|
||||
(build.build.block().hasLiquids && build.block().liquidCapacity >= 10f) ||
|
||||
(build.build.block.hasLiquids && build.block().liquidCapacity >= 10f) ||
|
||||
//battery
|
||||
(build.build.block.consPower != null && build.build.block.consPower.buffered)
|
||||
);
|
||||
|
||||
@@ -22,7 +22,7 @@ import static mindustry.world.blocks.payloads.PayloadMassDriver.PayloadDriverSta
|
||||
|
||||
public class PayloadMassDriver extends PayloadBlock{
|
||||
public float range = 100f;
|
||||
public float rotateSpeed = 2f;
|
||||
public float rotateSpeed = 5f;
|
||||
public float length = 89 / 8f;
|
||||
public float knockback = 5f;
|
||||
public float reload = 30f;
|
||||
@@ -72,7 +72,7 @@ public class PayloadMassDriver extends PayloadBlock{
|
||||
@Override
|
||||
public void init(){
|
||||
super.init();
|
||||
updateClipRadius(range);
|
||||
updateClipRadius(range + 4f);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -430,7 +430,7 @@ public class PayloadMassDriver extends PayloadBlock{
|
||||
|
||||
if(linkValid()){
|
||||
Building target = world.build(link);
|
||||
Drawf.circles(target.x, target.y, (target.block().size / 2f + 1) * tilesize + sin - 2f, Pal.place);
|
||||
Drawf.circles(target.x, target.y, (target.block.size / 2f + 1) * tilesize + sin - 2f, Pal.place);
|
||||
Drawf.arrow(x, y, target.x, target.y, size * tilesize + sin, 4f + sin);
|
||||
}
|
||||
|
||||
|
||||
@@ -149,6 +149,7 @@ public class UnitPayload implements Payload{
|
||||
|
||||
float e = unit.elevation;
|
||||
unit.elevation = 0f;
|
||||
Draw.scl(1f, 1f);
|
||||
unit.type.draw(unit);
|
||||
unit.elevation = e;
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.entities.units.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.world.draw.*;
|
||||
@@ -17,9 +16,6 @@ public class Battery extends PowerDistributor{
|
||||
public Color emptyLightColor = Color.valueOf("f8c266");
|
||||
public Color fullLightColor = Color.valueOf("fb9567");
|
||||
|
||||
@Deprecated
|
||||
public @Load("@-top") TextureRegion topRegion;
|
||||
|
||||
public Battery(String name){
|
||||
super(name);
|
||||
outputsPower = true;
|
||||
|
||||
@@ -39,7 +39,7 @@ public class LightBlock extends Block{
|
||||
@Override
|
||||
public void init(){
|
||||
lightRadius = radius*2.5f;
|
||||
clipSize = Math.max(clipSize, lightRadius * 3f);
|
||||
lightClipSize = Math.max(lightClipSize, lightRadius * 3f);
|
||||
emitLight = true;
|
||||
|
||||
super.init();
|
||||
|
||||
@@ -49,6 +49,7 @@ public class NuclearReactor extends PowerGenerator{
|
||||
hasItems = true;
|
||||
hasLiquids = true;
|
||||
rebuildable = false;
|
||||
emitLight = true;
|
||||
flags = EnumSet.of(BlockFlag.reactor, BlockFlag.generator);
|
||||
schematicPriority = -5;
|
||||
envEnabled = Env.any;
|
||||
|
||||
@@ -194,7 +194,7 @@ public class PowerNode extends PowerBlock{
|
||||
}
|
||||
|
||||
protected boolean overlaps(Building src, Building other, float range){
|
||||
return overlaps(src.x, src.y, other.tile(), range);
|
||||
return overlaps(src.x, src.y, other.tile, range);
|
||||
}
|
||||
|
||||
protected boolean overlaps(Tile src, Tile other, float range){
|
||||
@@ -209,9 +209,9 @@ public class PowerNode extends PowerBlock{
|
||||
protected void getPotentialLinks(Tile tile, Team team, Cons<Building> others){
|
||||
if(!autolink) return;
|
||||
|
||||
Boolf<Building> valid = other -> other != null && other.tile() != tile && other.block.connectedPower && other.power != null &&
|
||||
Boolf<Building> valid = other -> other != null && other.tile != tile && other.block.connectedPower && other.power != null &&
|
||||
(other.block.outputsPower || other.block.consumesPower || other.block instanceof PowerNode) &&
|
||||
overlaps(tile.x * tilesize + offset, tile.y * tilesize + offset, other.tile(), laserRange * tilesize) && other.team == team &&
|
||||
overlaps(tile.x * tilesize + offset, tile.y * tilesize + offset, other.tile, laserRange * tilesize) && other.team == team &&
|
||||
!graphs.contains(other.power.graph) &&
|
||||
!PowerNode.insulated(tile, other.tile) &&
|
||||
!(other instanceof PowerNodeBuild obuild && obuild.power.links.size >= ((PowerNode)obuild.block).maxNodes) &&
|
||||
@@ -264,7 +264,7 @@ public class PowerNode extends PowerBlock{
|
||||
//TODO code duplication w/ method above?
|
||||
/** Iterates through linked nodes of a block at a tile. All returned buildings are power nodes. */
|
||||
public static void getNodeLinks(Tile tile, Block block, Team team, Cons<Building> others){
|
||||
Boolf<Building> valid = other -> other != null && other.tile() != tile && other.block instanceof PowerNode node &&
|
||||
Boolf<Building> valid = other -> other != null && other.tile != tile && other.block instanceof PowerNode node &&
|
||||
node.autolink &&
|
||||
other.power.links.size < node.maxNodes &&
|
||||
node.overlaps(other.x, other.y, tile, block, node.laserRange * tilesize) && other.team == team
|
||||
|
||||
@@ -37,9 +37,10 @@ public class ThermalGenerator extends PowerGenerator{
|
||||
outputsLiquid = true;
|
||||
hasLiquids = true;
|
||||
}
|
||||
emitLight = true;
|
||||
super.init();
|
||||
//proper light clipping
|
||||
clipSize = Math.max(clipSize, 45f * size * 2f * 2f);
|
||||
lightClipSize = Math.max(lightClipSize, 45f * size * 2f * 2f);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -43,7 +43,7 @@ public class CoreBlock extends StorageBlock{
|
||||
|
||||
public @Load(value = "@-thruster1", fallback = "clear-effect") TextureRegion thruster1; //top right
|
||||
public @Load(value = "@-thruster2", fallback = "clear-effect") TextureRegion thruster2; //bot left
|
||||
public float thrusterLength = 14f/4f;
|
||||
public float thrusterLength = 14f/4f, thrusterOffset = 0f;
|
||||
public boolean isFirstTier;
|
||||
/** If true, this core type requires a core zone to upgrade. */
|
||||
public boolean requiresCoreZone;
|
||||
@@ -69,8 +69,6 @@ public class CoreBlock extends StorageBlock{
|
||||
priority = TargetPriority.core;
|
||||
flags = EnumSet.of(BlockFlag.core);
|
||||
unitCapModifier = 10;
|
||||
loopSound = Sounds.respawning;
|
||||
loopSoundVolume = 1f;
|
||||
drawDisabled = false;
|
||||
canOverdrive = false;
|
||||
envEnabled |= Env.space;
|
||||
@@ -92,6 +90,10 @@ public class CoreBlock extends StorageBlock{
|
||||
|
||||
if(!net.client()){
|
||||
Unit unit = spawnType.create(tile.team());
|
||||
//reset reload so that the player can't shoot immediately
|
||||
for(var mount : unit.mounts){
|
||||
mount.reload = mount.weapon.reload;
|
||||
}
|
||||
unit.set(core);
|
||||
unit.rotation(90f);
|
||||
unit.impulse(0f, 3f);
|
||||
@@ -649,24 +651,23 @@ public class CoreBlock extends StorageBlock{
|
||||
super.onProximityUpdate();
|
||||
|
||||
for(Building other : state.teams.cores(team)){
|
||||
if(other.tile() != tile){
|
||||
if(other.tile != tile){
|
||||
this.items = other.items;
|
||||
}
|
||||
}
|
||||
state.teams.registerCore(this);
|
||||
|
||||
storageCapacity = itemCapacity + proximity().sum(e -> owns(e) ? e.block.itemCapacity : 0);
|
||||
storageCapacity = itemCapacity + proximity.sum(e -> owns(e) ? e.block.itemCapacity : 0);
|
||||
proximity.each(this::owns, t -> {
|
||||
t.items = items;
|
||||
((StorageBuild)t).linkedCore = this;
|
||||
});
|
||||
|
||||
for(Building other : state.teams.cores(team)){
|
||||
if(other.tile() == tile) continue;
|
||||
storageCapacity += other.block.itemCapacity + other.proximity().sum(e -> owns(other, e) ? e.block.itemCapacity : 0);
|
||||
if(other.tile == tile) continue;
|
||||
storageCapacity += other.block.itemCapacity + other.proximity.sum(e -> owns(other, e) ? e.block.itemCapacity : 0);
|
||||
}
|
||||
|
||||
//Team.sharded.core().items.set(Items.surgeAlloy, 12000)
|
||||
if(!world.isGenerating()){
|
||||
for(Item item : content.items()){
|
||||
items.set(item, Math.min(items.get(item), storageCapacity));
|
||||
|
||||
@@ -142,15 +142,12 @@ public class Reconstructor extends UnitBlock{
|
||||
public @Nullable Vec2 commandPos;
|
||||
public @Nullable UnitCommand command;
|
||||
|
||||
boolean constructing;
|
||||
|
||||
public float fraction(){
|
||||
return progress / constructTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldActiveSound(){
|
||||
return shouldConsume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec2 getCommandPosition(){
|
||||
return commandPos;
|
||||
@@ -290,6 +287,8 @@ public class Reconstructor extends UnitBlock{
|
||||
|
||||
@Override
|
||||
public void updateTile(){
|
||||
//cache value to prevent repeated calls and multithreading issues
|
||||
constructing = constructing();
|
||||
boolean valid = false;
|
||||
|
||||
if(payload != null){
|
||||
@@ -338,7 +337,7 @@ public class Reconstructor extends UnitBlock{
|
||||
|
||||
@Override
|
||||
public boolean shouldConsume(){
|
||||
return constructing() && enabled;
|
||||
return constructing && enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -85,7 +85,7 @@ public class RepairTurret extends Block{
|
||||
}
|
||||
|
||||
consumePowerCond(powerUse, (RepairPointBuild entity) -> entity.target != null);
|
||||
updateClipRadius(repairRadius);
|
||||
updateClipRadius(repairRadius + tilesize);
|
||||
super.init();
|
||||
}
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ public class UnitAssembler extends PayloadBlock{
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
updateClipRadius(areaSize * tilesize);
|
||||
updateClipRadius((areaSize + 1) * tilesize);
|
||||
|
||||
consume(consPayload = new ConsumePayloadDynamic((UnitAssemblerBuild build) -> build.plan().requirements));
|
||||
consume(consItem = new ConsumeItemDynamic((UnitAssemblerBuild build) -> build.plan().itemReq != null ? build.plan().itemReq : ItemStack.empty));
|
||||
|
||||
@@ -53,13 +53,13 @@ public class UnitAssemblerModule extends PayloadBlock{
|
||||
@Override
|
||||
public void drawPlanRegion(BuildPlan plan, Eachable<BuildPlan> list){
|
||||
Draw.rect(region, plan.drawx(), plan.drawy());
|
||||
Draw.rect(plan.rotation >= 2 ? sideRegion2 : sideRegion1, plan.drawx(), plan.drawy(), plan.rotation * 90);
|
||||
drawSideRegion(plan.rotation >= 2 ? sideRegion2 : sideRegion1, plan.drawx(), plan.drawy(), plan.rotation);
|
||||
Draw.rect(topRegion, plan.drawx(), plan.drawy());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureRegion[] icons(){
|
||||
return new TextureRegion[]{region, sideRegion1, topRegion};
|
||||
return new TextureRegion[]{region, topRegion};
|
||||
}
|
||||
|
||||
public @Nullable UnitAssemblerBuild getLink(Team team, int x, int y, int rotation){
|
||||
@@ -93,11 +93,11 @@ public class UnitAssemblerModule extends PayloadBlock{
|
||||
//draw input conveyors
|
||||
for(int i = 0; i < 4; i++){
|
||||
if(blends(i) && i != rotation){
|
||||
Draw.rect(inRegion, x, y, (i * 90) - 180);
|
||||
drawSideRegion(inRegion, x, y, i - 2);
|
||||
}
|
||||
}
|
||||
|
||||
Draw.rect(rotation >= 2 ? sideRegion2 : sideRegion1, x, y, rotdeg());
|
||||
drawSideRegion(rotation >= 2 ? sideRegion2 : sideRegion1, x, y, rotation);
|
||||
|
||||
Draw.z(Layer.blockOver);
|
||||
payRotation = rotdeg();
|
||||
|
||||
@@ -142,11 +142,6 @@ public class UnitCargoLoader extends Block{
|
||||
return unit == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldActiveSound(){
|
||||
return shouldConsume() && warmup > 0.01f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
Draw.rect(block.region, x, y);
|
||||
|
||||
@@ -236,11 +236,6 @@ public class UnitFactory extends UnitBlock{
|
||||
return super.senseObject(sensor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldActiveSound(){
|
||||
return shouldConsume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double sense(LAccess sensor){
|
||||
if(sensor == LAccess.progress) return Mathf.clamp(fraction());
|
||||
|
||||
@@ -25,8 +25,9 @@ public class DrawFlame extends DrawBlock{
|
||||
|
||||
@Override
|
||||
public void load(Block block){
|
||||
block.emitLight = true;
|
||||
top = Core.atlas.find(block.name + "-top");
|
||||
block.clipSize = Math.max(block.clipSize, (lightRadius + lightSinMag) * 2f * block.size);
|
||||
block.lightClipSize = Math.max(block.lightClipSize, (lightRadius + lightSinMag) * 2f * block.size);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -18,6 +18,8 @@ public class DrawPlasma extends DrawFlame{
|
||||
|
||||
@Override
|
||||
public void load(Block block){
|
||||
block.emitLight = true;
|
||||
|
||||
regions = new TextureRegion[plasmas];
|
||||
for(int i = 0; i < regions.length; i++){
|
||||
regions[i] = Core.atlas.find(block.name + suffix + i);
|
||||
|
||||
@@ -29,7 +29,9 @@ public enum BlockFlag{
|
||||
launchPad,
|
||||
unitCargoUnloadPoint,
|
||||
unitAssembler,
|
||||
hasFogRadius;
|
||||
hasFogRadius,
|
||||
steamVent,
|
||||
blockRepair;
|
||||
|
||||
public final static BlockFlag[] all = values();
|
||||
|
||||
|
||||
@@ -581,18 +581,14 @@ public class StatValues{
|
||||
int count = 0;
|
||||
for(Ability ability : abilities){
|
||||
if(ability.display){
|
||||
t.table(Styles.grayPanel, a -> {
|
||||
a.add("[accent]" + ability.localized()).padBottom(4).center().top().expandX();
|
||||
a.row();
|
||||
a.left().top().defaults().left();
|
||||
ability.addStats(a);
|
||||
}).pad(5).margin(10).growX().top().uniformX();
|
||||
ability.display(t);
|
||||
|
||||
if((++count) == 2){
|
||||
count = 0;
|
||||
t.row();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user