Merge remote-tracking branch 'upstream/master' into burning-affects-tiles

This commit is contained in:
Leonwang4234
2020-10-02 17:47:11 -07:00
895 changed files with 41849 additions and 24819 deletions

View File

@@ -1,16 +1,17 @@
package mindustry.entities.bullet;
import arc.Core;
import arc.graphics.Color;
import arc.graphics.g2d.Draw;
import arc.graphics.g2d.TextureRegion;
import arc.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.util.*;
import mindustry.gen.*;
import mindustry.graphics.Pal;
import mindustry.graphics.*;
/** An extended BulletType for most ammo-based bullets shot from turrets and units. */
public class BasicBulletType extends BulletType{
public Color backColor = Pal.bulletYellowBack, frontColor = Pal.bulletYellow;
public Color mixColorFrom = new Color(1f, 1f, 1f, 0f), mixColorTo = new Color(1f, 1f, 1f, 0f);
public float width = 5f, height = 7f;
public float shrinkX = 0f, shrinkY = 0.5f;
public float spin = 0;
@@ -45,10 +46,15 @@ public class BasicBulletType extends BulletType{
float width = this.width * ((1f - shrinkX) + shrinkX * b.fout());
float offset = -90 + (spin != 0 ? Mathf.randomSeed(b.id, 360f) + b.time * spin : 0f);
Color mix = Tmp.c1.set(mixColorFrom).lerp(mixColorTo, b.fin());
Draw.mixcol(mix, mix.a);
Draw.color(backColor);
Draw.rect(backRegion, b.x, b.y, width, height, b.rotation() + offset);
Draw.color(frontColor);
Draw.rect(frontRegion, b.x, b.y, width, height, b.rotation() + offset);
Draw.color();
Draw.reset();
}
}

View File

