001package com.fs.starfarer.api.impl.combat.dweller;
002
003import org.lwjgl.util.vector.Vector2f;
004
005import com.fs.starfarer.api.Global;
006import com.fs.starfarer.api.combat.CombatEngineAPI;
007import com.fs.starfarer.api.combat.CombatFleetManagerAPI;
008import com.fs.starfarer.api.combat.MutableShipStatsAPI;
009import com.fs.starfarer.api.combat.ShipAPI;
010import com.fs.starfarer.api.combat.ShipwideAIFlags.AIFlags;
011import com.fs.starfarer.api.impl.combat.BaseShipSystemScript;
012import com.fs.starfarer.api.impl.combat.dweller.VortexLauncherEffect.DisturbShroudPlugin;
013import com.fs.starfarer.api.util.Misc;
014
015public class TenebrousExpulsionSystemScript extends BaseShipSystemScript {
016        
017        public static String EJECTA_WING = "shrouded_ejecta_wing";
018        
019        public static float REFIRE_DELAY = 0.15f;
020        public static float LAUNCH_ARC = 90f;
021        public static float BACK_OFF_ACCEL = 500f;
022        
023        protected Vector2f fireDir;
024        protected float elapsedActive = REFIRE_DELAY;
025        
026        protected void init(ShipAPI ship) {
027        }
028        
029        
030        @Override
031        public void apply(MutableShipStatsAPI stats, String id, State state, float effectLevel) {
032                ShipAPI ship = null;
033                if (stats.getEntity() instanceof ShipAPI) {
034                        ship = (ShipAPI) stats.getEntity();
035                } else {
036                        return;
037                }
038
039                if (state == State.IN) {
040                        if (fireDir == null) {
041                                float dir = ship.getFacing();
042                                if (ship.getMouseTarget() != null) {
043                                        dir = Misc.getAngleInDegrees(ship.getLocation(), ship.getMouseTarget());
044                                }
045                                if (ship.getShipAI() != null && ship.getAIFlags().hasFlag(AIFlags.SYSTEM_TARGET_COORDS)){
046                                        dir = Misc.getAngleInDegrees(ship.getLocation(), 
047                                                        (Vector2f) ship.getAIFlags().getCustom(AIFlags.SYSTEM_TARGET_COORDS));
048                                }
049                                fireDir = Misc.getUnitVectorAtDegreeAngle(dir);
050                        }
051                }
052
053                
054                if (state == State.ACTIVE && fireDir != null) {
055                        float amount = Global.getCombatEngine().getElapsedInLastFrame();
056                        elapsedActive += amount;
057                        while (elapsedActive >= REFIRE_DELAY) {
058                                elapsedActive -= REFIRE_DELAY;
059                                fireShroudedEjecta(ship, fireDir);
060                        }
061                }
062                
063                if (state == State.OUT && fireDir != null) {
064                        float amount = Global.getCombatEngine().getElapsedInLastFrame();
065                        ship.getVelocity().x -= fireDir.x * BACK_OFF_ACCEL * amount;                    
066                        ship.getVelocity().y -= fireDir.y * BACK_OFF_ACCEL * amount;                    
067                }
068                
069                if (state == State.IDLE || state == State.COOLDOWN) {
070                        fireDir = null;
071                        elapsedActive = REFIRE_DELAY;
072                }
073                
074        }
075        
076        public static void fireShroudedEjecta(ShipAPI ship, Vector2f fireDir) {
077                float dir = Misc.getAngleInDegrees(fireDir);
078                CombatEngineAPI engine = Global.getCombatEngine();
079                CombatFleetManagerAPI manager = engine.getFleetManager(ship.getOriginalOwner());
080                manager.setSuppressDeploymentMessages(true);
081                
082                // wing has size 1, so no other members besides the "leader"
083                // point is to spawn a ship but without it showing up in the deployment dialog etc
084                ShipAPI ejecta = manager.spawnShipOrWing(EJECTA_WING, 
085                                                                ship.getLocation(), dir, 0f, null);
086                manager.setSuppressDeploymentMessages(false);
087                
088                Vector2f takeoffVel = Misc.getUnitVectorAtDegreeAngle(
089                                                                dir + LAUNCH_ARC/2f - (float) Math.random() * LAUNCH_ARC);
090                float velMult = 1f;
091                velMult = 0.5f + (float) Math.random() * 1f;
092                takeoffVel.scale(ejecta.getMaxSpeed() * velMult);
093                
094                Vector2f.add(ejecta.getVelocity(), takeoffVel, ejecta.getVelocity());
095                
096                DwellerShroud shroud = DwellerShroud.getShroudFor(ejecta);
097                if (shroud != null) {
098                        shroud.custom1 = ship;
099                }
100                
101                DwellerShroud sourceShroud = DwellerShroud.getShroudFor(ship);
102                if (sourceShroud != null) {
103                        Vector2f offset = Vector2f.sub(ejecta.getLocation(), sourceShroud.getAttachedTo().getLocation(), new Vector2f());
104                        Global.getCombatEngine().addPlugin(
105                                        new DisturbShroudPlugin(1f, fireDir, ejecta, offset, sourceShroud, 
106                                                        (int) (sourceShroud.getNumMembersToMaintain() * 0.1f)));
107                        
108                }
109                
110                Global.getSoundPlayer().playSound("system_tenebrous_expulsion_fire", 1f, 1f, ejecta.getLocation(), ejecta.getVelocity());
111        }
112        
113        
114        public StatusData getStatusData(int index, State state, float effectLevel) {
115                return null;
116        }
117        
118}
119
120
121
122
123
124
125
126