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