001package com.fs.starfarer.api.impl.combat.dweller;
002
003import org.lwjgl.util.vector.Vector2f;
004
005import com.fs.starfarer.api.combat.CombatEngineAPI;
006import com.fs.starfarer.api.combat.ShipAPI;
007import com.fs.starfarer.api.combat.ShipCommand;
008import com.fs.starfarer.api.combat.ShipSystemAIScript;
009import com.fs.starfarer.api.combat.ShipSystemAPI;
010import com.fs.starfarer.api.combat.ShipwideAIFlags;
011import com.fs.starfarer.api.combat.ShipwideAIFlags.AIFlags;
012import com.fs.starfarer.api.util.IntervalUtil;
013import com.fs.starfarer.api.util.Misc;
014
015
016public class TenebrousExpulsionSystemAI implements ShipSystemAIScript {
017
018        public static float HULL_LOSS_FOR_ACTIVATION = 0.25f;
019        
020        protected ShipAPI ship;
021        protected CombatEngineAPI engine;
022        protected ShipwideAIFlags flags;
023        protected ShipSystemAPI system;
024        protected TenebrousExpulsionSystemScript script;
025        
026        protected IntervalUtil tracker = new IntervalUtil(0.75f, 1.25f);
027        
028        protected float hullLevelAtPrevSystemUse = 1f;
029        protected float prevHardFluxLevel = 0f;
030        
031        public void init(ShipAPI ship, ShipSystemAPI system, ShipwideAIFlags flags, CombatEngineAPI engine) {
032                this.ship = ship;
033                this.flags = flags;
034                this.engine = engine;
035                this.system = system;
036                
037                script = (TenebrousExpulsionSystemScript)system.getScript();
038        }
039        
040        public void advance(float amount, Vector2f missileDangerDir, Vector2f collisionDangerDir, ShipAPI target) {
041                if (ship == null) return;
042                
043                tracker.advance(amount);
044                
045                boolean forceUse = false;
046                if (ship.getFluxLevel() > 0.95f && ship.getHullLevel() > 0.25f && 
047                                ship.getShield() != null && ship.getShield().isOn()) {
048                        forceUse = true;
049                }
050                
051                if (tracker.intervalElapsed() || forceUse) {
052                        if (system.getCooldownRemaining() > 0) return;
053                        if (system.isOutOfAmmo()) return;
054                        if (system.isActive()) return;
055                        if (ship.getFluxTracker().isOverloadedOrVenting()) return;
056                        
057                        float hullLevel = ship.getHullLevel();
058                        float hardFluxLevel = ship.getHardFluxLevel();
059                        float fluxLevel = ship.getFluxLevel();
060                        
061                        boolean useSystem = hullLevel <= hullLevelAtPrevSystemUse - HULL_LOSS_FOR_ACTIVATION;
062                        
063                        if (((hardFluxLevel >= prevHardFluxLevel && hardFluxLevel >= 0.33f) || fluxLevel > 0.65f) &&
064                                        ship.getAIFlags().hasFlag(AIFlags.BACKING_OFF)) {// && (float) Math.random() > 0.75f) {
065                                if (target != null) {
066                                        float dist = Misc.getDistance(ship.getLocation(), target.getLocation());
067                                        dist -= ship.getCollisionRadius() + target.getCollisionRadius();
068                                        if (dist < 1000f || hardFluxLevel > prevHardFluxLevel + 0.02f) {
069                                                useSystem = true;
070                                        }
071                                }
072                        }
073                        
074                        prevHardFluxLevel = hardFluxLevel;
075                        
076                        useSystem |= forceUse;
077                        
078                        if (useSystem) {
079                                float angle = ship.getFacing();
080                                if (target != null) {
081                                        angle = Misc.getAngleInDegrees(ship.getLocation(), target.getLocation());
082                                }
083                                if (missileDangerDir != null) {
084                                        float angle2 = Misc.getAngleInDegrees(missileDangerDir);
085                                        if (target != null) {
086                                                angle = angle + Misc.getClosestTurnDirection(angle, angle2) * 0.5f * Misc.getAngleDiff(angle, angle2);
087                                        } else {
088                                                angle = angle2;
089                                        }
090                                }
091                                
092                                Vector2f point = Misc.getUnitVectorAtDegreeAngle(angle);
093                                point.scale(2000f);
094                                Vector2f.add(point, ship.getLocation(), point);
095                                
096                                giveCommand(point);
097                                hullLevelAtPrevSystemUse = hullLevel;
098                                return;
099                        }
100                }
101        }
102        
103        public void giveCommand(Vector2f target) {
104                if (ship.getAIFlags() != null) {
105                        ship.getAIFlags().setFlag(AIFlags.SYSTEM_TARGET_COORDS, 1f, target);
106                }
107                ship.giveCommand(ShipCommand.USE_SYSTEM, null, 0);
108        }
109
110}
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132