Merged some turret classes
This commit is contained in:
@@ -1359,7 +1359,7 @@ public class Blocks implements ContentList{
|
|||||||
rotatespeed = 10f;
|
rotatespeed = 10f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
scatter = new BurstTurret("scatter"){{
|
scatter = new ItemTurret("scatter"){{
|
||||||
requirements(Category.turret, ItemStack.with(Items.copper, 85, Items.lead, 45));
|
requirements(Category.turret, ItemStack.with(Items.copper, 85, Items.lead, 45));
|
||||||
ammo(
|
ammo(
|
||||||
Items.scrap, Bullets.flakScrap,
|
Items.scrap, Bullets.flakScrap,
|
||||||
@@ -1399,13 +1399,14 @@ public class Blocks implements ContentList{
|
|||||||
shootSound = Sounds.flame;
|
shootSound = Sounds.flame;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
hail = new ArtilleryTurret("hail"){{
|
hail = new ItemTurret("hail"){{
|
||||||
requirements(Category.turret, ItemStack.with(Items.copper, 40, Items.graphite, 17));
|
requirements(Category.turret, ItemStack.with(Items.copper, 40, Items.graphite, 17));
|
||||||
ammo(
|
ammo(
|
||||||
Items.graphite, Bullets.artilleryDense,
|
Items.graphite, Bullets.artilleryDense,
|
||||||
Items.silicon, Bullets.artilleryHoming,
|
Items.silicon, Bullets.artilleryHoming,
|
||||||
Items.pyratite, Bullets.artilleryIncendiary
|
Items.pyratite, Bullets.artilleryIncendiary
|
||||||
);
|
);
|
||||||
|
targetAir = false;
|
||||||
reloadTime = 60f;
|
reloadTime = 60f;
|
||||||
recoilAmount = 2f;
|
recoilAmount = 2f;
|
||||||
range = 230f;
|
range = 230f;
|
||||||
@@ -1415,7 +1416,7 @@ public class Blocks implements ContentList{
|
|||||||
shootSound = Sounds.artillery;
|
shootSound = Sounds.artillery;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
wave = new LiquidTurret("wave"){{
|
wave = new ItemTurret("wave"){{
|
||||||
requirements(Category.turret, ItemStack.with(Items.metaglass, 45, Items.lead, 75));
|
requirements(Category.turret, ItemStack.with(Items.metaglass, 45, Items.lead, 75));
|
||||||
ammo(
|
ammo(
|
||||||
Liquids.water, Bullets.waterShot,
|
Liquids.water, Bullets.waterShot,
|
||||||
@@ -1423,11 +1424,13 @@ public class Blocks implements ContentList{
|
|||||||
Liquids.cryofluid, Bullets.cryoShot,
|
Liquids.cryofluid, Bullets.cryoShot,
|
||||||
Liquids.oil, Bullets.oilShot
|
Liquids.oil, Bullets.oilShot
|
||||||
);
|
);
|
||||||
|
targetAir = false;
|
||||||
size = 2;
|
size = 2;
|
||||||
recoilAmount = 0f;
|
recoilAmount = 0f;
|
||||||
reloadTime = 2f;
|
reloadTime = 2f;
|
||||||
inaccuracy = 5f;
|
inaccuracy = 5f;
|
||||||
shootCone = 50f;
|
shootCone = 50f;
|
||||||
|
liquidCapacity = 10f;
|
||||||
shootEffect = Fx.shootLiquid;
|
shootEffect = Fx.shootLiquid;
|
||||||
range = 110f;
|
range = 110f;
|
||||||
health = 250 * size * size;
|
health = 250 * size * size;
|
||||||
@@ -1474,7 +1477,7 @@ public class Blocks implements ContentList{
|
|||||||
shootSound = Sounds.spark;
|
shootSound = Sounds.spark;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
swarmer = new BurstTurret("swarmer"){{
|
swarmer = new ItemTurret("swarmer"){{
|
||||||
requirements(Category.turret, ItemStack.with(Items.graphite, 35, Items.titanium, 35, Items.plastanium, 45, Items.silicon, 30));
|
requirements(Category.turret, ItemStack.with(Items.graphite, 35, Items.titanium, 35, Items.plastanium, 45, Items.silicon, 30));
|
||||||
ammo(
|
ammo(
|
||||||
Items.blastCompound, Bullets.missileExplosive,
|
Items.blastCompound, Bullets.missileExplosive,
|
||||||
@@ -1492,7 +1495,7 @@ public class Blocks implements ContentList{
|
|||||||
shootSound = Sounds.missile;
|
shootSound = Sounds.missile;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
salvo = new BurstTurret("salvo"){{
|
salvo = new ItemTurret("salvo"){{
|
||||||
requirements(Category.turret, ItemStack.with(Items.copper, 105, Items.graphite, 95, Items.titanium, 60));
|
requirements(Category.turret, ItemStack.with(Items.copper, 105, Items.graphite, 95, Items.titanium, 60));
|
||||||
ammo(
|
ammo(
|
||||||
Items.copper, Bullets.standardCopper,
|
Items.copper, Bullets.standardCopper,
|
||||||
@@ -1570,7 +1573,7 @@ public class Blocks implements ContentList{
|
|||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
|
|
||||||
ripple = new ArtilleryTurret("ripple"){{
|
ripple = new ItemTurret("ripple"){{
|
||||||
requirements(Category.turret, ItemStack.with(Items.copper, 150, Items.graphite, 135, Items.titanium, 60));
|
requirements(Category.turret, ItemStack.with(Items.copper, 150, Items.graphite, 135, Items.titanium, 60));
|
||||||
ammo(
|
ammo(
|
||||||
Items.graphite, Bullets.artilleryDense,
|
Items.graphite, Bullets.artilleryDense,
|
||||||
@@ -1579,6 +1582,8 @@ public class Blocks implements ContentList{
|
|||||||
Items.blastCompound, Bullets.artilleryExplosive,
|
Items.blastCompound, Bullets.artilleryExplosive,
|
||||||
Items.plastanium, Bullets.artilleryPlastic
|
Items.plastanium, Bullets.artilleryPlastic
|
||||||
);
|
);
|
||||||
|
|
||||||
|
targetAir = false;
|
||||||
size = 3;
|
size = 3;
|
||||||
shots = 4;
|
shots = 4;
|
||||||
inaccuracy = 12f;
|
inaccuracy = 12f;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ public class ArtilleryBulletType extends BasicBulletType{
|
|||||||
collidesTiles = false;
|
collidesTiles = false;
|
||||||
collides = false;
|
collides = false;
|
||||||
collidesAir = false;
|
collidesAir = false;
|
||||||
|
scaleVelocity = true;
|
||||||
hitShake = 1f;
|
hitShake = 1f;
|
||||||
hitSound = Sounds.explosion;
|
hitSound = Sounds.explosion;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ public abstract class BulletType extends Content{
|
|||||||
public boolean collides = true;
|
public boolean collides = true;
|
||||||
/** Whether velocity is inherited from the shooter. */
|
/** Whether velocity is inherited from the shooter. */
|
||||||
public boolean keepVelocity = true;
|
public boolean keepVelocity = true;
|
||||||
|
/** Whether to scale velocity to disappear at the target position. Used for artillery. */
|
||||||
|
public boolean scaleVelocity;
|
||||||
|
|
||||||
//additional effects
|
//additional effects
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc{
|
|||||||
shootY = mountY + Angles.trnsy(weaponRotation, weapon.shootX * i, weapon.shootY);
|
shootY = mountY + Angles.trnsy(weaponRotation, weapon.shootX * i, weapon.shootY);
|
||||||
float shootAngle = weapon.rotate ? weaponRotation + 90 : Angles.angle(shootX, shootY, mount.aimX, mount.aimY) + (this.rotation - angleTo(mount.aimX, mount.aimY));
|
float shootAngle = weapon.rotate ? weaponRotation + 90 : Angles.angle(shootX, shootY, mount.aimX, mount.aimY) + (this.rotation - angleTo(mount.aimX, mount.aimY));
|
||||||
|
|
||||||
shoot(weapon, shootX, shootY, shootAngle, -i);
|
shoot(weapon, shootX, shootY, mount.aimX, mount.aimY, shootAngle, -i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mount.weapon.mirror) mount.side = !mount.side;
|
if(mount.weapon.mirror) mount.side = !mount.side;
|
||||||
@@ -120,23 +120,24 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void shoot(Weapon weapon, float x, float y, float rotation, int side){
|
private void shoot(Weapon weapon, float x, float y, float aimX, float aimY, float rotation, int side){
|
||||||
float baseX = this.x, baseY = this.y;
|
float baseX = this.x, baseY = this.y;
|
||||||
|
|
||||||
weapon.shootSound.at(x, y, Mathf.random(0.8f, 1.0f));
|
weapon.shootSound.at(x, y, Mathf.random(0.8f, 1.0f));
|
||||||
|
|
||||||
|
BulletType ammo = weapon.bullet;
|
||||||
|
float lifeScl = ammo.scaleVelocity ? Mathf.clamp(Mathf.dst(x, y, aimX, aimY) / ammo.range()) : 1f;
|
||||||
|
|
||||||
sequenceNum = 0;
|
sequenceNum = 0;
|
||||||
if(weapon.shotDelay > 0.01f){
|
if(weapon.shotDelay > 0.01f){
|
||||||
Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> {
|
Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> {
|
||||||
Time.run(sequenceNum * weapon.shotDelay, () -> bullet(weapon, x + this.x - baseX, y + this.y - baseY, f + Mathf.range(weapon.inaccuracy)));
|
Time.run(sequenceNum * weapon.shotDelay, () -> bullet(weapon, x + this.x - baseX, y + this.y - baseY, f + Mathf.range(weapon.inaccuracy), lifeScl));
|
||||||
sequenceNum++;
|
sequenceNum++;
|
||||||
});
|
});
|
||||||
}else{
|
}else{
|
||||||
Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> bullet(weapon, x, y, f + Mathf.range(weapon.inaccuracy)));
|
Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> bullet(weapon, x, y, f + Mathf.range(weapon.inaccuracy), lifeScl));
|
||||||
}
|
}
|
||||||
|
|
||||||
BulletType ammo = weapon.bullet;
|
|
||||||
|
|
||||||
Tmp.v1.trns(rotation + 180f, ammo.recoil);
|
Tmp.v1.trns(rotation + 180f, ammo.recoil);
|
||||||
|
|
||||||
if(this instanceof Velc){
|
if(this instanceof Velc){
|
||||||
@@ -153,8 +154,8 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc{
|
|||||||
ammo.smokeEffect.at(x + Tmp.v1.x, y + Tmp.v1.y, rotation, parentize ? this : null);
|
ammo.smokeEffect.at(x + Tmp.v1.x, y + Tmp.v1.y, rotation, parentize ? this : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bullet(Weapon weapon, float x, float y, float angle){
|
private void bullet(Weapon weapon, float x, float y, float angle, float lifescl){
|
||||||
Tmp.v1.trns(angle, 3f);
|
Tmp.v1.trns(angle, 3f);
|
||||||
weapon.bullet.create(this, team(), x + Tmp.v1.x, y + Tmp.v1.y, angle, (1f - weapon.velocityRnd) + Mathf.random(weapon.velocityRnd));
|
weapon.bullet.create(this, team(), x + Tmp.v1.x, y + Tmp.v1.y, angle, (1f - weapon.velocityRnd) + Mathf.random(weapon.velocityRnd), lifescl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,8 +54,8 @@ public class CubemapMesh implements Disposable{
|
|||||||
};
|
};
|
||||||
|
|
||||||
private final Mesh mesh;
|
private final Mesh mesh;
|
||||||
private final Cubemap map;
|
|
||||||
private final Shader shader;
|
private final Shader shader;
|
||||||
|
private Cubemap map;
|
||||||
|
|
||||||
public CubemapMesh(Cubemap map){
|
public CubemapMesh(Cubemap map){
|
||||||
this.map = map;
|
this.map = map;
|
||||||
@@ -69,6 +69,10 @@ public class CubemapMesh implements Disposable{
|
|||||||
shader = new Shader(Core.files.internal("shaders/cubemap.vert"), Core.files.internal("shaders/cubemap.frag"));
|
shader = new Shader(Core.files.internal("shaders/cubemap.vert"), Core.files.internal("shaders/cubemap.frag"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setCubemap(Cubemap map){
|
||||||
|
this.map = map;
|
||||||
|
}
|
||||||
|
|
||||||
public void render(Mat3D projection){
|
public void render(Mat3D projection){
|
||||||
map.bind();
|
map.bind();
|
||||||
shader.bind();
|
shader.bind();
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
package mindustry.world.blocks.defense.turrets;
|
|
||||||
|
|
||||||
import arc.math.*;
|
|
||||||
import mindustry.entities.bullet.*;
|
|
||||||
|
|
||||||
import static mindustry.Vars.tilesize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Artillery turrets have special shooting calculations done to hit targets.
|
|
||||||
*/
|
|
||||||
public class ArtilleryTurret extends ItemTurret{
|
|
||||||
public float velocityInaccuracy = 0f;
|
|
||||||
|
|
||||||
public ArtilleryTurret(String name){
|
|
||||||
super(name);
|
|
||||||
targetAir = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ArtilleryTurretEntity extends ItemTurretEntity{
|
|
||||||
@Override
|
|
||||||
protected void shoot(BulletType ammo){
|
|
||||||
recoil = recoilAmount;
|
|
||||||
heat = 1f;
|
|
||||||
|
|
||||||
BulletType type = peekAmmo();
|
|
||||||
|
|
||||||
tr.trns(rotation, size * tilesize / 2);
|
|
||||||
|
|
||||||
float dst = dst(targetPos.x, targetPos.y);
|
|
||||||
float maxTraveled = type.lifetime * type.speed;
|
|
||||||
|
|
||||||
for(int i = 0; i < shots; i++){
|
|
||||||
ammo.create(tile.entity, team, x + tr.x, y + tr.y,
|
|
||||||
rotation + Mathf.range(inaccuracy + type.inaccuracy), 1f + Mathf.range(velocityInaccuracy), (dst / maxTraveled));
|
|
||||||
}
|
|
||||||
|
|
||||||
effects();
|
|
||||||
useAmmo();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
package mindustry.world.blocks.defense.turrets;
|
|
||||||
|
|
||||||
import arc.math.*;
|
|
||||||
import arc.util.*;
|
|
||||||
import mindustry.entities.bullet.*;
|
|
||||||
|
|
||||||
import static mindustry.Vars.tilesize;
|
|
||||||
|
|
||||||
public class BurstTurret extends ItemTurret{
|
|
||||||
public float burstSpacing = 5;
|
|
||||||
|
|
||||||
public BurstTurret(String name){
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class BurstTurretEntity extends ItemTurretEntity{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void shoot(BulletType ammo){
|
|
||||||
heat = 1f;
|
|
||||||
|
|
||||||
for(int i = 0; i < shots; i++){
|
|
||||||
Time.run(burstSpacing * i, () -> {
|
|
||||||
if(!(tile.entity instanceof TurretEntity) || !hasAmmo()) return;
|
|
||||||
|
|
||||||
recoil = recoilAmount;
|
|
||||||
|
|
||||||
tr.trns(rotation, size * tilesize / 2, Mathf.range(xRand));
|
|
||||||
bullet(ammo, rotation + Mathf.range(inaccuracy));
|
|
||||||
effects();
|
|
||||||
useAmmo();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,7 +9,6 @@ import mindustry.entities.bullet.*;
|
|||||||
import static mindustry.Vars.tilesize;
|
import static mindustry.Vars.tilesize;
|
||||||
|
|
||||||
public class ChargeTurret extends PowerTurret{
|
public class ChargeTurret extends PowerTurret{
|
||||||
|
|
||||||
public float chargeTime = 30f;
|
public float chargeTime = 30f;
|
||||||
public int chargeEffects = 5;
|
public int chargeEffects = 5;
|
||||||
public float chargeMaxDelay = 10f;
|
public float chargeMaxDelay = 10f;
|
||||||
@@ -27,13 +26,13 @@ public class ChargeTurret extends PowerTurret{
|
|||||||
public void shoot(BulletType ammo){
|
public void shoot(BulletType ammo){
|
||||||
useAmmo();
|
useAmmo();
|
||||||
|
|
||||||
tr.trns(rotation, size * tilesize / 2);
|
tr.trns(rotation, size * tilesize / 2f);
|
||||||
chargeBeginEffect.at(x + tr.x, y + tr.y, rotation);
|
chargeBeginEffect.at(x + tr.x, y + tr.y, rotation);
|
||||||
|
|
||||||
for(int i = 0; i < chargeEffects; i++){
|
for(int i = 0; i < chargeEffects; i++){
|
||||||
Time.run(Mathf.random(chargeMaxDelay), () -> {
|
Time.run(Mathf.random(chargeMaxDelay), () -> {
|
||||||
if(!isValid()) return;
|
if(!isValid()) return;
|
||||||
tr.trns(rotation, size * tilesize / 2);
|
tr.trns(rotation, size * tilesize / 2f);
|
||||||
chargeEffect.at(x + tr.x, y + tr.y, rotation);
|
chargeEffect.at(x + tr.x, y + tr.y, rotation);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -42,7 +41,7 @@ public class ChargeTurret extends PowerTurret{
|
|||||||
|
|
||||||
Time.run(chargeTime, () -> {
|
Time.run(chargeTime, () -> {
|
||||||
if(!isValid()) return;
|
if(!isValid()) return;
|
||||||
tr.trns(rotation, size * tilesize / 2);
|
tr.trns(rotation, size * tilesize / 2f);
|
||||||
recoil = recoilAmount;
|
recoil = recoilAmount;
|
||||||
heat = 1f;
|
heat = 1f;
|
||||||
bullet(ammo, rotation + Mathf.range(inaccuracy));
|
bullet(ammo, rotation + Mathf.range(inaccuracy));
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
package mindustry.world.blocks.defense.turrets;
|
|
||||||
|
|
||||||
import arc.*;
|
|
||||||
import arc.math.*;
|
|
||||||
import arc.util.*;
|
|
||||||
import mindustry.content.*;
|
|
||||||
import mindustry.entities.*;
|
|
||||||
import mindustry.game.EventType.*;
|
|
||||||
import mindustry.gen.*;
|
|
||||||
import mindustry.type.*;
|
|
||||||
import mindustry.world.consumers.*;
|
|
||||||
import mindustry.world.meta.*;
|
|
||||||
import mindustry.world.meta.values.*;
|
|
||||||
|
|
||||||
import static mindustry.Vars.tilesize;
|
|
||||||
|
|
||||||
public class CooledTurret extends Turret{
|
|
||||||
/** How much reload is lowered by for each unit of liquid of heat capacity. */
|
|
||||||
public float coolantMultiplier = 5f;
|
|
||||||
public Effect coolEffect = Fx.fuelburn;
|
|
||||||
|
|
||||||
public CooledTurret(String name){
|
|
||||||
super(name);
|
|
||||||
hasLiquids = true;
|
|
||||||
liquidCapacity = 20f;
|
|
||||||
|
|
||||||
consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 0.2f)).update(false).boost();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setStats(){
|
|
||||||
super.setStats();
|
|
||||||
|
|
||||||
stats.add(BlockStat.booster, new BoosterListValue(reloadTime, consumes.<ConsumeLiquidBase>get(ConsumeType.liquid).amount, coolantMultiplier, true, l -> consumes.liquidfilters.get(l.id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CooledTurretEntity extends TurretEntity{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleLiquid(Tilec source, Liquid liquid, float amount){
|
|
||||||
if(liquids.currentAmount() <= 0.001f){
|
|
||||||
Events.fire(Trigger.turretCool);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.handleLiquid(source, liquid, amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void updateShooting(){
|
|
||||||
super.updateShooting();
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -18,7 +18,7 @@ import mindustry.world.meta.values.*;
|
|||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class ItemTurret extends CooledTurret{
|
public class ItemTurret extends Turret{
|
||||||
public int maxAmmo = 30;
|
public int maxAmmo = 30;
|
||||||
public ObjectMap<Item, BulletType> ammoTypes = new ObjectMap<>();
|
public ObjectMap<Item, BulletType> ammoTypes = new ObjectMap<>();
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public class LiquidTurret extends Turret{
|
|||||||
|
|
||||||
public LiquidTurret(String name){
|
public LiquidTurret(String name){
|
||||||
super(name);
|
super(name);
|
||||||
|
acceptCoolant = false;
|
||||||
hasLiquids = true;
|
hasLiquids = true;
|
||||||
activeSound = Sounds.spray;
|
activeSound = Sounds.spray;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import arc.util.ArcAnnotate.*;
|
|||||||
import mindustry.entities.bullet.*;
|
import mindustry.entities.bullet.*;
|
||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
|
|
||||||
public class PowerTurret extends CooledTurret{
|
public class PowerTurret extends Turret{
|
||||||
public @NonNull BulletType shootType;
|
public @NonNull BulletType shootType;
|
||||||
public float powerUse = 1f;
|
public float powerUse = 1f;
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ public class PowerTurret extends CooledTurret{
|
|||||||
super.init();
|
super.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PowerTurretEntity extends CooledTurretEntity{
|
public class PowerTurretEntity extends TurretEntity{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BulletType useAmmo(){
|
public BulletType useAmmo(){
|
||||||
|
|||||||
@@ -8,18 +8,22 @@ import arc.graphics.g2d.*;
|
|||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
|
import arc.util.*;
|
||||||
import arc.util.io.*;
|
import arc.util.io.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.bullet.*;
|
import mindustry.entities.bullet.*;
|
||||||
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.*;
|
import mindustry.world.blocks.*;
|
||||||
|
import mindustry.world.consumers.*;
|
||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
|
import mindustry.world.meta.values.*;
|
||||||
|
|
||||||
import static mindustry.Vars.tilesize;
|
import static mindustry.Vars.tilesize;
|
||||||
|
|
||||||
@@ -38,6 +42,7 @@ public abstract class Turret extends Block{
|
|||||||
public float range = 50f;
|
public float range = 50f;
|
||||||
public float reloadTime = 10f;
|
public float reloadTime = 10f;
|
||||||
public float inaccuracy = 0f;
|
public float inaccuracy = 0f;
|
||||||
|
public float velocityInaccuracy = 0f;
|
||||||
public int shots = 1;
|
public int shots = 1;
|
||||||
public float spread = 4f;
|
public float spread = 4f;
|
||||||
public float recoilAmount = 1f;
|
public float recoilAmount = 1f;
|
||||||
@@ -47,9 +52,15 @@ public abstract class Turret extends Block{
|
|||||||
public float shootCone = 8f;
|
public float shootCone = 8f;
|
||||||
public float shootShake = 0f;
|
public float shootShake = 0f;
|
||||||
public float xRand = 0f;
|
public float xRand = 0f;
|
||||||
|
public float burstSpacing = 0;
|
||||||
public boolean alternate = false;
|
public boolean alternate = false;
|
||||||
public boolean targetAir = true;
|
public boolean targetAir = true;
|
||||||
public boolean targetGround = true;
|
public boolean targetGround = 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;
|
||||||
|
|
||||||
protected Vec2 tr = new Vec2();
|
protected Vec2 tr = new Vec2();
|
||||||
protected Vec2 tr2 = new Vec2();
|
protected Vec2 tr2 = new Vec2();
|
||||||
@@ -75,6 +86,7 @@ public abstract class Turret extends Block{
|
|||||||
group = BlockGroup.turrets;
|
group = BlockGroup.turrets;
|
||||||
flags = EnumSet.of(BlockFlag.turret);
|
flags = EnumSet.of(BlockFlag.turret);
|
||||||
outlineIcon = true;
|
outlineIcon = true;
|
||||||
|
liquidCapacity = 20f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -92,6 +104,20 @@ public abstract class Turret extends Block{
|
|||||||
stats.add(BlockStat.shots, shots, StatUnit.none);
|
stats.add(BlockStat.shots, shots, StatUnit.none);
|
||||||
stats.add(BlockStat.targetsAir, targetAir);
|
stats.add(BlockStat.targetsAir, targetAir);
|
||||||
stats.add(BlockStat.targetsGround, targetGround);
|
stats.add(BlockStat.targetsGround, targetGround);
|
||||||
|
|
||||||
|
if(acceptCoolant){
|
||||||
|
stats.add(BlockStat.booster, new BoosterListValue(reloadTime, consumes.<ConsumeLiquidBase>get(ConsumeType.liquid).amount, coolantMultiplier, true, l -> consumes.liquidfilters.get(l.id)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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
|
@Override
|
||||||
@@ -119,6 +145,7 @@ public abstract class Turret extends Block{
|
|||||||
public Vec2 targetPos = new Vec2();
|
public Vec2 targetPos = new Vec2();
|
||||||
public @NonNull BlockUnitc unit = Nulls.blockUnit;
|
public @NonNull BlockUnitc unit = Nulls.blockUnit;
|
||||||
|
|
||||||
|
@Override
|
||||||
public void created(){
|
public void created(){
|
||||||
unit = (BlockUnitc)UnitTypes.block.create(team);
|
unit = (BlockUnitc)UnitTypes.block.create(team);
|
||||||
unit.tile(this);
|
unit.tile(this);
|
||||||
@@ -196,14 +223,40 @@ public abstract class Turret extends Block{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
if(acceptCoolant){
|
||||||
|
updateCooling();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawSelect(){
|
public void drawSelect(){
|
||||||
Drawf.dashCircle(x, y, range, team.color);
|
Drawf.dashCircle(x, y, range, team.color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleLiquid(Tilec source, Liquid liquid, float amount){
|
||||||
|
if(acceptCoolant && liquids.currentAmount() <= 0.001f){
|
||||||
|
Events.fire(Trigger.turretCool);
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
return !Units.invalidateTarget(target, team, x, y) || isControlled();
|
||||||
}
|
}
|
||||||
@@ -232,7 +285,7 @@ public abstract class Turret extends Block{
|
|||||||
entry.amount -= ammoPerShot;
|
entry.amount -= ammoPerShot;
|
||||||
if(entry.amount == 0) ammo.pop();
|
if(entry.amount == 0) ammo.pop();
|
||||||
totalAmmo -= ammoPerShot;
|
totalAmmo -= ammoPerShot;
|
||||||
Time.run(reloadTime / 2f, () -> ejectEffects());
|
Time.run(reloadTime / 2f, this::ejectEffects);
|
||||||
return entry.type();
|
return entry.type();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,27 +319,48 @@ public abstract class Turret extends Block{
|
|||||||
recoil = recoilAmount;
|
recoil = recoilAmount;
|
||||||
heat = 1f;
|
heat = 1f;
|
||||||
|
|
||||||
if(alternate){
|
//when burst spacing is enabled, use the burst pattern
|
||||||
float i = (shotCounter % shots) - shots/2f + (((shots+1)%2) / 2f);
|
if(burstSpacing > 0.0001f){
|
||||||
|
|
||||||
tr.trns(rotation - 90, spread * i + Mathf.range(xRand), size * tilesize / 2);
|
|
||||||
bullet(type, rotation + Mathf.range(inaccuracy));
|
|
||||||
}else{
|
|
||||||
tr.trns(rotation, size * tilesize / 2f, Mathf.range(xRand));
|
|
||||||
|
|
||||||
for(int i = 0; i < shots; i++){
|
for(int i = 0; i < shots; i++){
|
||||||
bullet(type, rotation + Mathf.range(inaccuracy + type.inaccuracy) + (i - shots / 2f) * spread);
|
Time.run(burstSpacing * i, () -> {
|
||||||
|
if(!isValid() || !hasAmmo()) return;
|
||||||
|
|
||||||
|
recoil = recoilAmount;
|
||||||
|
|
||||||
|
tr.trns(rotation, size * tilesize / 2f, Mathf.range(xRand));
|
||||||
|
bullet(type, rotation + Mathf.range(inaccuracy));
|
||||||
|
effects();
|
||||||
|
useAmmo();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
//otherwise, use the normal shot pattern(s)
|
||||||
|
|
||||||
|
if(alternate){
|
||||||
|
float i = (shotCounter % shots) - shots/2f + (((shots+1)%2) / 2f);
|
||||||
|
|
||||||
|
tr.trns(rotation - 90, spread * i + Mathf.range(xRand), size * tilesize / 2f);
|
||||||
|
bullet(type, rotation + Mathf.range(inaccuracy));
|
||||||
|
}else{
|
||||||
|
tr.trns(rotation, size * tilesize / 2f, Mathf.range(xRand));
|
||||||
|
|
||||||
|
for(int i = 0; i < shots; i++){
|
||||||
|
bullet(type, rotation + Mathf.range(inaccuracy + type.inaccuracy) + (i - shots / 2f) * spread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shotCounter++;
|
||||||
|
|
||||||
|
effects();
|
||||||
|
useAmmo();
|
||||||
}
|
}
|
||||||
|
|
||||||
shotCounter++;
|
|
||||||
|
|
||||||
effects();
|
|
||||||
useAmmo();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void bullet(BulletType type, float angle){
|
protected void bullet(BulletType type, float angle){
|
||||||
type.create(this, team, x + tr.x, y + tr.y, angle);
|
float lifeScl = type.scaleVelocity ? Mathf.clamp(Mathf.dst(x, y, targetPos.x, targetPos.y) / type.range()) : 1f;
|
||||||
|
|
||||||
|
type.create(this, team, x + tr.x, y + tr.y, angle, 1f + Mathf.range(velocityInaccuracy), lifeScl);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void effects(){
|
protected void effects(){
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||||
archash=edaf52e6768e0c24cc4598de8105d07a6c66efd8
|
archash=316daf68d366d591ea1ae3caa30b1a5c0d838098
|
||||||
|
|||||||
Reference in New Issue
Block a user