Merge remote-tracking branch 'origin/master'

This commit is contained in:
Anuken
2026-01-01 11:14:05 -05:00
50 changed files with 359 additions and 15 deletions

View File

@@ -66,6 +66,8 @@ public class Block extends UnlockableContent implements Senseable{
public boolean acceptsItems = false;
/** If true, this block won't be affected by the onlyDepositCore rule. */
public boolean alwaysAllowDeposit = false;
/** Cooldown, in seconds, applied to player item depositing when any item is deposited to this block. Overrides the itemDepositCooldown if non-negative. */
public float depositCooldown = -1f;
/** If true, all item capacities of this block are separate instead of pooled as one number. */
public boolean separateItemCapacity = false;
/** maximum items this block can carry (usually, this is per-type of item) */

View File

@@ -1,5 +1,7 @@
package mindustry.world.blocks.defense.turrets;
import arc.*;
import arc.graphics.*;
import arc.math.*;
import arc.struct.*;
import arc.util.*;
@@ -8,6 +10,7 @@ import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.logic.*;
import mindustry.ui.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
import mindustry.world.consumers.*;
@@ -21,6 +24,8 @@ public class BaseTurret extends Block{
public float rotateSpeed = 5;
public float fogRadiusMultiplier = 1f;
public boolean disableOverlapCheck = false;
/** How much time to start shooting after placement. */
public float activationTime = 0f;
/** Effect displayed when coolant is used. */
public Effect coolEffect = Fx.fuelburn;
@@ -90,10 +95,31 @@ public class BaseTurret extends Block{
super.setStats();
stats.add(Stat.shootRange, range / tilesize, StatUnit.blocks);
if(activationTime > 0) stats.add(Stat.activationTime, activationTime / 60f, StatUnit.seconds);
}
@Override
public void setBars(){
super.setBars();
if(activationTime > 0){
addBar("activationtimer", (BaseTurretBuild entity) ->
new Bar(() ->
(entity.activationTimer > 0)? Core.bundle.format("bar.activationtimer", Mathf.ceil(entity.activationTimer / 60f)) : Core.bundle.get("bar.activated"),
() -> (entity.activationTimer > 0)? Pal.lightOrange : Pal.techBlue,
() -> 1 - entity.activationTimer / activationTime));
}
}
public class BaseTurretBuild extends Building implements Ranged, RotBlock{
public float rotation = 90;
public float activationTimer = 0;
@Override
public void placed(){
super.placed();
activationTimer = activationTime;
}
@Override
public float range(){
@@ -113,5 +139,10 @@ public class BaseTurret extends Block{
public float estimateDps(){
return 0f;
}
@Override
public BlockStatus status() {
return (activationTimer <= 0)? super.status() : BlockStatus.inactive;
}
}
}

View File

@@ -26,7 +26,7 @@ public class ReloadTurret extends BaseTurret{
public float reloadCounter;
protected void updateCooling(){
if(reloadCounter < reload && coolant != null && coolant.efficiency(this) > 0 && efficiency > 0){
if(canReload() && coolant != null && coolant.efficiency(this) > 0 && efficiency > 0){
float capacity = coolant instanceof ConsumeLiquidFilter filter ? filter.getConsumed(this).heatCapacity : (coolant.consumes(liquids.current()) ? liquids.current().heatCapacity : 0.4f);
float amount = coolant.amount * coolant.efficiency(this);
coolant.update(this);
@@ -45,5 +45,9 @@ public class ReloadTurret extends BaseTurret{
protected float baseReloadSpeed(){
return efficiency;
}
protected boolean canReload(){
return reloadCounter < reload;
}
}
}

View File

@@ -76,6 +76,11 @@ public class TractorBeamTurret extends BaseTurret{
@Override
public void updateTile(){
if(activationTimer > 0){
activationTimer -= Time.delta;
return;
}
float eff = efficiency * coolantMultiplier, edelta = eff * delta();
//retarget

View File

@@ -278,6 +278,8 @@ public class Turret extends ReloadTurret{
public @Nullable float[] curRecoils;
public float shootWarmup, charge, warmupHold = 0f;
public int totalShots, barrelCounter;
public float excessReload = 0;
public int reloadShots = 0;
public boolean logicShooting = false;
public @Nullable Posc target;
public Vec2 targetPos = new Vec2();
@@ -419,7 +421,7 @@ public class Turret extends ReloadTurret{
}
public boolean isActive(){
return (target != null || wasShooting) && enabled;
return (target != null || wasShooting) && enabled && activationTimer <= 0;
}
public void targetPosition(Posc pos){
@@ -481,8 +483,6 @@ public class Turret extends ReloadTurret{
shootWarmup = Mathf.lerpDelta(shootWarmup, warmupTarget, shootWarmupSpeed * (warmupTarget > 0 ? efficiency : 1f));
}
wasShooting = false;
curRecoil = Mathf.approachDelta(curRecoil, 0, 1 / recoilTime);
if(recoils > 0){
if(curRecoils == null) curRecoils = new float[recoils];
@@ -515,8 +515,11 @@ public class Turret extends ReloadTurret{
if(reloadWhileCharging || !charging()){
updateReload();
updateCooling();
capReload();
}
wasShooting = false;
if(state.rules.fog){
float newRange = hasAmmo() ? peekAmmo().rangeChange : 0f;
if(newRange != lastRangeChange){
@@ -525,6 +528,11 @@ public class Turret extends ReloadTurret{
}
}
if(activationTimer > 0){
activationTimer -= Time.delta;
return;
}
if(hasAmmo()){
if(Float.isNaN(reloadCounter)) reloadCounter = 0;
@@ -673,11 +681,30 @@ public class Turret extends ReloadTurret{
return queuedBullets > 0 && shoot.firstShotDelay > 0;
}
protected void updateReload(){
reloadCounter += delta() * ammoReloadMultiplier() * baseReloadSpeed();
@Override
protected boolean canReload(){
//keep reloading as the turret keeps shooting
return reloadShots < 1 || wasShooting;
}
//cap reload for visual reasons
protected void updateReload(){
if(!canReload()) return;
reloadCounter += delta() * ammoReloadMultiplier() * baseReloadSpeed();
}
protected void capReload(){
//cap reload for visual reasons, need to store the excess reload to keep the firerate consistent
if(canReload() && reloadCounter >= reload){
reloadShots += (int)(reloadCounter / reload);
excessReload += reloadCounter % reload;
}
reloadCounter = Math.min(reloadCounter, reload);
reloadShots = Math.min(reloadShots, 5);
if(!wasShooting){
reloadShots = 0;
excessReload = 0;
}
}
@Override
@@ -687,12 +714,14 @@ public class Turret extends ReloadTurret{
protected void updateShooting(){
if(reloadCounter >= reload && !charging() && shootWarmup >= minWarmup){
if(reloadShots > 0 && !charging() && shootWarmup >= minWarmup){
BulletType type = peekAmmo();
shoot(type);
reloadCounter %= reload;
reloadCounter = excessReload;
excessReload = 0;
reloadShots--;
}
}

View File

@@ -7,7 +7,8 @@ public enum BlockStatus{
active(Color.valueOf("5ce677")),
noOutput(Color.orange),
noInput(Pal.remove),
logicDisable(Color.valueOf("8a73c6"));
logicDisable(Color.valueOf("8a73c6")),
inactive(Color.lightGray);
public final Color color;

View File

@@ -95,6 +95,7 @@ public class Stat implements Comparable<Stat>{
shieldHealth = new Stat("shieldHealth", StatCat.function),
cooldownTime = new Stat("cooldownTime", StatCat.function),
regenerationRate = new Stat("regenerationRate", StatCat.function),
activationTime = new Stat("activationTime", StatCat.function),
moduleTier = new Stat("moduletier", StatCat.function),
unitType = new Stat("unittype", StatCat.function),

View File

@@ -704,6 +704,16 @@ public class StatValues{
sep(bt, "@bullet.armorpierce");
}
if(type.armorMultiplier != 1f){
if(type.armorMultiplier > 1f){
sep(bt, Core.bundle.format("bullet.armorweakness", (int)(type.armorMultiplier * 100)));
}else if(Mathf.sign(type.armorMultiplier) == 1){
sep(bt, Core.bundle.format("bullet.armorpiercing", (int)((1 - type.armorMultiplier) * 100)));
}else{
sep(bt, Core.bundle.format("bullet.antiarmor", (-type.armorMultiplier)));
}
}
if(type.maxDamageFraction > 0){
sep(bt, Core.bundle.format("bullet.maxdamagefraction", (int)(type.maxDamageFraction * 100)));
}