1package com.fs.starfarer.api.impl.combat;
3import java.util.ArrayList;
4import java.util.Collections;
5import java.util.Comparator;
10import com.fs.starfarer.api.Global;
11import com.fs.starfarer.api.combat.MutableShipStatsAPI;
12import com.fs.starfarer.api.combat.ShipAPI;
13import com.fs.starfarer.api.combat.WeaponAPI;
14import com.fs.starfarer.api.combat.WeaponAPI.WeaponType;
15import com.fs.starfarer.api.impl.campaign.ids.Tags;
16import com.fs.starfarer.api.util.Misc;
31 public static class LidarDishData {
33 public float turnRate;
55 if (w.isDecorative() && w.getSpec().hasTag(
Tags.
LIDAR)) {
59 List<WeaponAPI> lidar =
new ArrayList<WeaponAPI>();
61 if (w.isDecorative() && w.getSpec().hasTag(
Tags.
LIDAR)) {
65 Collections.sort(lidar,
new Comparator<WeaponAPI>() {
71 if (w.isDecorative() && w.getSpec().hasTag(
Tags.
LIDAR)) {
72 w.setSuspendAutomaticTurning(
true);
73 LidarDishData data =
new LidarDishData();
74 data.turnDir = Math.signum(turnDir);
79 data.phase = index / count;
91 float turnRateMult = 1f;
97 for (LidarDishData data :
dishData) {
98 float arc = data.w.getArc();
99 float useTurnDir = data.turnDir;
103 float delta = useTurnDir * amount * data.turnRate * turnRateMult * arc;
104 if (active && effectLevel > 0f && Math.abs(data.angle) < Math.abs(delta * 1.5f)) {
108 data.phase += 1f * amount;
110 if (data.angle > arc/2f && data.turnDir > 0f) {
114 if (data.angle < -arc/2f && data.turnDir < 0f) {
115 data.angle = -arc/2f;
119 data.angle = data.angle % 360f;
124 float facing = data.angle + data.w.getArcFacing() + data.w.getShip().getFacing();
125 data.w.setFacing(facing);
126 data.w.updateBeamFromPoints();
136 if (ship ==
null || ship.
isHulk()) {
140 if (!w.isDecorative() && w.getSlot().isHardpoint() && !w.isBeam() &&
141 (w.getType() == WeaponType.BALLISTIC || w.getType() == WeaponType.ENERGY)) {
142 w.setGlowAmount(0,
null);
154 boolean active = state == State.IN || state == State.ACTIVE || state == State.OUT;
159 modify(
id, stats, effectLevel);
165 if (w.getSlot().isSystemSlot())
continue;
166 if (!w.isDecorative() && w.getSlot().isHardpoint() && !w.isBeam() &&
167 (w.getType() == WeaponType.BALLISTIC || w.getType() == WeaponType.ENERGY)) {
168 w.setGlowAmount(0,
null);
179 if (w.getSlot().isSystemSlot())
continue;
180 if (w.getType() == WeaponType.MISSILE)
continue;
181 if (state == State.IN) {
182 if (!(w.isDecorative() && w.getSpec().hasTag(
Tags.
LIDAR))) {
183 w.setForceNoFireOneFrame(
true);
186 if (!(!w.isDecorative() && w.getSlot().isHardpoint() && !w.isBeam() &&
187 (w.getType() == WeaponType.BALLISTIC || w.getType() == WeaponType.ENERGY))) {
188 w.setForceNoFireOneFrame(
true);
195 float lidarRange = 500;
197 if (!w.isDecorative() && w.getSlot().isHardpoint() && !w.isBeam() &&
198 (w.getType() == WeaponType.BALLISTIC || w.getType() == WeaponType.ENERGY)) {
199 lidarRange = Math.max(lidarRange, w.getRange());
200 w.setGlowAmount(effectLevel, glowColor);
217 float fireThreshold = 0.25f / 3.25f;
218 fireThreshold += 0.02f;
220 for (LidarDishData data :
dishData) {
221 boolean skip = data.phase % 1f > 1f / data.count;
225 if (data.w.isDecorative() && data.w.getSpec().hasTag(
Tags.
LIDAR)) {
226 if (state == State.IN && Math.abs(data.angle) < 5f && effectLevel >= fireThreshold) {
227 data.w.setForceFireOneFrame(
true);
232 if (((state == State.IN && effectLevel > 0.67f) || state == State.ACTIVE) && !
playedWindup) {
240 float mult = 1f +
ROF_BONUS * effectLevel;
277 public StatusData
getStatusData(
int index, State state,
float effectLevel) {
278 if (state == State.IDLE || state == State.COOLDOWN) {
283 if (effectLevel <= 0f)
return null;
287 float bonusPercent = (int) ((mult - 1f) * 100f);
289 return new StatusData(
"weapon range +" + (
int)
RANGE_BONUS +
"%",
false);
292 return new StatusData(
"rate of fire +" + (
int) bonusPercent +
"%",
false);
298 return new StatusData(
"weapon recoil -" + (
int)
RECOIL_BONUS +
"%",
false);
307 if (state == State.IDLE || state == State.COOLDOWN) {
308 return "lidar array - passive";
static SoundPlayerAPI getSoundPlayer()
static CombatEngineAPI getCombatEngine()
void modifyPercent(String source, float value)
void unmodifyMult(String source)
void unmodifyPercent(String source)
void modifyMult(String source, float value)
void modifyPercent(String source, float value)
void modifyFlat(String source, float value)
void apply(MutableShipStatsAPI stats, String id, State state, float effectLevel)
static float PROJECTILE_SPEED_BONUS
void unmodify(String id, MutableShipStatsAPI stats)
void rotateLidarDishes(boolean active, float effectLevel)
void unapply(MutableShipStatsAPI stats, String id)
void modify(String id, MutableShipStatsAPI stats, float effectLevel)
static float RECOIL_BONUS
List< LidarDishData > dishData
String getDisplayNameOverride(State state, float effectLevel)
StatusData getStatusData(int index, State state, float effectLevel)
static String LIDAR_WINDUP
static float PASSIVE_RANGE_BONUS
static float getClosestTurnDirection(float facing, float desired)
SoundAPI playSound(String id, float pitch, float volume, Vector2f loc, Vector2f vel)
float getElapsedInLastFrame()
MutableStat getBallisticProjectileSpeedMult()
MutableStat getEnergyRoFMult()
StatBonus getBallisticWeaponRangeBonus()
MutableStat getEnergyProjectileSpeedMult()
MutableStat getBallisticRoFMult()
MutableStat getMaxRecoilMult()
StatBonus getBeamWeaponRangeBonus()
MutableStat getRecoilDecayMult()
StatBonus getEnergyWeaponRangeBonus()
MutableStat getRecoilPerShotMult()
CombatEntityAPI getEntity()
List< WeaponAPI > getAllWeapons()