|
| 1 | +package progressed.entities.bullet.energy; |
| 2 | + |
| 3 | +import arc.graphics.*; |
| 4 | +import arc.graphics.g2d.*; |
| 5 | +import arc.math.*; |
| 6 | +import arc.util.*; |
| 7 | +import mindustry.*; |
| 8 | +import mindustry.content.*; |
| 9 | +import mindustry.entities.*; |
| 10 | +import mindustry.entities.bullet.*; |
| 11 | +import mindustry.gen.*; |
| 12 | +import mindustry.graphics.*; |
| 13 | +import progressed.content.effects.*; |
| 14 | +import progressed.entities.*; |
| 15 | +import progressed.util.*; |
| 16 | + |
| 17 | +import static mindustry.Vars.*; |
| 18 | + |
| 19 | +public class EMPCloudBulletType extends BulletType{ |
| 20 | + protected static Rand cloudRand = new Rand(); |
| 21 | + |
| 22 | + public float radius = 20f * tilesize; |
| 23 | + public float growTime = 6f * 60f; |
| 24 | + public float empInterval = 20f; |
| 25 | + public float timeDuration = 60f * 10f; |
| 26 | + public float powerDamageScl = 2f, powerSclDecrease = 0.2f; |
| 27 | + public boolean hitUnits = true; |
| 28 | + public float unitDamageScl = 0.5f; |
| 29 | + public Color cloudColor = Pal.lancerLaser.cpy().a(0.125f); |
| 30 | + public int cloudGroups = 15, cloudsPerGroup = 6; |
| 31 | + public float cloudLifeMin = 0.9f; |
| 32 | + public float cloudRad = 9f * tilesize, cloudRadRand = -1f; |
| 33 | + public Effect hitPowerEffect = MissileFx.hitEmpSpark; |
| 34 | + public float lightningEffectChance = 0.5f; |
| 35 | + public LightningEffect lightningEffect = LightningFx.empLightning; |
| 36 | + |
| 37 | + public EMPCloudBulletType(float damage){ |
| 38 | + super(0f, damage); |
| 39 | + collides = hittable = absorbable = false; |
| 40 | + hitEffect = despawnEffect = Fx.none; |
| 41 | + hitColor = Pal.lancerLaser; |
| 42 | + layer = Layer.effect + 0.021f; |
| 43 | + } |
| 44 | + |
| 45 | + @Override |
| 46 | + public void init(){ |
| 47 | + super.init(); |
| 48 | + drawSize = Math.max(drawSize, (radius + cloudRad + cloudRadRand) * 2); |
| 49 | + if(cloudRadRand < 0f) cloudRadRand = cloudRad / 2f; |
| 50 | + } |
| 51 | + |
| 52 | + @Override |
| 53 | + public void draw(Bullet b){ |
| 54 | + Draw.color(cloudColor); |
| 55 | + float scl = scl(b); |
| 56 | + for(int i = 0; i < cloudGroups; i++){ |
| 57 | + cloudRand.setSeed(b.id + i); |
| 58 | + float lifeScl = cloudRand.random(cloudLifeMin, 1f); |
| 59 | + |
| 60 | + float fin = b.fin() / lifeScl; |
| 61 | + if(fin >= 1) continue; |
| 62 | + |
| 63 | + Angles.randLenVectors(b.id + i + cloudGroups, Interp.pow5Out.apply(Mathf.curve(b.time / lifeScl, 0f, growTime)), cloudsPerGroup, scl * radius, (x, y, in, out) -> { |
| 64 | + float fout = Interp.pow5Out.apply(1f - fin); |
| 65 | + float rad = scl * fout * (cloudRad + cloudRand.range(cloudRadRand)); |
| 66 | + Fill.circle(b.x + x, b.y + y, rad); |
| 67 | + }); |
| 68 | + } |
| 69 | + } |
| 70 | + |
| 71 | + @Override |
| 72 | + public void drawLight(Bullet b){ |
| 73 | + if(lightOpacity <= 0f || lightRadius <= 0f) return; |
| 74 | + float scl = Interp.pow3Out.apply(Mathf.curve(b.time, 0f, growTime)); |
| 75 | + Drawf.light(b, lightRadius * scl, lightColor, lightOpacity); |
| 76 | + } |
| 77 | + |
| 78 | + @Override |
| 79 | + public void update(Bullet b){ |
| 80 | + super.update(b); |
| 81 | + updateLightningEffects(b); |
| 82 | + updateEmp(b); |
| 83 | + } |
| 84 | + |
| 85 | + public void updateLightningEffects(Bullet b){ |
| 86 | + if(lightningEffectChance > 0.01f && |
| 87 | + b.time < b.lifetime - lightningEffect.lifetime && |
| 88 | + Mathf.chanceDelta(lightningEffectChance * b.fout(Interp.pow5Out)) |
| 89 | + ){ |
| 90 | + float rad = rad(b); |
| 91 | + PMMathf.randomCirclePoint(Tmp.v1, rad); |
| 92 | + Tmp.v1.add(b); |
| 93 | + float x1 = Tmp.v1.x, y1 = Tmp.v1.y; |
| 94 | + PMMathf.randomCirclePoint(Tmp.v1, rad); |
| 95 | + Tmp.v1.add(b); |
| 96 | + lightningEffect.at(x1, y1, Tmp.v1.x, Tmp.v1.y, hitColor); |
| 97 | + } |
| 98 | + } |
| 99 | + |
| 100 | + public void updateEmp(Bullet b){ |
| 101 | + if(!b.timer(3, empInterval)) return; |
| 102 | + |
| 103 | + float rad = rad(b); |
| 104 | + Vars.indexer.allBuildings(b.x, b.y, rad, other -> { |
| 105 | + if(other.team != b.team && other.power != null){ |
| 106 | + if(other.power.graph.getLastPowerProduced() > 0f){ |
| 107 | + other.applySlowdown(powerSclDecrease, timeDuration); |
| 108 | + other.damage(b.damage * powerDamageScl); |
| 109 | + hitPowerEffect.at(other.x, other.y, b.angleTo(other), hitColor); |
| 110 | + } |
| 111 | + } |
| 112 | + }); |
| 113 | + |
| 114 | + if(hitUnits){ |
| 115 | + Units.nearbyEnemies(b.team, b.x, b.y, radius, other -> { |
| 116 | + if(other.team != b.team && other.hittable()){ |
| 117 | + hitPowerEffect.at(other.x, other.y, b.angleTo(other), hitColor); |
| 118 | + other.damage(damage * unitDamageScl); |
| 119 | + other.apply(status, statusDuration); |
| 120 | + } |
| 121 | + }); |
| 122 | + } |
| 123 | + } |
| 124 | + |
| 125 | + public float scl(Bullet b){ |
| 126 | + return Interp.pow5Out.apply(Mathf.curve(b.time, 0f, growTime)); |
| 127 | + } |
| 128 | + |
| 129 | + public float rad(Bullet b){ |
| 130 | + return scl(b) * radius; |
| 131 | + } |
| 132 | +} |
0 commit comments