WIP point laser turret

This commit is contained in:
Anuken 2022-06-23 20:57:22 -04:00
parent ac47d22ea1
commit be61b45d08
18 changed files with 202 additions and 61 deletions

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 629 B

After

Width:  |  Height:  |  Size: 629 B

View File

Before

Width:  |  Height:  |  Size: 639 B

After

Width:  |  Height:  |  Size: 639 B

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 783 B

After

Width:  |  Height:  |  Size: 783 B

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -380,9 +380,10 @@ editor.mapinfo = Map Info
editor.author = Author: editor.author = Author:
editor.description = Description: editor.description = Description:
editor.nodescription = A map must have a description of at least 4 characters before being published. editor.nodescription = A map must have a description of at least 4 characters before being published.
editor.waves = Waves: editor.waves = Waves
editor.rules = Rules: editor.rules = Rules
editor.generation = Generation: editor.generation = Generation
editor.objectives = Objectives
editor.ingame = Edit In-Game editor.ingame = Edit In-Game
editor.playtest = Playtest editor.playtest = Playtest
editor.publish.workshop = Publish On Workshop editor.publish.workshop = Publish On Workshop
@ -395,6 +396,8 @@ editor.filters.type = Map Type:
editor.filters.search = Search In: editor.filters.search = Search In:
editor.filters.author = Author editor.filters.author = Author
editor.filters.description = Description editor.filters.description = Description
editor.shiftx = Shift X
editor.shifty = Shift Y
workshop = Workshop workshop = Workshop
waves.title = Waves waves.title = Waves
waves.remove = Remove waves.remove = Remove
@ -2067,7 +2070,3 @@ unit.merui.name = Merui
unit.anthicus.name = Anthicus unit.anthicus.name = Anthicus
unit.elude.name = Elude unit.elude.name = Elude
unit.obviate.name = Obviate unit.obviate.name = Obviate
sector.two.name = Two
sector.three.name = Three
sector.four.name = Four
sector.five.name = Five

View File

@ -568,3 +568,4 @@
63116=shielded-wall|block-shielded-wall-ui 63116=shielded-wall|block-shielded-wall-ui
63115=fracture|block-fracture-ui 63115=fracture|block-fracture-ui
63114=renale|unit-renale-ui 63114=renale|unit-renale-ui
63113=lustre|block-lustre-ui

Binary file not shown.

View File

