This commit is contained in:
Anuken 2020-10-19 10:04:10 -04:00
parent 7f21d61078
commit 80f801db36
22 changed files with 228 additions and 128 deletions

Binary file not shown.

View File

@ -80,7 +80,7 @@ public class WaveSpawner{
Unit unit = group.createUnit(state.rules.waveTeam, state.wave - 1); Unit unit = group.createUnit(state.rules.waveTeam, state.wave - 1);
unit.set(spawnX + Tmp.v1.x, spawnY + Tmp.v1.y); unit.set(spawnX + Tmp.v1.x, spawnY + Tmp.v1.y);
Time.run(Math.min(i * 5, 60 * 2), () -> spawnEffect(unit)); spawnEffect(unit);
} }
}); });
} }

View File

@ -34,10 +34,10 @@ public class FlyingAI extends AIController{
Teamc result = target(x, y, range, air, ground); Teamc result = target(x, y, range, air, ground);
if(result != null) return result; if(result != null) return result;
if(ground) result = targetFlag(x, y, BlockFlag.producer, true); if(ground) result = targetFlag(x, y, BlockFlag.generator, true);
if(result != null) return result; if(result != null) return result;
if(ground) result = targetFlag(x, y, BlockFlag.turret, true); if(ground) result = targetFlag(x, y, BlockFlag.core, true);
if(result != null) return result; if(result != null) return result;
return null; return null;

View File

@ -14,6 +14,8 @@ import mindustry.world.blocks.*;
import mindustry.world.blocks.campaign.*; import mindustry.world.blocks.campaign.*;
import mindustry.world.blocks.defense.*; import mindustry.world.blocks.defense.*;
import mindustry.world.blocks.defense.turrets.*; import mindustry.world.blocks.defense.turrets.*;
import mindustry.world.blocks.defense.turrets.PointDefenseTurret;
import mindustry.world.blocks.defense.turrets.TractorBeamTurret;
import mindustry.world.blocks.distribution.*; import mindustry.world.blocks.distribution.*;
import mindustry.world.blocks.environment.*; import mindustry.world.blocks.environment.*;
import mindustry.world.blocks.experimental.*; import mindustry.world.blocks.experimental.*;

View File

@ -10,6 +10,7 @@ import mindustry.entities.bullet.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.meta.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
@ -897,6 +898,7 @@ public class UnitTypes implements ContentList{
range = 140f; range = 140f;
faceTarget = false; faceTarget = false;
armor = 4f; armor = 4f;
targetFlag = BlockFlag.factory;
weapons.add(new Weapon(){{ weapons.add(new Weapon(){{
minShootVelocity = 0.75f; minShootVelocity = 0.75f;
@ -977,6 +979,7 @@ public class UnitTypes implements ContentList{
engineOffset = 21; engineOffset = 21;
engineSize = 5.3f; engineSize = 5.3f;
hitSize = 56f; hitSize = 56f;
targetFlag = BlockFlag.battery;
BulletType missiles = new MissileBulletType(2.7f, 10){{ BulletType missiles = new MissileBulletType(2.7f, 10){{
width = 8f; width = 8f;
@ -1051,6 +1054,7 @@ public class UnitTypes implements ContentList{
hitSize = 58f; hitSize = 58f;
destructibleWreck = false; destructibleWreck = false;
armor = 13f; armor = 13f;
targetFlag = BlockFlag.reactor;
BulletType fragBullet = new FlakBulletType(4f, 5){{ BulletType fragBullet = new FlakBulletType(4f, 5){{
shootEffect = Fx.shootBig; shootEffect = Fx.shootBig;
@ -1246,6 +1250,7 @@ public class UnitTypes implements ContentList{
buildSpeed = 2.5f; buildSpeed = 2.5f;
range = 140f; range = 140f;
targetAir = false; targetAir = false;
targetFlag = BlockFlag.battery;
ammoType = AmmoTypes.powerHigh; ammoType = AmmoTypes.powerHigh;
@ -1654,7 +1659,7 @@ public class UnitTypes implements ContentList{
rotateSpeed = 15f; rotateSpeed = 15f;
accel = 0.1f; accel = 0.1f;
itemCapacity = 30; itemCapacity = 30;
health = 120f; health = 150f;
engineOffset = 6f; engineOffset = 6f;
hitSize = 8f; hitSize = 8f;
commandLimit = 3; commandLimit = 3;
@ -1665,7 +1670,7 @@ public class UnitTypes implements ContentList{
y = 1f; y = 1f;
top = false; top = false;
bullet = new BasicBulletType(2.5f, 9){{ bullet = new BasicBulletType(2.5f, 10){{
width = 7f; width = 7f;
height = 9f; height = 9f;
lifetime = 60f; lifetime = 60f;
@ -1689,7 +1694,7 @@ public class UnitTypes implements ContentList{
rotateSpeed = 17f; rotateSpeed = 17f;
accel = 0.1f; accel = 0.1f;
itemCapacity = 50; itemCapacity = 50;
health = 150f; health = 170f;
engineOffset = 6f; engineOffset = 6f;
hitSize = 9f; hitSize = 9f;
rotateShooting = false; rotateShooting = false;
@ -1706,7 +1711,7 @@ public class UnitTypes implements ContentList{
shotDelay = 4f; shotDelay = 4f;
spacing = 0f; spacing = 0f;
bullet = new BasicBulletType(3f, 9){{ bullet = new BasicBulletType(3f, 10){{
width = 7f; width = 7f;
height = 9f; height = 9f;
lifetime = 60f; lifetime = 60f;
@ -1730,7 +1735,7 @@ public class UnitTypes implements ContentList{
rotateSpeed = 19f; rotateSpeed = 19f;
accel = 0.11f; accel = 0.11f;
itemCapacity = 70; itemCapacity = 70;
health = 190f; health = 220f;
engineOffset = 6f; engineOffset = 6f;
hitSize = 10f; hitSize = 10f;
commandLimit = 7; commandLimit = 7;
@ -1745,7 +1750,7 @@ public class UnitTypes implements ContentList{
inaccuracy = 3f; inaccuracy = 3f;
shotDelay = 3f; shotDelay = 3f;
bullet = new BasicBulletType(3.5f, 9){{ bullet = new BasicBulletType(3.5f, 10{{
width = 6.5f; width = 6.5f;
height = 11f; height = 11f;
lifetime = 70f; lifetime = 70f;

View File

@ -98,7 +98,7 @@ abstract class PuddleComp implements Posc, Puddlec, Drawc{
boolean onLiquid = tile.floor().isLiquid; boolean onLiquid = tile.floor().isLiquid;
float f = Mathf.clamp(amount / (maxLiquid / 1.5f)); float f = Mathf.clamp(amount / (maxLiquid / 1.5f));
float smag = onLiquid ? 0.8f : 0f; float smag = onLiquid ? 0.8f : 0f;
float sscl = 20f; float sscl = 25f;
Draw.color(tmp.set(liquid.color).shiftValue(-0.05f)); Draw.color(tmp.set(liquid.color).shiftValue(-0.05f));
Fill.circle(x + Mathf.sin(Time.time() + seeds * 532, sscl, smag), y + Mathf.sin(Time.time() + seeds * 53, sscl, smag), f * 8f); Fill.circle(x + Mathf.sin(Time.time() + seeds * 532, sscl, smag), y + Mathf.sin(Time.time() + seeds * 53, sscl, smag), f * 8f);

View File

@ -89,7 +89,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
case rotation -> rotation; case rotation -> rotation;
case health -> health; case health -> health;
case maxHealth -> maxHealth; case maxHealth -> maxHealth;
case ammo -> state.rules.unitAmmo ? type.ammoCapacity : ammo; case ammo -> !state.rules.unitAmmo ? type.ammoCapacity : ammo;
case ammoCapacity -> type.ammoCapacity; case ammoCapacity -> type.ammoCapacity;
case x -> World.conv(x); case x -> World.conv(x);
case y -> World.conv(y); case y -> World.conv(y);

View File

@ -41,7 +41,7 @@ public class AmmoTypes implements ContentList{
@Override @Override
public void resupply(Unit unit){ public void resupply(Unit unit){
float range = unit.hitSize + 60f; float range = unit.hitSize + 60f;
Tile closest = Vars.indexer.findClosestFlag(unit.x, unit.y, unit.team, BlockFlag.powerRes); Tile closest = Vars.indexer.findClosestFlag(unit.x, unit.y, unit.team, BlockFlag.battery);
if(closest != null && closest.build != null && unit.within(closest.build, range) && closest.build.power != null){ if(closest != null && closest.build != null && unit.within(closest.build, range) && closest.build.power != null){
var build = closest.build; var build = closest.build;

View File

@ -28,6 +28,7 @@ import mindustry.world.blocks.environment.*;
import mindustry.world.blocks.payloads.*; import mindustry.world.blocks.payloads.*;
import mindustry.world.blocks.units.*; import mindustry.world.blocks.units.*;
import mindustry.world.consumers.*; import mindustry.world.consumers.*;
import mindustry.world.meta.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
@ -58,6 +59,7 @@ public class UnitType extends UnlockableContent{
public Effect fallEffect = Fx.fallSmoke; public Effect fallEffect = Fx.fallSmoke;
public Effect fallThrusterEffect = Fx.fallSmoke; public Effect fallThrusterEffect = Fx.fallSmoke;
public Seq<Ability> abilities = new Seq<>(); public Seq<Ability> abilities = new Seq<>();
public BlockFlag targetFlag = BlockFlag.generator;
public int legCount = 4, legGroupSize = 2; public int legCount = 4, legGroupSize = 2;
public float legLength = 10f, legSpeed = 0.1f, legTrns = 1f, legBaseOffset = 0f, legMoveSpace = 1f, legExtension = 0, legPairOffset = 0, legLengthScl = 1f, kinematicScl = 1f, maxStretch = 1.75f; public float legLength = 10f, legSpeed = 0.1f, legTrns = 1f, legBaseOffset = 0f, legMoveSpace = 1f, legExtension = 0, legPairOffset = 0, legLengthScl = 1f, kinematicScl = 1f, maxStretch = 1.75f;

View File

@ -457,18 +457,23 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
if(mode == look && !sector.hasBase()){ if(mode == look && !sector.hasBase()){
shouldHide = false; shouldHide = false;
Sector from = findLauncher(sector); Sector from = findLauncher(sector);
CoreBlock block = from.info.bestCoreType instanceof CoreBlock b ? b : (CoreBlock)Blocks.coreShard; if(from == null){
//free launch.
control.playSector(sector);
}else{
CoreBlock block = from.info.bestCoreType instanceof CoreBlock b ? b : (CoreBlock)Blocks.coreShard;
loadouts.show(block, from, () -> { loadouts.show(block, from, () -> {
from.removeItems(universe.getLastLoadout().requirements()); from.removeItems(universe.getLastLoadout().requirements());
from.removeItems(universe.getLaunchResources()); from.removeItems(universe.getLaunchResources());
launching = true; launching = true;
zoom = 0.5f; zoom = 0.5f;
ui.hudfrag.showLaunchDirect(); ui.hudfrag.showLaunchDirect();
Time.runTask(launchDuration, () -> control.playSector(from, sector)); Time.runTask(launchDuration, () -> control.playSector(from, sector));
}); });
}
}else if(mode == select){ }else if(mode == select){
listener.get(sector); listener.get(sector);
}else{ }else{

View File

@ -0,0 +1,67 @@
package mindustry.world.blocks.defense.turrets;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.logic.*;
import mindustry.world.*;
import mindustry.world.consumers.*;
import mindustry.world.meta.*;
import static mindustry.Vars.*;
public abstract class BaseTurret extends Block{
public float range = 80f;
public float rotateSpeed = 5;
public boolean acceptCoolant = true;
/** Effect displayed when coolant is used. */
public Effect coolEffect = Fx.fuelburn;
/** How much reload is lowered by for each unit of liquid of heat capacity. */
public float coolantMultiplier = 5f;
public BaseTurret(String name){
super(name);
update = true;
solid = true;
outlineIcon = true;
}
@Override
public void init(){
if(acceptCoolant && !consumes.has(ConsumeType.liquid)){
hasLiquids = true;
consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 0.2f)).update(false).boost();
}
super.init();
}
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, range, Pal.placing);
}
@Override
public void setStats(){
super.setStats();
stats.add(BlockStat.shootRange, range / tilesize, StatUnit.blocks);
}
public class BaseTurretBuild extends Building implements Ranged{
public float rotation = 90;
@Override
public float range(){
return range;
}
@Override
public void drawSelect(){
Drawf.dashCircle(x, y, range, team.color);
}
}
}

View File

@ -1,4 +1,4 @@
package mindustry.world.blocks.defense; package mindustry.world.blocks.defense.turrets;
import arc.graphics.*; import arc.graphics.*;
import arc.graphics.g2d.*; import arc.graphics.g2d.*;
@ -11,12 +11,9 @@ import mindustry.content.*;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
import mindustry.world.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
import static mindustry.Vars.*; public class PointDefenseTurret extends ReloadTurret{
public class PointDefenseTurret extends Block{
public final int timerTarget = timers++; public final int timerTarget = timers++;
public float retargetTime = 5f; public float retargetTime = 5f;
@ -27,9 +24,6 @@ public class PointDefenseTurret extends Block{
public Effect hitEffect = Fx.pointHit; public Effect hitEffect = Fx.pointHit;
public Effect shootEffect = Fx.sparkShoot; public Effect shootEffect = Fx.sparkShoot;
public float range = 80f;
public float reloadTime = 30f;
public float rotateSpeed = 20;
public float shootCone = 5f; public float shootCone = 5f;
public float bulletDamage = 10f; public float bulletDamage = 10f;
public float shootLength = 3f; public float shootLength = 3f;
@ -37,13 +31,12 @@ public class PointDefenseTurret extends Block{
public PointDefenseTurret(String name){ public PointDefenseTurret(String name){
super(name); super(name);
outlineIcon = true; rotateSpeed = 20f;
update = true; reloadTime = 30f;
}
@Override coolantMultiplier = 2f;
public void drawPlace(int x, int y, int rotation, boolean valid){ //disabled due to version mismatch problems
Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, range, Pal.accent); acceptCoolant = false;
} }
@Override @Override
@ -55,12 +48,10 @@ public class PointDefenseTurret extends Block{
public void setStats(){ public void setStats(){
super.setStats(); super.setStats();
stats.add(BlockStat.shootRange, range / tilesize, StatUnit.blocks);
stats.add(BlockStat.reload, 60f / reloadTime, StatUnit.none); stats.add(BlockStat.reload, 60f / reloadTime, StatUnit.none);
} }
public class PointDefenseBuild extends Building{ public class PointDefenseBuild extends ReloadTurretBuild{
public float rotation = 90, reload;
public @Nullable Bullet target; public @Nullable Bullet target;
@Override @Override
@ -76,14 +67,18 @@ public class PointDefenseTurret extends Block{
target = null; target = null;
} }
if(acceptCoolant){
updateCooling();
}
//look at target //look at target
if(target != null && target.within(this, range) && target.team != team && target.type() != null && target.type().hittable){ if(target != null && target.within(this, range) && target.team != team && target.type() != null && target.type().hittable){
float dest = angleTo(target); float dest = angleTo(target);
rotation = Angles.moveToward(rotation, dest, rotateSpeed * edelta()); rotation = Angles.moveToward(rotation, dest, rotateSpeed * edelta());
reload -= edelta(); reload += edelta();
//shoot when possible //shoot when possible
if(Angles.within(rotation, dest, shootCone) && reload <= 0f){ if(Angles.within(rotation, dest, shootCone) && reload >= reloadTime){
if(target.damage() > bulletDamage){ if(target.damage() > bulletDamage){
target.damage(target.damage() - bulletDamage); target.damage(target.damage() - bulletDamage);
}else{ }else{
@ -95,18 +90,13 @@ public class PointDefenseTurret extends Block{
beamEffect.at(x + Tmp.v1.x, y + Tmp.v1.y, rotation, color, new Vec2().set(target)); beamEffect.at(x + Tmp.v1.x, y + Tmp.v1.y, rotation, color, new Vec2().set(target));
shootEffect.at(x + Tmp.v1.x, y + Tmp.v1.y, rotation, color); shootEffect.at(x + Tmp.v1.x, y + Tmp.v1.y, rotation, color);
hitEffect.at(target.x, target.y, color); hitEffect.at(target.x, target.y, color);
reload = reloadTime; reload = 0;
} }
}else{ }else{
target = null; target = null;
} }
} }
@Override
public void drawSelect(){
Drawf.dashCircle(x, y, range, Pal.accent);
}
@Override @Override
public void draw(){ public void draw(){
Draw.rect(baseRegion, x, y); Draw.rect(baseRegion, x, y);

View File

@ -0,0 +1,49 @@
package mindustry.world.blocks.defense.turrets;
import arc.math.*;
import arc.util.*;
import mindustry.type.*;
import mindustry.world.consumers.*;
import mindustry.world.meta.*;
import mindustry.world.meta.values.*;
import static mindustry.Vars.*;
public abstract class ReloadTurret extends BaseTurret{
public float reloadTime = 10f;
public ReloadTurret(String name){
super(name);
}
@Override
public void setStats(){
super.setStats();
if(acceptCoolant){
stats.add(BlockStat.booster, new BoosterListValue(reloadTime, consumes.<ConsumeLiquidBase>get(ConsumeType.liquid).amount, coolantMultiplier, true, l -> consumes.liquidfilters.get(l.id)));
}
}
public class ReloadTurretBuild extends BaseTurretBuild{
public float reload;
protected void updateCooling(){
float maxUsed = consumes.<ConsumeLiquidBase>get(ConsumeType.liquid).amount;
Liquid liquid = liquids.current();
float used = Math.min(Math.min(liquids.get(liquid), maxUsed * Time.delta), Math.max(0, ((reloadTime - reload) / coolantMultiplier) / liquid.heatCapacity)) * baseReloadSpeed();
reload += used * liquid.heatCapacity * coolantMultiplier;
liquids.remove(liquid, used);
if(Mathf.chance(0.06 * used)){
coolEffect.at(x + Mathf.range(size * tilesize / 2f), y + Mathf.range(size * tilesize / 2f));
}
}
protected float baseReloadSpeed(){
return efficiency();
}
}
}

View File

@ -1,4 +1,4 @@
package mindustry.world.blocks.defense; package mindustry.world.blocks.defense.turrets;
import arc.graphics.*; import arc.graphics.*;
import arc.graphics.g2d.*; import arc.graphics.g2d.*;
@ -9,12 +9,13 @@ import mindustry.annotations.Annotations.*;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
import mindustry.world.*; import mindustry.type.*;
import mindustry.world.consumers.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
public class TractorBeamTurret extends Block{ public class TractorBeamTurret extends BaseTurret{
public final int timerTarget = timers++; public final int timerTarget = timers++;
public float retargetTime = 5f; public float retargetTime = 5f;
@ -22,8 +23,6 @@ public class TractorBeamTurret extends Block{
public @Load("@-laser") TextureRegion laser; public @Load("@-laser") TextureRegion laser;
public @Load("@-laser-end") TextureRegion laserEnd; public @Load("@-laser-end") TextureRegion laserEnd;
public float range = 80f;
public float rotateSpeed = 10;
public float shootCone = 6f; public float shootCone = 6f;
public float laserWidth = 0.6f; public float laserWidth = 0.6f;
public float force = 0.3f; public float force = 0.3f;
@ -35,14 +34,11 @@ public class TractorBeamTurret extends Block{
public TractorBeamTurret(String name){ public TractorBeamTurret(String name){
super(name); super(name);
update = true; rotateSpeed = 10f;
solid = true; coolantMultiplier = 1f;
outlineIcon = true;
}
@Override //disabled due to version mismatch problems
public void drawPlace(int x, int y, int rotation, boolean valid){ acceptCoolant = false;
Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, range, Pal.accent);
} }
@Override @Override
@ -54,17 +50,16 @@ public class TractorBeamTurret extends Block{
public void setStats(){ public void setStats(){
super.setStats(); super.setStats();
stats.add(BlockStat.shootRange, range / tilesize, StatUnit.blocks);
stats.add(BlockStat.targetsAir, targetAir); stats.add(BlockStat.targetsAir, targetAir);
stats.add(BlockStat.targetsGround, targetGround); stats.add(BlockStat.targetsGround, targetGround);
stats.add(BlockStat.damage, damage * 60f, StatUnit.perSecond); stats.add(BlockStat.damage, damage * 60f, StatUnit.perSecond);
} }
public class TractorBeamBuild extends Building{ public class TractorBeamBuild extends BaseTurretBuild{
public float rotation = 90;
public @Nullable Unit target; public @Nullable Unit target;
public float lastX, lastY, strength; public float lastX, lastY, strength;
public boolean any; public boolean any;
public float coolant = 1f;
@Override @Override
public void updateTile(){ public void updateTile(){
@ -74,6 +69,23 @@ public class TractorBeamTurret extends Block{
target = Units.closestEnemy(team, x, y, range, u -> u.checkTarget(targetAir, targetGround)); target = Units.closestEnemy(team, x, y, range, u -> u.checkTarget(targetAir, targetGround));
} }
//consume coolant
if(target != null && acceptCoolant){
float maxUsed = consumes.<ConsumeLiquidBase>get(ConsumeType.liquid).amount;
Liquid liquid = liquids.current();
float used = Math.min(Math.min(liquids.get(liquid), maxUsed * Time.delta), Math.max(0, (1f / coolantMultiplier) / liquid.heatCapacity));
liquids.remove(liquid, used);
if(Mathf.chance(0.06 * used)){
coolEffect.at(x + Mathf.range(size * tilesize / 2f), y + Mathf.range(size * tilesize / 2f));
}
coolant = 1f + (used * liquid.heatCapacity * coolantMultiplier);
}
//look at target //look at target
if(target != null && target.within(this, range) && target.team() != team && target.type.flying && efficiency() > 0.01f){ if(target != null && target.within(this, range) && target.team() != team && target.type.flying && efficiency() > 0.01f){
any = true; any = true;
@ -98,8 +110,8 @@ public class TractorBeamTurret extends Block{
} }
@Override @Override
public void drawSelect(){ public float efficiency() {
Drawf.dashCircle(x, y, range, Pal.accent); return super.efficiency() * coolant;
} }
@Override @Override

View File

@ -21,7 +21,6 @@ import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
import mindustry.logic.*; import mindustry.logic.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.blocks.*; import mindustry.world.blocks.*;
import mindustry.world.consumers.*; import mindustry.world.consumers.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
@ -29,7 +28,7 @@ import mindustry.world.meta.values.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
public abstract class Turret extends Block{ public abstract class Turret extends ReloadTurret{
//after being logic-controlled and this amount of time passes, the turret will resume normal AI //after being logic-controlled and this amount of time passes, the turret will resume normal AI
public final static float logicControlCooldown = 60 * 2; public final static float logicControlCooldown = 60 * 2;
@ -45,8 +44,6 @@ public abstract class Turret extends Block{
public int maxAmmo = 30; public int maxAmmo = 30;
public int ammoPerShot = 1; public int ammoPerShot = 1;
public float ammoEjectBack = 1f; public float ammoEjectBack = 1f;
public float range = 50f;
public float reloadTime = 10f;
public float inaccuracy = 0f; public float inaccuracy = 0f;
public float velocityInaccuracy = 0f; public float velocityInaccuracy = 0f;
public int shots = 1; public int shots = 1;
@ -54,7 +51,6 @@ public abstract class Turret extends Block{
public float recoilAmount = 1f; public float recoilAmount = 1f;
public float restitution = 0.02f; public float restitution = 0.02f;
public float cooldown = 0.02f; public float cooldown = 0.02f;
public float rotateSpeed = 5f; //in degrees per tick
public float shootCone = 8f; public float shootCone = 8f;
public float shootShake = 0f; public float shootShake = 0f;
public float xRand = 0f; public float xRand = 0f;
@ -65,10 +61,7 @@ public abstract class Turret extends Block{
public boolean targetAir = true; public boolean targetAir = true;
public boolean targetGround = true; public boolean targetGround = true;
public boolean acceptCoolant = true; public boolean acceptCoolant = true;
/** How much reload is lowered by for each unit of liquid of heat capacity. */
public float coolantMultiplier = 5f;
/** Effect displayed when coolant is used. */
public Effect coolEffect = Fx.fuelburn;
public Sortf unitSort = Unit::dst2; public Sortf unitSort = Unit::dst2;
protected Vec2 tr = new Vec2(); protected Vec2 tr = new Vec2();
@ -108,7 +101,6 @@ public abstract class Turret extends Block{
public void setStats(){ public void setStats(){
super.setStats(); super.setStats();
stats.add(BlockStat.shootRange, range / tilesize, StatUnit.blocks);
stats.add(BlockStat.inaccuracy, (int)inaccuracy, StatUnit.degrees); stats.add(BlockStat.inaccuracy, (int)inaccuracy, StatUnit.degrees);
stats.add(BlockStat.reload, 60f / reloadTime * shots, StatUnit.none); stats.add(BlockStat.reload, 60f / reloadTime * shots, StatUnit.none);
stats.add(BlockStat.targetsAir, targetAir); stats.add(BlockStat.targetsAir, targetAir);
@ -134,32 +126,22 @@ public abstract class Turret extends Block{
return new TextureRegion[]{baseRegion, region}; return new TextureRegion[]{baseRegion, region};
} }
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, range, Pal.placing);
}
public static abstract class AmmoEntry{ public static abstract class AmmoEntry{
public int amount; public int amount;
public abstract BulletType type(); public abstract BulletType type();
} }
public class TurretBuild extends Building implements ControlBlock, Ranged{ public class TurretBuild extends ReloadTurretBuild implements ControlBlock{
public Seq<AmmoEntry> ammo = new Seq<>(); public Seq<AmmoEntry> ammo = new Seq<>();
public int totalAmmo; public int totalAmmo;
public float reload, rotation = 90, recoil, heat, logicControlTime = -1; public float recoil, heat, logicControlTime = -1;
public int shotCounter; public int shotCounter;
public boolean logicShooting = false; public boolean logicShooting = false;
public @Nullable Posc target; public @Nullable Posc target;
public Vec2 targetPos = new Vec2(); public Vec2 targetPos = new Vec2();
public BlockUnitc unit = Nulls.blockUnit; public BlockUnitc unit = Nulls.blockUnit;
@Override
public float range(){
return range;
}
@Override @Override
public void created(){ public void created(){
unit = (BlockUnitc)UnitTypes.block.create(team); unit = (BlockUnitc)UnitTypes.block.create(team);
@ -197,8 +179,8 @@ public abstract class Turret extends Block{
case ammo -> totalAmmo; case ammo -> totalAmmo;
case ammoCapacity -> maxAmmo; case ammoCapacity -> maxAmmo;
case rotation -> rotation; case rotation -> rotation;
case shootX -> targetPos.x; case shootX -> World.conv(targetPos.x);
case shootY -> targetPos.y; case shootY -> World.conv(targetPos.y);
case shooting -> (isControlled() ? unit.isShooting() : logicControlled() ? logicShooting : validateTarget()) ? 1 : 0; case shooting -> (isControlled() ? unit.isShooting() : logicControlled() ? logicShooting : validateTarget()) ? 1 : 0;
default -> super.sense(sensor); default -> super.sense(sensor);
}; };
@ -301,11 +283,6 @@ public abstract class Turret extends Block{
} }
} }
@Override
public void drawSelect(){
Drawf.dashCircle(x, y, range, team.color);
}
@Override @Override
public void handleLiquid(Building source, Liquid liquid, float amount){ public void handleLiquid(Building source, Liquid liquid, float amount){
if(acceptCoolant && liquids.currentAmount() <= 0.001f){ if(acceptCoolant && liquids.currentAmount() <= 0.001f){
@ -315,20 +292,6 @@ public abstract class Turret extends Block{
super.handleLiquid(source, liquid, amount); super.handleLiquid(source, liquid, amount);
} }
protected void updateCooling(){
float maxUsed = consumes.<ConsumeLiquidBase>get(ConsumeType.liquid).amount;
Liquid liquid = liquids.current();
float used = Math.min(Math.min(liquids.get(liquid), maxUsed * Time.delta), Math.max(0, ((reloadTime - reload) / coolantMultiplier) / liquid.heatCapacity)) * baseReloadSpeed();
reload += used * liquid.heatCapacity * coolantMultiplier;
liquids.remove(liquid, used);
if(Mathf.chance(0.06 * used)){
coolEffect.at(x + Mathf.range(size * tilesize / 2f), y + Mathf.range(size * tilesize / 2f));
}
}
protected boolean validateTarget(){ protected boolean validateTarget(){
return !Units.invalidateTarget(target, team, x, y) || isControlled() || logicControlled(); return !Units.invalidateTarget(target, team, x, y) || isControlled() || logicControlled();
} }
@ -453,10 +416,6 @@ public abstract class Turret extends Block{
ammoUseEffect.at(x - Angles.trnsx(rotation, ammoEjectBack), y - Angles.trnsy(rotation, ammoEjectBack), rotation); ammoUseEffect.at(x - Angles.trnsx(rotation, ammoEjectBack), y - Angles.trnsy(rotation, ammoEjectBack), rotation);
} }
protected float baseReloadSpeed(){
return efficiency();
}
@Override @Override
public void write(Writes write){ public void write(Writes write){
super.write(write); super.write(write);

View File

@ -336,16 +336,18 @@ public class ItemBridge extends Block{
Tile other = world.tile(link); Tile other = world.tile(link);
if(items.total() >= itemCapacity) return false;
if(linked(source)) return true;
if(linkValid(tile, other)){ if(linkValid(tile, other)){
int rel = relativeTo(other); int rel = relativeTo(other);
int rel2 = relativeTo(Edges.getFacingEdge(source, this)); int rel2 = relativeTo(Edges.getFacingEdge(source, this));
if(rel == rel2) return false; return rel != rel2;
}else{
return linked(source) && items.total() < itemCapacity;
} }
return items.total() < itemCapacity; return false;
} }
@Override @Override
@ -359,16 +361,18 @@ public class ItemBridge extends Block{
Tile other = world.tile(link); Tile other = world.tile(link);
if(!(liquids.current() == liquid || liquids.get(liquids.current()) < 0.2f)) return false;
if(linked(source)) return true;
if(linkValid(tile, other)){ if(linkValid(tile, other)){
int rel = relativeTo(other.x, other.y); int rel = relativeTo(other.x, other.y);
int rel2 = relativeTo(Edges.getFacingEdge(source, this)); int rel2 = relativeTo(Edges.getFacingEdge(source, this));
if(rel == rel2) return false; return rel != rel2;
}else if(!(linked(source))){
return false;
} }
return (liquids.current() == liquid || liquids.get(liquids.current()) < 0.2f); return false;
} }
protected boolean linked(Building source){ protected boolean linked(Building source){

View File

@ -20,7 +20,7 @@ public class Battery extends PowerDistributor{
super(name); super(name);
outputsPower = true; outputsPower = true;
consumesPower = true; consumesPower = true;
flags = EnumSet.of(BlockFlag.powerRes); flags = EnumSet.of(BlockFlag.battery);
} }
public class BatteryBuild extends Building{ public class BatteryBuild extends Building{

View File

@ -5,6 +5,7 @@ import arc.graphics.*;
import arc.graphics.g2d.*; import arc.graphics.g2d.*;
import arc.math.*; import arc.math.*;
import arc.math.geom.*; import arc.math.geom.*;
import arc.struct.*;
import arc.util.*; import arc.util.*;
import arc.util.io.*; import arc.util.io.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
@ -47,6 +48,7 @@ public class NuclearReactor extends PowerGenerator{
hasItems = true; hasItems = true;
hasLiquids = true; hasLiquids = true;
rebuildable = false; rebuildable = false;
flags = EnumSet.of(BlockFlag.reactor);
} }
@Override @Override

View File

@ -18,7 +18,7 @@ public class PowerGenerator extends PowerDistributor{
super(name); super(name);
sync = true; sync = true;
baseExplosiveness = 5f; baseExplosiveness = 5f;
flags = EnumSet.of(BlockFlag.producer); flags = EnumSet.of(BlockFlag.generator);
} }
@Override @Override

View File

@ -2,6 +2,7 @@ package mindustry.world.blocks.production;
import arc.graphics.g2d.*; import arc.graphics.g2d.*;
import arc.math.*; import arc.math.*;
import arc.struct.*;
import arc.util.io.*; import arc.util.io.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.entities.*; import mindustry.entities.*;
@ -23,9 +24,6 @@ public class GenericCrafter extends Block{
public DrawBlock drawer = new DrawBlock(); public DrawBlock drawer = new DrawBlock();
//public Cons<GenericCrafterEntity> drawer = null;
//public Prov<TextureRegion[]> drawIcons = null;
public GenericCrafter(String name){ public GenericCrafter(String name){
super(name); super(name);
update = true; update = true;
@ -34,6 +32,7 @@ public class GenericCrafter extends Block{
idleSound = Sounds.machine; idleSound = Sounds.machine;
sync = true; sync = true;
idleSoundVolume = 0.03f; idleSoundVolume = 0.03f;
flags = EnumSet.of(BlockFlag.factory);
} }
@Override @Override

View File

@ -47,7 +47,7 @@ public class CoreBlock extends StorageBlock{
update = true; update = true;
hasItems = true; hasItems = true;
priority = TargetPriority.core; priority = TargetPriority.core;
flags = EnumSet.of(BlockFlag.core, BlockFlag.producer, BlockFlag.unitModifier); flags = EnumSet.of(BlockFlag.core, BlockFlag.unitModifier);
unitCapModifier = 10; unitCapModifier = 10;
activeSound = Sounds.respawning; activeSound = Sounds.respawning;
activeSoundVolume = 1f; activeSoundVolume = 1f;

View File

@ -4,18 +4,22 @@ package mindustry.world.meta;
public enum BlockFlag{ public enum BlockFlag{
/** Enemy core; primary target for all units. */ /** Enemy core; primary target for all units. */
core, core,
/** Producer of important goods. */ /** Something that generates power. */
producer, generator,
/** A turret. */ /** Any turret. */
turret, turret,
/** A block that transforms resources. */
factory,
/** Repair point. */ /** Repair point. */
repair, repair,
/** Rally point. */ /** Rally point. */
rally, rally,
/** Block that stored power for resupply. */ /** Block that stored power for resupply. */
powerRes, battery,
/** Block used for resupply. */ /** Block used for resupply. */
resupply, resupply,
/** Any reactor block. */
reactor,
/** Any block that boosts unit capacity. */ /** Any block that boosts unit capacity. */
unitModifier; unitModifier;