@@ -24,7 +24,7 @@ public abstract class BulletType extends Content{
public float hitSize = 4;
public float drawSize = 40f;
public float drag = 0f;
public boolean pierce;
public boolean pierce, pierceBuilding;
public Effect hitEffect, despawnEffect;
/** Effect created when shooting. */
@@ -54,7 +54,7 @@ public abstract class BulletType extends Content{
/** Status effect applied on hit. */
public StatusEffect status = StatusEffects.none;
/** Intensity of applied status effect in terms of duration. */
public float statusDuration = 60 * 10f;
public float statusDuration = 60 * 8f;
/** Whether this bullet type collides with tiles. */
public boolean collidesTiles = true;
/** Whether this bullet type collides with tiles that are of the same team. */
@@ -69,13 +69,23 @@ public abstract class BulletType extends Content{
public boolean scaleVelocity;
/** Whether this bullet can be hit by point defense. */
public boolean hittable = true;
/** Whether this bullet can be reflected. */
public boolean reflectable = true;
/** Whether this projectile can be absorbed by shields. */
public boolean absorbable = true;
/** Whether to move the bullet back depending on delta to fix some delta-time realted issues.
* Do not change unless you know what you're doing. */
public boolean backMove = true;
/** Bullet range override. */
public float range = -1f;
//additional effects
public float fragCone = 360f;
public float fragAngle = 0f;
public int fragBullets = 9;
public float fragVelocityMin = 0.2f, fragVelocityMax = 1f;
public BulletType fragBullet = null;
public float fragVelocityMin = 0.2f, fragVelocityMax = 1f, fragLifeMin = 1f, fragLifeMax = 1f;
public @Nullable BulletType fragBullet = null;
public Color hitColor = Color.white;
public Color trailColor = Pal.missileYellowBack;
@@ -92,14 +102,17 @@ public abstract class BulletType extends Content{
public float homingPower = 0f;
public float homingRange = 50f;
public Color lightningColor = Pal.surge;
public int lightning;
public int lightningLength = 5;
public int lightningLength = 5, lightningLengthRand = 0;
/** Use a negative value to use default bullet damage. */
public float lightningDamage = -1;
public float lightningCone = 360f;
public float lightningAngle = 0f;
public float weaveScale = 1f;
public float weaveMag = -1f;
public float hitShake = 0f;
public float hitShake = 0f, despawnShake = 0f;
public int puddles;
public float puddleRange;
@@ -123,20 +136,24 @@ public abstract class BulletType extends Content{
/** Returns maximum distance the bullet this bullet type has can travel. */
public float range(){
return speed * lifetime * (1f - drag);
return Math.max(speed * lifetime * (1f - drag), range);
}
public boolean collides(Bullet bullet, Building tile){
return true;
}
public void hitTile(Bullet b, Building tile){
public void hitTile(Bullet b, Building tile, float initialHealth){
if(status == StatusEffects.burning) {
Damage.createIncend(b.x, b.y, damage/10f, (int) damage/10);
}
hit(b);
}
public void hitEntity(Bullet b, Hitboxc other, float initialHealth){
}
public void hit(Bullet b){
hit(b, b.x, b.y);
}
@@ -145,13 +162,13 @@ public abstract class BulletType extends Content{
hitEffect.at(x, y, b.rotation(), hitColor);
hitSound.at(b);
Effects.shake(hitShake, hitShake, b);
Effect.shake(hitShake, hitShake, b);
if(fragBullet != null){
for(int i = 0; i < fragBullets; i++){
float len = Mathf.random(1f, 7f);
float a = b.rotation() + Mathf.range(fragCone/2);
fragBullet.create(b, x + Angles.trnsx(a, len), y + Angles.trnsy(a, len), a, Mathf.random(fragVelocityMin, fragVelocityMax));
float a = b.rotation() + Mathf.range(fragCone/2) + fragAngle;
fragBullet.create(b, x + Angles.trnsx(a, len), y + Angles.trnsy(a, len), a, Mathf.random(fragVelocityMin, fragVelocityMax), Mathf.random(fragLifeMin, fragLifeMax));
}
}
@@ -175,7 +192,7 @@ public abstract class BulletType extends Content{
}
for(int i = 0; i < lightning; i++){
Lightning.create(b, Pal.surge, lightningDamage < 0 ? damage : lightningDamage, b.x, b.y, Mathf.random(360f), lightningLength);
Lightning.create(b, lightningColor, lightningDamage < 0 ? damage : lightningDamage, b.x, b.y, b.rotation() + Mathf.range(lightningCone/2) + lightningAngle, lightningLength + Mathf.random(lightningLengthRand));
}
}
@@ -183,6 +200,8 @@ public abstract class BulletType extends Content{
despawnEffect.at(b.x, b.y, b.rotation(), hitColor);
hitSound.at(b);
Effect.shake(despawnShake, despawnShake, b);
if(fragBullet != null || splashDamageRadius > 0 || lightning > 0){
hit(b);
}
@@ -201,7 +220,7 @@ public abstract class BulletType extends Content{
}
if(instantDisappear){
b.time(lifetime);
b.time = lifetime;
}
}
@@ -249,6 +268,10 @@ public abstract class BulletType extends Content{
return create(parent.owner(), parent.team, x, y, angle);
}
public Bullet create(Bullet parent, float x, float y, float angle, float velocityScl, float lifeScale){
return create(parent.owner(), parent.team, x, y, angle, velocityScl, lifeScale);
}
public Bullet create(Bullet parent, float x, float y, float angle, float velocityScl){
return create(parent.owner(), parent.team, x, y, angle, velocityScl);
}
@@ -259,7 +282,11 @@ public abstract class BulletType extends Content{
bullet.owner = owner;
bullet.team = team;
bullet.vel.trns(angle, speed * velocityScl);
bullet.set(x - bullet.vel.x * Time.delta, y - bullet.vel.y * Time.delta);
if(backMove){
bullet.set(x - bullet.vel.x * Time.delta, y - bullet.vel.y * Time.delta);
}else{
bullet.set(x, y);
}
bullet.lifetime = lifetime * lifetimeScl;
bullet.data = data;
bullet.drag = drag;
@@ -267,13 +294,12 @@ public abstract class BulletType extends Content{
bullet.damage = damage < 0 ? this.damage : damage;
bullet.add();
if(keepVelocity && owner instanceof Hitboxc) bullet.vel.add(((Hitboxc)owner).deltaX(), ((Hitboxc)owner).deltaY());
if(keepVelocity && owner instanceof Velc) bullet.vel.add(((Velc)owner).vel().x, ((Velc)owner).vel().y);
return bullet;
}
public void createNet(Team team, float x, float y, float angle, float damage, float velocityScl, float lifetimeScl){
Call.createBullet(this, team, x, y, damage, angle, velocityScl, lifetimeScl);
Call.createBullet(this, team, x, y, angle, damage, velocityScl, lifetimeScl);
}
@Remote(called = Loc.server, unreliable = true)

View File

@@ -12,10 +12,13 @@ import mindustry.graphics.*;
public class ContinuousLaserBulletType extends BulletType{
public float length = 220f;
public float shake = 1f;
public float fadeTime = 16f;
public Color[] colors = {Color.valueOf("ec745855"), Color.valueOf("ec7458aa"), Color.valueOf("ff9c5a"), Color.white};
public float[] tscales = {1f, 0.7f, 0.5f, 0.2f};
public float[] strokes = {2f, 1.5f, 1f, 0.3f};
public float[] lenscales = {1f, 1.12f, 1.15f, 1.17f};
public float width = 9f, oscScl = 0.8f, oscMag = 1.5f;
public boolean largeHit = true;
public ContinuousLaserBulletType(float damage){
super(0.001f, damage);
@@ -25,6 +28,7 @@ public class ContinuousLaserBulletType extends BulletType{
hitSize = 4;
drawSize = 420f;
lifetime = 16f;
keepVelocity = false;
pierce = true;
hittable = false;
hitColor = colors[2];
@@ -32,6 +36,8 @@ public class ContinuousLaserBulletType extends BulletType{
incendAmount = 1;
incendSpread = 5;
incendChance = 0.4f;
lightColor = Color.orange;
absorbable = false;
}
protected ContinuousLaserBulletType(){
@@ -43,37 +49,45 @@ public class ContinuousLaserBulletType extends BulletType{
return length;
}
@Override
public void init(){
super.init();
drawSize = Math.max(drawSize, length*2f);
}
@Override
public void update(Bullet b){
//TODO possible laser absorption from blocks
//damage every 5 ticks
if(b.timer(1, 5f)){
Damage.collideLine(b, b.team, hitEffect, b.x, b.y, b.rotation(), length, true);
Damage.collideLine(b, b.team, hitEffect, b.x, b.y, b.rotation(), length, largeHit);
}
if(shake > 0){
Effects.shake(shake, shake, b);
Effect.shake(shake, shake, b);
}
}
@Override
public void draw(Bullet b){
float baseLen = length * b.fout();
float realLength = Damage.findLaserLength(b, length);
float fout = Mathf.clamp(b.time > b.lifetime - fadeTime ? 1f - (b.time - (lifetime - fadeTime)) / fadeTime : 1f);
float baseLen = realLength * fout;
Lines.lineAngle(b.x, b.y, b.rotation(), baseLen);
for(int s = 0; s < colors.length; s++){
Draw.color(Tmp.c1.set(colors[s]).mul(1f + Mathf.absin(Time.time(), 1f, 0.1f)));
for(int i = 0; i < tscales.length; i++){
Tmp.v1.trns(b.rotation() + 180f, (lenscales[i] - 1f) * 35f);
Lines.stroke((9f + Mathf.absin(Time.time(), 0.8f, 1.5f)) * b.fout() * strokes[s] * tscales[i]);
Lines.lineAngle(b.x + Tmp.v1.x, b.y + Tmp.v1.y, b.rotation(), baseLen * lenscales[i], CapStyle.none);
Lines.stroke((width + Mathf.absin(Time.time(), oscScl, oscMag)) * fout * strokes[s] * tscales[i]);
Lines.lineAngle(b.x + Tmp.v1.x, b.y + Tmp.v1.y, b.rotation(), baseLen * lenscales[i], false);
}
}
Tmp.v1.trns(b.rotation(), baseLen * 1.1f);
Drawf.light(b.team, b.x, b.y, b.x + Tmp.v1.x, b.y + Tmp.v1.y, 40, Color.orange, 0.7f);
Drawf.light(b.team, b.x, b.y, b.x + Tmp.v1.x, b.y + Tmp.v1.y, 40, lightColor, 0.7f);
Draw.reset();
}

View File

@@ -21,6 +21,7 @@ public class HealBulletType extends BulletType{
despawnEffect = Fx.hitLaser;
collidesTeam = true;
hittable = false;
reflectable = false;
}
public HealBulletType(){
@@ -29,7 +30,7 @@ public class HealBulletType extends BulletType{
@Override
public boolean collides(Bullet b, Building tile){
return tile.team() != b.team || tile.healthf() < 1f;
return tile.team != b.team || tile.healthf() < 1f;
}
@Override
@@ -43,11 +44,11 @@ public class HealBulletType extends BulletType{
}
@Override
public void hitTile(Bullet b, Building tile){
public void hitTile(Bullet b, Building tile, float initialHealth){
super.hit(b);
if(tile.team() == b.team && !(tile.block() instanceof BuildBlock)){
Fx.healBlockFull.at(tile.x, tile.y, tile.block().size, Pal.heal);
if(tile.team == b.team && !(tile.block instanceof ConstructBlock)){
Fx.healBlockFull.at(tile.x, tile.y, tile.block.size, Pal.heal);
tile.heal(healPercent / 100f * tile.maxHealth());
}
}

View File

@@ -8,20 +8,17 @@ import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.world.*;
import static mindustry.Vars.world;
public class LaserBulletType extends BulletType{
protected static Tile furthest;
protected Color[] colors = {Pal.lancerLaser.cpy().mul(1f, 1f, 1f, 0.4f), Pal.lancerLaser, Color.white};
protected Effect laserEffect = Fx.lancerLaserShootSmoke;
protected float length = 160f;
protected float width = 15f;
protected float lengthFalloff = 0.5f;
protected float sideLength = 29f, sideWidth = 0.7f;
protected float sideAngle = 90f;
public Color[] colors = {Pal.lancerLaser.cpy().mul(1f, 1f, 1f, 0.4f), Pal.lancerLaser, Color.white};
public Effect laserEffect = Fx.lancerLaserShootSmoke;
public float length = 160f;
public float width = 15f;
public float lengthFalloff = 0.5f;
public float sideLength = 29f, sideWidth = 0.7f;
public float sideAngle = 90f;
public float lightningSpacing = -1, lightningDelay = 0.1f, lightningAngleRand;
public boolean largeHit = false;
public LaserBulletType(float damage){
super(0.01f, damage);
@@ -42,6 +39,13 @@ public class LaserBulletType extends BulletType{
this(1f);
}
@Override
public void init(){
super.init();
drawSize = Math.max(drawSize, length*2f);
}
@Override
public float range(){
return length;
@@ -49,24 +53,35 @@ public class LaserBulletType extends BulletType{
@Override
public void init(Bullet b){
Tmp.v1.trns(b.rotation(), length);
float resultLength = Damage.collideLaser(b, length, largeHit), rot = b.rotation();
furthest = null;
laserEffect.at(b.x, b.y, rot, resultLength * 0.75f);
world.raycast(b.tileX(), b.tileY(), world.toTile(b.x + Tmp.v1.x), world.toTile(b.y + Tmp.v1.y),
(x, y) -> (furthest = world.tile(x, y)) != null && furthest.team() != b.team && furthest.block().absorbLasers);
if(lightningSpacing > 0){
int idx = 0;
for(float i = 0; i <= resultLength; i += lightningSpacing){
float cx = b.x + Angles.trnsx(rot, i),
cy = b.y + Angles.trnsy(rot, i);
float resultLength = furthest != null ? Math.max(6f, b.dst(furthest.worldx(), furthest.worldy())) : length;
int f = idx++;
Damage.collideLine(b, b.team, hitEffect, b.x, b.y, b.rotation(), resultLength);
if(furthest != null) b.data(resultLength);
laserEffect.at(b.x, b.y, b.rotation(), resultLength * 0.75f);
for(int s : Mathf.signs){
Time.run(f * lightningDelay, () -> {
if(b.isAdded() && b.type == this){
Lightning.create(b, lightningColor,
lightningDamage < 0 ? damage : lightningDamage,
cx, cy, rot + 90*s + Mathf.range(lightningAngleRand),
lightningLength + Mathf.random(lightningLengthRand));
}
});
}
}
}
}
@Override
public void draw(Bullet b){
float realLength = b.data() == null ? length : (Float)b.data();
float realLength = b.fdata;
float f = Mathf.curve(b.fin(), 0f, 0.2f);
float baseLen = realLength * f;
@@ -74,11 +89,10 @@ public class LaserBulletType extends BulletType{
float compound = 1f;
Lines.lineAngle(b.x, b.y, b.rotation(), baseLen);
Lines.precise(true);
for(Color color : colors){
Draw.color(color);
Lines.stroke((cwidth *= lengthFalloff) * b.fout());
Lines.lineAngle(b.x, b.y, b.rotation(), baseLen, CapStyle.none);
Lines.lineAngle(b.x, b.y, b.rotation(), baseLen, false);
Tmp.v1.trns(b.rotation(), baseLen);
Drawf.tri(b.x + Tmp.v1.x, b.y + Tmp.v1.y, Lines.getStroke() * 1.22f, cwidth * 2f + width / 2f, b.rotation());
@@ -89,7 +103,6 @@ public class LaserBulletType extends BulletType{
compound *= lengthFalloff;
}
Lines.precise(false);
Draw.reset();
Tmp.v1.trns(b.rotation(), baseLen * 1.1f);

View File

@@ -13,7 +13,7 @@ import mindustry.world.*;
import static mindustry.Vars.*;
public class LiquidBulletType extends BulletType{
public @NonNull Liquid liquid;
public Liquid liquid;
public float puddleSize = 6f;
public LiquidBulletType(@Nullable Liquid liquid){
@@ -24,8 +24,9 @@ public class LiquidBulletType extends BulletType{
this.status = liquid.effect;
}
lifetime = 74f;
statusDuration = 90f;
ammoMultiplier = 1f;
lifetime = 34f;
statusDuration = 60f * 2f;
despawnEffect = Fx.none;
hitEffect = Fx.hitLiquid;
smokeEffect = Fx.none;
@@ -61,7 +62,7 @@ public class LiquidBulletType extends BulletType{
public void draw(Bullet b){
Draw.color(liquid.color, Color.white, b.fout() / 100f);
Fill.circle(b.x, b.y, 3f);
Fill.circle(b.x, b.y, puddleSize / 2);
}
@Override
@@ -69,7 +70,7 @@ public class LiquidBulletType extends BulletType{
super.despawned(b);
//don't create liquids when the projectile despawns
hitEffect.at(b.x, b.y, liquid.color);
hitEffect.at(b.x, b.y, b.rotation(), liquid.color);
}
@Override
@@ -78,7 +79,7 @@ public class LiquidBulletType extends BulletType{
Puddles.deposit(world.tileWorld(hitx, hity), liquid, puddleSize);
if(liquid.temperature <= 0.5f && liquid.flammability < 0.3f){
float intensity = 400f;
float intensity = 400f * puddleSize/6f;
Fires.extinguish(world.tileWorld(hitx, hity), intensity);
for(Point2 p : Geometry.d4){
Fires.extinguish(world.tileWorld(hitx + p.x * tilesize, hity + p.y * tilesize), intensity);

View File

@@ -1,15 +1,14 @@
package mindustry.entities.bullet;
import arc.graphics.Color;
import arc.graphics.g2d.Draw;
import arc.math.Angles;
import arc.math.Mathf;
import mindustry.content.Fx;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import mindustry.content.*;
import mindustry.gen.*;
import mindustry.graphics.Pal;
import mindustry.world.blocks.distribution.MassDriver.DriverBulletData;
import mindustry.graphics.*;
import mindustry.world.blocks.distribution.MassDriver.*;
import static mindustry.Vars.content;
import static mindustry.Vars.*;
public class MassDriverBolt extends BulletType{

View File

@@ -15,6 +15,7 @@ public class MissileBulletType extends BasicBulletType{
height = 8f;
hitSound = Sounds.explosion;
trailChance = 0.2f;
lifetime = 49f;
}
public MissileBulletType(float speed, float damage){

View File

@@ -0,0 +1,70 @@
package mindustry.entities.bullet;
import arc.math.geom.*;
import arc.util.*;
import mindustry.*;
import mindustry.entities.*;
import mindustry.gen.*;
public class PointBulletType extends BulletType{
private static float cdist = 0f;
private static Unit result;
public float trailSpacing = 10f;
public PointBulletType(){
scaleVelocity = true;
lifetime = 100f;
collides = false;
keepVelocity = false;
backMove = false;
}
@Override
public void init(Bullet b){
super.init(b);
float px = b.x + b.lifetime * b.vel.x,
py = b.y + b.lifetime * b.vel.y,
rot = b.rotation();
Geometry.iterateLine(0f, b.x, b.y, px, py, trailSpacing, (x, y) -> {
trailEffect.at(x, y, rot);
});
b.time = b.lifetime;
b.set(px, py);
//calculate hit entity
cdist = 0f;
result = null;
float range = 1f;
Units.nearbyEnemies(b.team, px - range, py - range, range*2f, range*2f, e -> {
if(e.dead()) return;
e.hitbox(Tmp.r1);
if(!Tmp.r1.contains(px, py)) return;
float dst = e.dst(px, py) - e.hitSize;
if((result == null || dst < cdist)){
result = e;
cdist = dst;
}
});
if(result != null){
b.collision(result, px, py);
}else{
Building build = Vars.world.buildWorld(px, py);
if(build != null && build.team != b.team){
build.collision(b);
}
}
b.remove();
b.vel.setZero();
}
}

View File

@@ -0,0 +1,60 @@
package mindustry.entities.bullet;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
//TODO this class is bad for multiple reasons, remove/replace it.
//- effects unreliable
//- not really hitscan but works like it
//- buggy trails
//- looks bad
//- generally unreliable
public class RailBulletType extends BulletType{
public Effect pierceEffect = Fx.hitBulletSmall, updateEffect = Fx.none;
/** Multiplier of damage decreased per health pierced. */
public float pierceDamageFactor = 1f;
public RailBulletType(){
pierceBuilding = true;
pierce = true;
reflectable = false;
hitEffect = Fx.none;
despawnEffect = Fx.none;
}
void handle(Bullet b, Posc pos, float initialHealth){
float sub = initialHealth*pierceDamageFactor;
if(sub >= b.damage){
//cause a despawn
b.remove();
}
//subtract health from each consecutive pierce
b.damage -= Math.min(b.damage, sub);
if(b.damage > 0){
pierceEffect.at(pos.getX(), pos.getY(), b.rotation());
}
hitEffect.at(pos.getX(), pos.getY());
}
@Override
public void update(Bullet b){
if(b.timer(1, 0.9f)){
updateEffect.at(b.x, b.y, b.rotation());
}
}
@Override
public void hitEntity(Bullet b, Hitboxc entity, float initialHealth){
handle(b, entity, initialHealth);
}
@Override
public void hitTile(Bullet b, Building tile, float initialHealth){
handle(b, tile, initialHealth);
}
}

View File

@@ -39,10 +39,15 @@ public class SapBulletType extends BulletType{
Draw.reset();
Drawf.light(b.team, b.x, b.y, b.x + Tmp.v1.x, b.y + Tmp.v1.y, 15f * b.fout(), lightColor, 0.6f);
Drawf.light(b.team, b.x, b.y, Tmp.v1.x, Tmp.v1.y, 15f * b.fout(), lightColor, 0.6f);
}
}
@Override
public void drawLight(Bullet b){
}
@Override
public float range(){
return length;

View File

@@ -13,9 +13,10 @@ public class ShrapnelBulletType extends BulletType{
public float length = 100f;
public float width = 20f;
public Color fromColor = Color.white, toColor = Pal.lancerLaser;
public boolean hitLarge = false;
public int serrations = 7;
public float serrationLenScl = 10f, serrationWidth = 4f, serrationSpacing = 8f, serrationSpaceOffset = 80f;
public float serrationLenScl = 10f, serrationWidth = 4f, serrationSpacing = 8f, serrationSpaceOffset = 80f, serrationFadeOffset = 0.5f;
public ShrapnelBulletType(){
speed = 0.01f;
@@ -24,23 +25,39 @@ public class ShrapnelBulletType extends BulletType{
lifetime = 10f;
despawnEffect = Fx.none;
pierce = true;
keepVelocity = false;
hittable = false;
}
@Override
public void init(Bullet b){
Damage.collideLine(b, b.team, hitEffect, b.x, b.y, b.rotation(), length);
Damage.collideLaser(b, length, hitLarge);
}
@Override
public void init(){
super.init();
drawSize = Math.max(drawSize, length*2f);
}
@Override
public float range(){
return length;
}
@Override
public void draw(Bullet b){
float realLength = b.fdata;
Draw.color(fromColor, toColor, b.fin());
for(int i = 0; i < serrations; i++){
for(int i = 0; i < (int)(serrations * realLength / length); i++){
Tmp.v1.trns(b.rotation(), i * serrationSpacing);
float sl = Mathf.clamp(b.fout() - 0.5f) * (serrationSpaceOffset - i * serrationLenScl);
float sl = Mathf.clamp(b.fout() - serrationFadeOffset) * (serrationSpaceOffset - i * serrationLenScl);
Drawf.tri(b.x + Tmp.v1.x, b.y + Tmp.v1.y, serrationWidth, sl, b.rotation() + 90);
Drawf.tri(b.x + Tmp.v1.x, b.y + Tmp.v1.y, serrationWidth, sl, b.rotation() - 90);
}
Drawf.tri(b.x, b.y, width * b.fout(), (length + 50), b.rotation());
Drawf.tri(b.x, b.y, width * b.fout(), (realLength + 50), b.rotation());
Drawf.tri(b.x, b.y, width * b.fout(), 10f, b.rotation() + 180f);
Draw.reset();
}