001package com.fs.starfarer.api.impl.combat.dweller;
002
003import java.util.List;
004
005import org.lwjgl.util.vector.Vector2f;
006
007import com.fs.starfarer.api.Global;
008import com.fs.starfarer.api.combat.BaseEveryFrameCombatPlugin;
009import com.fs.starfarer.api.combat.CombatEngineAPI;
010import com.fs.starfarer.api.combat.CombatEntityAPI;
011import com.fs.starfarer.api.combat.CombatFleetManagerAPI;
012import com.fs.starfarer.api.combat.DamagingProjectileAPI;
013import com.fs.starfarer.api.combat.EveryFrameWeaponEffectPlugin;
014import com.fs.starfarer.api.combat.OnFireEffectPlugin;
015import com.fs.starfarer.api.combat.ShipAPI;
016import com.fs.starfarer.api.combat.WeaponAPI;
017import com.fs.starfarer.api.impl.combat.threat.RoilingSwarmEffect.SwarmMember;
018import com.fs.starfarer.api.input.InputEventAPI;
019import com.fs.starfarer.api.util.Misc;
020import com.fs.starfarer.api.util.WeightedRandomPicker;
021
022public class VortexLauncherEffect implements OnFireEffectPlugin, EveryFrameWeaponEffectPlugin {
023
024        //public static String VORTEX_VARIANT = "shrouded_vortex_Churning";
025        public static String VORTEX_WING = "shrouded_vortex_wing";
026        
027        public static float LAUNCH_ARC = 60f;
028
029        public static class DisturbShroudPlugin extends BaseEveryFrameCombatPlugin {
030                float elapsed = 0f;
031                float dur;
032                Vector2f dir;
033                DwellerShroud shroud;
034                int numMembers;
035                Vector2f offset;
036                CombatEntityAPI disturber;
037                
038                public DisturbShroudPlugin(float dur, Vector2f dir, CombatEntityAPI disturber, Vector2f offset, DwellerShroud shroud, int numMembers) {
039                        this.dur = dur;
040                        this.dir = dir;
041                        this.disturber = disturber;
042                        this.offset = offset;
043                        this.shroud = shroud;
044                        this.numMembers = numMembers;
045                }
046                        
047                @Override
048                public void advance(float amount, List<InputEventAPI> events) {
049                        if (Global.getCombatEngine().isPaused()) return;
050                
051                        elapsed += amount;
052                        if (elapsed > dur) {
053                                CombatEngineAPI engine = Global.getCombatEngine();
054                                engine.removePlugin(this);
055                                return;
056                        }
057                        
058                        Vector2f loc = Vector2f.add(shroud.getAttachedTo().getLocation(), offset, new Vector2f());
059                        
060                        Vector2f useDir = dir;
061                        if (disturber != null) {
062                                useDir = new Vector2f(disturber.getVelocity());
063                                useDir = Misc.normalise(useDir);
064                        }
065                        
066                        WeightedRandomPicker<SwarmMember> picker = shroud.getPicker(false, true, loc, 70f);
067                        for (int i = 0; i < numMembers; i++) {
068                                SwarmMember pick = picker.pickAndRemove();
069                                if (pick == null) break;
070                                float accel = ConvulsiveLungeSystemScript.PARTICLE_WINDUP_ACCEL * amount * 3f;
071                                accel *= 1f + (float) Math.random();
072                                pick.vel.x += useDir.x * accel;
073                                pick.vel.y += useDir.y * accel;
074                        }
075        
076                }
077        }
078        
079        public VortexLauncherEffect() {
080                
081        }
082        
083        @Override
084        public void advance(float amount, CombatEngineAPI engine, WeaponAPI weapon) {
085                ShipAPI ship = weapon.getShip();
086                if (ship == null) return;
087
088                //weapon.setForceFireOneFrame(true);
089        }
090        
091
092        
093        public void onFire(DamagingProjectileAPI projectile, WeaponAPI weapon, CombatEngineAPI engine) {
094                
095                //FighterWingSpecAPI spec = Global.getSettings().getFighterWingSpec(ATTACK_SWARM_WING);
096
097                CombatFleetManagerAPI manager = engine.getFleetManager(projectile.getOwner());
098                manager.setSuppressDeploymentMessages(true);
099                // wing has size 1, so no other members besides the "leader"
100                // point is to spawn a ship but without it showing up in the deployment dialog etc
101                ShipAPI vortex = manager.spawnShipOrWing(VORTEX_WING, 
102                                                                projectile.getLocation(), projectile.getFacing(), 0f, null);
103                manager.setSuppressDeploymentMessages(false);
104                
105                Vector2f takeoffVel = Misc.getUnitVectorAtDegreeAngle(
106                                projectile.getFacing() + LAUNCH_ARC/2f - (float) Math.random() * LAUNCH_ARC);
107                float velMult = 1f;
108                if (Misc.getAngleDiff(projectile.getFacing(), weapon.getShip().getFacing()) > 150f) {
109                        velMult = 0.5f;
110                }
111                takeoffVel.scale(vortex.getMaxSpeed() * velMult);
112                
113                Vector2f.add(vortex.getVelocity(), takeoffVel, vortex.getVelocity());
114                
115                DwellerShroud shroud = DwellerShroud.getShroudFor(vortex);
116                if (shroud != null) {
117                        shroud.custom1 = weapon.getShip();
118                }
119                
120                DwellerShroud sourceShroud = DwellerShroud.getShroudFor(weapon.getShip());
121                if (sourceShroud != null) {
122                        
123                        Vector2f dir = Misc.getUnitVectorAtDegreeAngle(projectile.getFacing());
124                        Vector2f offset = Vector2f.sub(projectile.getLocation(), sourceShroud.getAttachedTo().getLocation(), new Vector2f());
125                        Global.getCombatEngine().addPlugin(
126                                        new DisturbShroudPlugin(1f, dir, vortex, offset, sourceShroud, 
127                                                        (int) (sourceShroud.getNumMembersToMaintain() * 0.1f)));
128                                        //new DisturbShroudPlugin(1f, dir, offset, sourceShroud, 10));
129                        
130                }
131                
132                engine.removeEntity(projectile);
133        }
134        
135        
136        
137}
138
139
140
141
142
143
144
145