001package com.fs.starfarer.api.impl.combat.threat;
002
003import java.awt.Color;
004
005import org.lwjgl.util.vector.Vector2f;
006
007import com.fs.starfarer.api.Global;
008import com.fs.starfarer.api.combat.CombatEngineAPI;
009import com.fs.starfarer.api.combat.CombatEntityAPI;
010import com.fs.starfarer.api.combat.DamageAPI;
011import com.fs.starfarer.api.combat.DamagingProjectileAPI;
012import com.fs.starfarer.api.combat.MissileAPI;
013import com.fs.starfarer.api.combat.OnHitEffectPlugin;
014import com.fs.starfarer.api.combat.ShipAPI;
015import com.fs.starfarer.api.combat.WeaponAPI;
016import com.fs.starfarer.api.combat.listeners.ApplyDamageResultAPI;
017import com.fs.starfarer.api.combat.listeners.DamageDealtModifier;
018import com.fs.starfarer.api.impl.combat.DisintegratorEffect;
019import com.fs.starfarer.api.impl.combat.threat.RoilingSwarmEffect.RoilingSwarmParams;
020import com.fs.starfarer.api.impl.combat.threat.RoilingSwarmEffect.SwarmMember;
021import com.fs.starfarer.api.util.Misc;
022
023public class DevouringSwarmMissileEffect extends BaseFragmentMissileEffect implements OnHitEffectPlugin {
024
025        public static String DISMANTLING_SWARM = "dismantling_swarm";
026        
027        public static int NUM_TICKS = 11; // about 10 seconds (duration of damage over time effect)
028        
029        public static class DismantlingFragmentBaseDamageNegator implements DamageDealtModifier {
030                @Override
031                public String modifyDamageDealt(Object param, CombatEntityAPI target, DamageAPI damage, Vector2f point,
032                                boolean shieldHit) {
033                        if (shieldHit) {
034                                return null;
035                        }
036                        if (param instanceof MissileAPI) {
037                                MissileAPI missile = (MissileAPI) param;
038                                RoilingSwarmEffect swarm = RoilingSwarmEffect.getSwarmFor(missile);
039                                if (swarm != null && swarm.params.tags.contains(DISMANTLING_SWARM)) {
040                                        damage.getModifier().modifyMult(DISMANTLING_SWARM, 0f);
041                                        return DISMANTLING_SWARM;
042                                }
043                        }
044                        return null;
045                }
046        }
047        
048        
049        
050        public void onFire(DamagingProjectileAPI projectile, WeaponAPI weapon, CombatEngineAPI engine) {
051                super.onFire(projectile, weapon, engine);
052                if (weapon.getShip() != null && 
053                                !weapon.getShip().hasListenerOfClass(DismantlingFragmentBaseDamageNegator.class)) {
054                        weapon.getShip().addListener(new DismantlingFragmentBaseDamageNegator());
055                }
056        }
057        
058        protected void configureMissileSwarmParams(RoilingSwarmParams params) {
059//              params.flashFringeColor = new Color(183,65,13,255);
060//              params.flashCoreColor = Color.white;
061//              params.flashRadius = 40f;
062//              params.flashCoreRadiusMult = 0.75f;
063                
064                params.tags.add(DISMANTLING_SWARM);
065                
066//              params.flashFringeColor = new Color(183,65,13,80);
067//              params.flashCoreColor = new Color(183,65,13,127);
068                params.flashFringeColor = new Color(130,165,50,50);
069                params.flashCoreColor = new Color(130,165,50,127);
070                //params.flashCoreColor = new Color(50,165,50,127);
071                
072//              params.flashFringeColor = new Color(100,165,100,127);
073//              params.flashCoreColor = Color.white;
074                
075                
076                //params.flashCoreColor = new Color(183,65,13,127);
077                params.flashCoreRadiusMult = 0f;
078                params.renderFlashOnSameLayer = true;
079                params.flashRadius = 40f;
080                params.preFlashDelay = 0.5f * (float) Math.random();
081                
082                params.flashFrequency = 40f;
083                params.flashProbability = 1f;
084        }
085        
086        protected int getNumOtherMembersToTransfer() {
087                return 5;
088                //return 0;
089        }
090        
091        @Override
092        protected int getNumOtherMembersToAdd() {
093                return 0;
094                //return 5;
095        }
096
097        protected int getEMPResistance() {
098                return 1;
099        }
100        
101        protected boolean explodeOnFizzling() {
102                return false;
103        }
104        
105        @Override
106        protected FragmentBehaviorOnImpact getOtherFragmentBehaviorOnImpact() {
107                return FragmentBehaviorOnImpact.STOP_AND_FADE;
108        }
109
110        protected void reportFragmentHit(MissileAPI missile, SwarmMember p, RoilingSwarmEffect swarm, CombatEntityAPI target) {
111                CombatEngineAPI engine = Global.getCombatEngine();
112                Color color = swarm.params.flashFringeColor;
113                color = Misc.setAlpha(color, 255);
114                float size = swarm.params.flashRadius * 2f;
115                engine.addHitParticle(p.loc, new Vector2f(), size, 0.5f, color);
116                engine.addHitParticle(p.loc, new Vector2f(), size * 0.25f, 1f, Color.white);
117        }
118
119        @Override
120        public void onHit(DamagingProjectileAPI projectile, CombatEntityAPI target, Vector2f point, boolean shieldHit,
121                        ApplyDamageResultAPI damageResult, CombatEngineAPI engine) {
122                if (shieldHit) return;
123                if (projectile.getDamageAmount() <= 0f) return;
124                //if (projectile.isFading()) return;
125                if (!(target instanceof ShipAPI)) return;
126                
127                ShipAPI source = projectile.getSource();
128                RoilingSwarmEffect sourceSwarm = RoilingSwarmEffect.getSwarmFor(source);
129                
130                Vector2f offset = Vector2f.sub(point, target.getLocation(), new Vector2f());
131                offset = Misc.rotateAroundOrigin(offset, -target.getFacing());
132                DisintegratorEffect effect = new DisintegratorEffect(projectile, (ShipAPI) target, offset) {
133                        protected float getTotalDamage() {
134                                return projectile.getDamageAmount();
135                        }
136                        protected int getNumTicks() {
137                                return NUM_TICKS;
138                        }
139                        protected boolean canDamageHull() {
140                                return true;
141                        }
142                        protected int getNumParticlesPerTick() {
143                                return 5;
144                        }
145                        protected String getSoundLoopId() {
146                                return "devouring_swarm_loop";
147                        }
148                        protected void addParticle() {
149                                ParticleData p = new ParticleData(25f, 3f + (float) Math.random() * 2f, 1f);
150                                p.color = new Color(125,100,200,25);
151//                              p.color = RiftLanceEffect.getColorForDarkening(VoltaicDischargeOnFireEffect.EMP_FRINGE_COLOR);
152//                              p.color = Misc.setAlpha(p.color, 25);
153                                particles.add(p);
154                                p.offset = Misc.getPointWithinRadius(p.offset, 10f);
155                        }
156                        protected void damageDealt(Vector2f loc, float hullDamage, float armorDamage) {
157                                if (sourceSwarm == null || source == null || !source.isAlive()) return;
158                                if (source.isFighter()) return;
159                                
160                                if ((float) Math.random() < 0.25f) return;
161                                if (hullDamage > 0 || armorDamage > 0) {
162                                        SwarmMember p = sourceSwarm.addMember();
163                                        p.loc.set(loc);
164                                        p.fader.setDurationIn(0.3f);
165                                }
166                        }
167                };
168                CombatEntityAPI e = engine.addLayeredRenderingPlugin(effect);
169                e.getLocation().set(projectile.getLocation());
170                
171                if (projectile instanceof MissileAPI) {
172                        MissileAPI missile = (MissileAPI) projectile;
173                        missile.setDidDamage(true);
174                        Global.getSoundPlayer().playSound("devouring_swarm_hit_ship", 1f, 1f, point,
175                                                                        missile.getVelocity());
176                }
177        }
178
179        protected boolean withEMPArc() {
180                return super.withEMPArc();
181        }
182        
183        protected Color getEMPFringeColor() {
184                Color c = weapon.getSpec().getGlowColor();
185                c = Misc.scaleColorOnly(c, 0.5f);
186                return c;
187                //return super.getEMPFringeColor();
188        }
189        
190        protected Color getEMPCoreColor() {
191                Color c = Color.white;
192                c = Misc.scaleColorOnly(c, 0.5f);
193                return c;
194                //return super.getEMPCoreColor();
195        }
196        
197//      protected String getExplosionSoundId() {
198//              return "devastator_explosion";
199//      }
200
201}
202
203
204
205
206
207
208
209