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