@ -8,6 +8,7 @@ import mindustry.entities.*;
import mindustry.entities.bullet.*; import mindustry.entities.bullet.*;
import mindustry.entities.effect.*; import mindustry.entities.effect.*;
import mindustry.entities.part.*; import mindustry.entities.part.*;
import mindustry.entities.part.DrawPart.*;
import mindustry.entities.pattern.*; import mindustry.entities.pattern.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
@ -23,8 +24,6 @@ import mindustry.world.blocks.heat.*;
import mindustry.world.blocks.legacy.*; import mindustry.world.blocks.legacy.*;
import mindustry.world.blocks.liquid.*; import mindustry.world.blocks.liquid.*;
import mindustry.world.blocks.logic.*; import mindustry.world.blocks.logic.*;
import mindustry.world.blocks.payloads.PayloadConveyor;
import mindustry.world.blocks.payloads.PayloadRouter;
import mindustry.world.blocks.payloads.*; import mindustry.world.blocks.payloads.*;
import mindustry.world.blocks.power.*; import mindustry.world.blocks.power.*;
import mindustry.world.blocks.production.*; import mindustry.world.blocks.production.*;
@ -135,7 +134,7 @@ public class Blocks{
duo, scatter, scorch, hail, arc, wave, lancer, swarmer, salvo, fuse, ripple, cyclone, foreshadow, spectre, meltdown, segment, parallax, tsunami, duo, scatter, scorch, hail, arc, wave, lancer, swarmer, salvo, fuse, ripple, cyclone, foreshadow, spectre, meltdown, segment, parallax, tsunami,
//turrets - erekir //turrets - erekir
breach, diffuse, sublimate, titan, disperse, afflict, fracture, breach, diffuse, sublimate, titan, disperse, afflict, lustre,
//units //units
groundFactory, airFactory, navalFactory, groundFactory, airFactory, navalFactory,
@ -4081,7 +4080,6 @@ public class Blocks{
limitRange(-5f); limitRange(-5f);
}}; }};
//TODO WIP
afflict = new PowerTurret("afflict"){{ afflict = new PowerTurret("afflict"){{
requirements(Category.turret, with(Items.surgeAlloy, 100, Items.silicon, 200, Items.graphite, 250, Items.oxide, 40)); requirements(Category.turret, with(Items.surgeAlloy, 100, Items.silicon, 200, Items.graphite, 250, Items.oxide, 40));
@ -4197,61 +4195,33 @@ public class Blocks{
limitRange(9f); limitRange(9f);
}}; }};
if(false) lustre = new ContinuousTurret("lustre"){{
fracture = new ItemTurret("fracture"){{
requirements(Category.turret, with(Items.beryllium, 150, Items.silicon, 200, Items.graphite, 200, Items.carbide, 50)); requirements(Category.turret, with(Items.beryllium, 150, Items.silicon, 200, Items.graphite, 200, Items.carbide, 50));
ammo( range = 100f;
Items.tungsten, new BasicBulletType(8f, 41){{
knockback = 4f;
width = 25f;
hitSize = 7f;
height = 20f;
shootEffect = Fx.shootBigColor;
smokeEffect = Fx.shootSmokeSquareSparse;
ammoMultiplier = 1;
hitColor = backColor = trailColor = Color.valueOf("ea8878");
frontColor = Color.valueOf("feb380");
trailWidth = 6f;
trailLength = 3;
hitEffect = despawnEffect = Fx.hitSquaresColor;
buildingDamageMultiplier = 0.2f;
if(false) shootType = new PointLaserBulletType(){{
spawnBullets.add(new BulletType(){{ damage = 150f;
instantDisappear = true; buildingDamageMultiplier = 0.3f;
lightning = 6; hitColor = Color.valueOf("fd9e81");
lightningLength = 10; }};
lightningLengthRand = 10;
lightningColor = Color.valueOf("ff6214");
lightningCone = 20f;
damage = 30;
despawnEffect = hitEffect = Fx.none;
}});
}}
);
coolantMultiplier = 6f;
shake = 1f;
//shoot = new ShootAlternate(){{
// shots = 3;
// barrels = 3;
//}};
drawer = new DrawTurret("reinforced-"){{ drawer = new DrawTurret("reinforced-"){{
var heatp = PartProgress.warmup.blend(p -> Mathf.absin(2f, 1f) * p.warmup, 0.2f);
parts.add(new RegionPart("-blade"){{ parts.add(new RegionPart("-blade"){{
progress = PartProgress.warmup; progress = PartProgress.warmup;
heatProgress = PartProgress.warmup.blend(PartProgress.recoil, 0.2f); heatProgress = PartProgress.warmup;
heatColor = Color.valueOf("ff6214"); heatColor = Color.valueOf("ff6214");
mirror = true; mirror = true;
under = true; under = true;
moveX = 2f; moveX = 2f;
moveRot = -7f; moveRot = -7f;
moves.add(new PartMove(PartProgress.recoil, 0f, -2f, 3f)); moves.add(new PartMove(PartProgress.warmup, 0f, -2f, 3f));
}}, }},
new RegionPart("-inner"){{ new RegionPart("-inner"){{
progress = PartProgress.recoil; heatProgress = heatp;
progress = PartProgress.warmup;
heatColor = Color.valueOf("ff6214"); heatColor = Color.valueOf("ff6214");
mirror = true; mirror = true;
under = false; under = false;
@ -4259,26 +4229,32 @@ public class Blocks{
moveY = -8f; moveY = -8f;
}}, }},
new RegionPart("-mid"){{ new RegionPart("-mid"){{
heatProgress = PartProgress.warmup.blend(PartProgress.recoil, 0.2f); heatProgress = heatp;
progress = PartProgress.warmup;
heatColor = Color.valueOf("ff6214"); heatColor = Color.valueOf("ff6214");
moveY = -8f; moveY = -8f;
progress = PartProgress.recoil;
mirror = false; mirror = false;
under = true; under = true;
}}); }});
}}; }};
shootY = 11f; shootWarmupSpeed = 0.08f;
shootCone = 360f;
aimChangeSpeed = 0.9f;
rotateSpeed = 0.9f;
shootY = 0.5f;
outlineColor = Pal.darkOutline; outlineColor = Pal.darkOutline;
size = 4; size = 4;
envEnabled |= Env.space; envEnabled |= Env.space;
reload = 30f; range = 250f;
recoil = 2f;
range = 125;
scaledHealth = 210; scaledHealth = 210;
rotateSpeed = 3f;
coolant = consume(new ConsumeLiquid(Liquids.water, 15f / 60f)); //TODO is this a good idea to begin with?
unitSort = UnitSorts.strongest;
consumeLiquid(Liquids.nitrogen, 5f / 60f);
}}; }};
//TODO 3 more turrets. //TODO 3 more turrets.

View File

@ -1003,6 +1003,11 @@ public class Fx{
Fill.circle(e.x, e.y, e.rotation * e.fout()); Fill.circle(e.x, e.y, e.rotation * e.fout());
}).layer(Layer.bullet - 0.001f), }).layer(Layer.bullet - 0.001f),
colorTrail = new Effect(50, e -> {
color(e.color);
Fill.circle(e.x, e.y, e.rotation * e.fout());
}),
absorb = new Effect(12, e -> { absorb = new Effect(12, e -> {
color(Pal.accent); color(Pal.accent);
stroke(2f * e.fout()); stroke(2f * e.fout());

View File

@ -298,6 +298,39 @@ public class Damage{
units.each(cons); units.each(cons);
} }
/**
* Damages entities on a point.
* Only enemies of the specified team are damaged.
*/
public static void collidePoint(Bullet hitter, Team team, Effect effect, float x, float y){
if(hitter.type.collidesGround){
Building build = world.build(World.toTile(x), World.toTile(y));
if(build != null && hitter.damage > 0){
float health = build.health;
if(build.team != team && build.collide(hitter)){
build.collision(hitter);
hitter.type.hit(hitter, x, y);
}
//try to heal the tile
if(hitter.type.testCollision(hitter, build)){
hitter.type.hitTile(hitter, build, x, y, health, false);
}
}
}
Units.nearbyEnemies(team, rect.setCentered(x, y, 1f), u -> {
if(u.checkTarget(hitter.type.collidesAir, hitter.type.collidesGround) && u.hittable()){
effect.at(x, y);
u.collision(hitter, x, y);
hitter.collision(u, x, y);
}
});
}
/** /**
* Casts forward in a line. * Casts forward in a line.
* @return the first encountered object. * @return the first encountered object.

View File

@ -4,7 +4,7 @@ import mindustry.content.*;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.gen.*; import mindustry.gen.*;
/** Basic continuous bullet type that does not draw itself. Essentially abstract. */ /** Basic continuous (line) bullet type that does not draw itself. Essentially abstract. */
public class ContinuousBulletType extends BulletType{ public class ContinuousBulletType extends BulletType{
public float length = 220f; public float length = 220f;
public float shake = 0f; public float shake = 0f;

View File

@ -0,0 +1,85 @@
package mindustry.entities.bullet;
import arc.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.util.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.graphics.*;
/** A continuous bullet type that only damages in a point. */
public class PointLaserBulletType extends BulletType{
public String sprite = "drill-laser";
public TextureRegion laser, laserEnd;
public Color color = Color.white;
public Effect beamEffect = Fx.colorTrail;
public float beamEffectInterval = 3f, beamEffectSize = 3.5f;
public float oscScl = 2f, oscMag = 0.3f;
public float damageInterval = 5f;
public float shake = 0f;
public PointLaserBulletType(){
removeAfterPierce = false;
speed = 0f;
despawnEffect = Fx.none;
shootEffect = Fx.none;
lifetime = 20f;
impact = true;
keepVelocity = false;
collides = false;
pierce = true;
hittable = false;
absorbable = false;
optimalLifeFract = 0.5f;
//just make it massive, users of this bullet can adjust as necessary
drawSize = 1000f;
}
@Override
public float estimateDPS(){
return damage * 100f / damageInterval * 3f;
}
@Override
public void load(){
super.load();
laser = Core.atlas.find(sprite);
laserEnd = Core.atlas.find(sprite + "-end");
}
@Override
public void draw(Bullet b){
super.draw(b);
Draw.color(color);
Drawf.laser(laser, laserEnd, b.x, b.y, b.aimX, b.aimY, b.fslope() * (1f - oscMag + Mathf.absin(Time.time, oscScl, oscMag)));
Draw.reset();
}
@Override
public void update(Bullet b){
super.update(b);
if(b.timer.get(0, damageInterval)){
Damage.collidePoint(b, b.team, hitEffect, b.aimX, b.aimY);
}
if(b.timer.get(1, beamEffectInterval)){
beamEffect.at(b.aimX, b.aimY, beamEffectSize * b.fslope(), hitColor);
}
if(shake > 0){
Effect.shake(shake, shake, b);
}
}
}

View File

@ -3,6 +3,7 @@ package mindustry.world.blocks.defense.turrets;
import arc.math.*; import arc.math.*;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
import arc.util.io.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.entities.bullet.*; import mindustry.entities.bullet.*;
import mindustry.gen.*; import mindustry.gen.*;
@ -12,6 +13,8 @@ import mindustry.world.meta.*;
/** A turret that fires a continuous beam bullet with no reload or coolant necessary. The bullet only disappears when the turret stops shooting. */ /** A turret that fires a continuous beam bullet with no reload or coolant necessary. The bullet only disappears when the turret stops shooting. */
public class ContinuousTurret extends Turret{ public class ContinuousTurret extends Turret{
public BulletType shootType = Bullets.placeholder; public BulletType shootType = Bullets.placeholder;
/** Speed at which the turret can change its bullet "aim" distance. This is only used for point laser bullets. */
public float aimChangeSpeed = Float.POSITIVE_INFINITY;
public ContinuousTurret(String name){ public ContinuousTurret(String name){
super(name); super(name);
@ -33,6 +36,7 @@ public class ContinuousTurret extends Turret{
//TODO LaserTurret shared code //TODO LaserTurret shared code
public class ContinuousTurretBuild extends TurretBuild{ public class ContinuousTurretBuild extends TurretBuild{
public Seq<BulletEntry> bullets = new Seq<>(); public Seq<BulletEntry> bullets = new Seq<>();
public float lastLength = size * 4f;
@Override @Override
protected void updateCooling(){ protected void updateCooling(){
@ -85,6 +89,18 @@ public class ContinuousTurret extends Turret{
entry.bullet.rotation(angle); entry.bullet.rotation(angle);
entry.bullet.set(bulletX, bulletY); entry.bullet.set(bulletX, bulletY);
//target length of laser
float shootLength = Math.min(dst(targetPos), range);
//current length of laser
float curLength = dst(entry.bullet.aimX, entry.bullet.aimY);
//resulting length of the bullet (smoothed)
float resultLength = Mathf.approachDelta(curLength, shootLength, aimChangeSpeed);
//actual aim end point based on length
Tmp.v1.trns(rotation, lastLength = resultLength).add(x, y);
entry.bullet.aimX = Tmp.v1.x;
entry.bullet.aimY = Tmp.v1.y;
if(isShooting() && hasAmmo()){ if(isShooting() && hasAmmo()){
entry.bullet.time = entry.bullet.lifetime * entry.bullet.type.optimalLifeFract * shootWarmup; entry.bullet.time = entry.bullet.lifetime * entry.bullet.type.optimalLifeFract * shootWarmup;
entry.bullet.keepAlive = true; entry.bullet.keepAlive = true;
@ -122,6 +138,11 @@ public class ContinuousTurret extends Turret{
protected void handleBullet(@Nullable Bullet bullet, float offsetX, float offsetY, float angleOffset){ protected void handleBullet(@Nullable Bullet bullet, float offsetX, float offsetY, float angleOffset){
if(bullet != null){ if(bullet != null){
bullets.add(new BulletEntry(bullet, offsetX, offsetY, angleOffset, 0f)); bullets.add(new BulletEntry(bullet, offsetX, offsetY, angleOffset, 0f));
//make sure the length updates to the last set value
Tmp.v1.trns(rotation, shootY + lastLength).add(x, y);
bullet.aimX = Tmp.v1.x;
bullet.aimY = Tmp.v1.y;
} }
} }
@ -129,5 +150,26 @@ public class ContinuousTurret extends Turret{
public boolean shouldActiveSound(){ public boolean shouldActiveSound(){
return bullets.any(); return bullets.any();
} }
@Override
public byte version(){
return 3;
}
@Override
public void write(Writes write){
super.write(write);
write.f(lastLength);
}
@Override
public void read(Reads read, byte revision){
super.read(read, revision);
if(revision >= 3){
lastLength = read.f();
}
}
} }
} }