001package com.fs.starfarer.api.impl.combat.threat;
002
003import com.fs.starfarer.api.combat.MutableShipStatsAPI;
004import com.fs.starfarer.api.combat.ShipAIConfig;
005import com.fs.starfarer.api.combat.ShipAPI;
006import com.fs.starfarer.api.combat.ShipwideAIFlags.AIFlags;
007import com.fs.starfarer.api.combat.WeaponAPI;
008import com.fs.starfarer.api.combat.WeaponAPI.WeaponType;
009import com.fs.starfarer.api.impl.campaign.ids.Personalities;
010import com.fs.starfarer.api.util.Misc;
011
012public class IncursionModeSystemScript extends BaseEnergyLashActivatedSystem {
013        
014        public static float SPEED_BONUS = 100f;
015        public static float FLUX_DISSIPATION_MULT = 3f;
016        public static float AMMO_REGEN_MULT = 5f;
017        
018        
019        protected ShipAIConfig origConfig; 
020        
021        protected void init(ShipAPI ship) {
022                super.init(ship);
023                if (ship.getShipAI() != null && ship.getShipAI().getConfig() != null) {
024                        ShipAIConfig config = ship.getShipAI().getConfig();
025                        origConfig = config.clone();
026                }
027        }
028        
029        public void applyImpl(ShipAPI ship, MutableShipStatsAPI stats, String id, State state, float effectLevel) {
030                stats.getMaxSpeed().modifyFlat(id, SPEED_BONUS * effectLevel);
031                stats.getAcceleration().modifyFlat(id, 2f * SPEED_BONUS * effectLevel);
032                stats.getDeceleration().modifyFlat(id, 2f * SPEED_BONUS * effectLevel);
033                stats.getEnergyAmmoRegenMult().modifyMult(id, 1f + (AMMO_REGEN_MULT - 1f) * effectLevel);
034                stats.getBallisticAmmoRegenMult().modifyMult(id, 1f + (AMMO_REGEN_MULT - 1f) * effectLevel);
035                //stats.getMissileAmmoRegenMult().modifyMult(id, AMMO_REGEN_MULT * effectLevel);
036                stats.getFluxDissipation().modifyMult(id, 1f + (FLUX_DISSIPATION_MULT - 1f) * effectLevel);
037                
038                if (ship.getShipAI() != null && ship.getShipAI().getConfig() != null) {
039                        ShipAIConfig config = ship.getShipAI().getConfig();
040                        if (effectLevel > 0) {
041                                config.personalityOverride = Personalities.RECKLESS;
042                                config.alwaysStrafeOffensively = true;
043                                config.backingOffWhileNotVentingAllowed = false;
044                                config.turnToFaceWithUndamagedArmor = false;
045                                config.burnDriveIgnoreEnemies = true;
046                        } else {
047                                config.copyFrom(origConfig);
048                        }
049                }
050                
051                //if (state != State.IDLE && state != State.OUT) return;
052                if (effectLevel <= 0f) return;
053                
054                ship.getEngineController().extendFlame(ship.getSystem(), 1f * effectLevel, 0f * effectLevel, 0.5f * effectLevel);
055                
056                ship.getAIFlags().setFlag(AIFlags.DO_NOT_BACK_OFF, 1f);
057                ship.getAIFlags().setFlag(AIFlags.DO_NOT_VENT, 1f);
058                ship.getAIFlags().setFlag(AIFlags.IGNORES_ORDERS, 1f);
059                
060                makeAllGroupsAutofireOneFrame(ship);
061                
062                setStandardJitter(ship, state, effectLevel);
063        }
064        
065        
066        public StatusData getStatusData(int index, State state, float effectLevel) {
067                if (effectLevel <= 0f) return null;
068                
069                if (index == 0) {
070                        return new StatusData("improved maneuverability", false);
071                } else if (index == 1) {
072                        return new StatusData("+" + (int)SPEED_BONUS + " top speed", false);
073                } else if (index == 2) {
074                        return new StatusData("x" + (int)FLUX_DISSIPATION_MULT+ " flux dissipation", false);
075                } else if (index == 3) {
076                        return new StatusData("rapid charge regen", false);
077                }
078                return null;
079        }
080
081        @Override
082        public float getCurrentUsefulnessLevel(ShipAPI overseer, ShipAPI ship) {
083                if (ship.getSystem().isActive() || ship.getSystem().isChargedown() ||
084                                ship.getSystem().isChargeup() || ship.getSystem().isCoolingDown()) {
085                        return 0f;
086                }
087                
088                Object test = ship.getAIFlags().getCustom(AIFlags.MANEUVER_TARGET);
089                if (test instanceof ShipAPI) {
090                        ShipAPI target = (ShipAPI) test;
091                        
092                        float dist = Misc.getDistance(ship.getLocation(), target.getLocation());
093                        dist -= ship.getCollisionRadius() + target.getCollisionRadius();
094                        
095                        float range = getNonMissileWeaponRange(ship);
096                        float extra = 750f;
097                        if (dist < range + extra) {
098                                float distToOverseer = Misc.getDistance(ship.getLocation(), overseer.getLocation());
099                                distToOverseer -= ship.getCollisionRadius() + overseer.getCollisionRadius();
100                                float overseerDistFactor = 0f;
101                                if (distToOverseer < 1000f) {
102                                        float min = 500f;
103                                        overseerDistFactor = (1f - Math.max(0f, distToOverseer - min) / (1000f - min)) * 0.25f;
104                                }
105                                return Math.min(1f, 0.5f + Math.min(0.5f, ship.getFluxLevel() * 1f) + overseerDistFactor);
106                        }
107                }
108                
109                return 0f;
110        }
111        
112        
113        public static float getNonMissileWeaponRange(ShipAPI ship) {
114                float max = 0f;
115                for (WeaponAPI w : ship.getAllWeapons()) {
116                        if (w.isDecorative()) continue;
117                        if (w.getType() == WeaponType.MISSILE) continue;
118                        max = Math.max(max, w.getRange());
119                }
120                return max;
121        }
122        
123}
124
125
126
127
128
129
130
131