Starsector API
Loading...
Searching...
No Matches
PhaseAnchor.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.hullmods;
2
3import java.awt.Color;
4
5import org.lwjgl.util.vector.Vector2f;
6
7import com.fs.starfarer.api.Global;
8import com.fs.starfarer.api.combat.BaseHullMod;
9import com.fs.starfarer.api.combat.MutableShipStatsAPI;
10import com.fs.starfarer.api.combat.ShipAPI;
11import com.fs.starfarer.api.combat.ShipAPI.HullSize;
12import com.fs.starfarer.api.combat.ShipCommand;
13import com.fs.starfarer.api.combat.ShipSystemAPI.SystemState;
14import com.fs.starfarer.api.combat.listeners.AdvanceableListener;
15import com.fs.starfarer.api.combat.listeners.HullDamageAboutToBeTakenListener;
16import com.fs.starfarer.api.impl.campaign.ids.HullMods;
17import com.fs.starfarer.api.impl.campaign.ids.Strings;
18import com.fs.starfarer.api.impl.campaign.skills.NeuralLinkScript;
19import com.fs.starfarer.api.util.FaderUtil;
20import com.fs.starfarer.api.util.Misc;
21
22public class PhaseAnchor extends BaseHullMod {
23
24 public static float PHASE_DISSIPATION_MULT = 2f;
25 public static float ACTIVATION_COST_MULT = 0f;
26
27 public static float CR_LOSS_MULT_FOR_EMERGENCY_DIVE = 1f;
28
29 public static class PhaseAnchorScript implements AdvanceableListener, HullDamageAboutToBeTakenListener {
30 public ShipAPI ship;
31 public boolean emergencyDive = false;
32 public float diveProgress = 0f;
33 public FaderUtil diveFader = new FaderUtil(1f, 1f);
34 public PhaseAnchorScript(ShipAPI ship) {
35 this.ship = ship;
36 }
37
38 public boolean notifyAboutToTakeHullDamage(Object param, ShipAPI ship, Vector2f point, float damageAmount) {
39 //if (ship.getCurrentCR() <= 0) return false;
40
41 if (!emergencyDive) {
42 String key = "phaseAnchor_canDive";
43 boolean canDive = !Global.getCombatEngine().getCustomData().containsKey(key);
44 float depCost = 0f;
45 if (ship.getFleetMember() != null) {
46 depCost = ship.getFleetMember().getDeployCost();
47 }
48 float crLoss = CR_LOSS_MULT_FOR_EMERGENCY_DIVE * depCost;
49 canDive &= ship.getCurrentCR() >= crLoss;
50
51 float hull = ship.getHitpoints();
52 if (damageAmount >= hull && canDive) {
53 ship.setHitpoints(1f);
54
55 //ship.setCurrentCR(Math.max(0f, ship.getCurrentCR() - crLoss));
56 if (ship.getFleetMember() != null) { // fleet member is fake during simulation, so this is fine
57 ship.getFleetMember().getRepairTracker().applyCREvent(-crLoss, "Emergency phase dive");
58 //ship.getFleetMember().getRepairTracker().setCR(ship.getFleetMember().getRepairTracker().getBaseCR() + crLoss);
59 }
60 emergencyDive = true;
61 Global.getCombatEngine().getCustomData().put(key, true);
62
63 if (!ship.isPhased()) {
64 Global.getSoundPlayer().playSound("system_phase_cloak_activate", 1f, 1f, ship.getLocation(), ship.getVelocity());
65 }
66 }
67 }
68
69 if (emergencyDive) {
70 return true;
71 }
72
73 return false;
74 }
75
76 public void advance(float amount) {
77 String id = "phase_anchor_modifier";
78 if (emergencyDive) {
79 Color c = ship.getPhaseCloak().getSpecAPI().getEffectColor2();
80 c = Misc.setAlpha(c, 255);
81 c = Misc.interpolateColor(c, Color.white, 0.5f);
82
83 if (diveProgress == 0f) {
84 if (ship.getFluxTracker().showFloaty()) {
85 float timeMult = ship.getMutableStats().getTimeMult().getModifiedValue();
87 "Emergency dive!",
88 NeuralLinkScript.getFloatySize(ship), c, ship, 16f * timeMult, 3.2f/timeMult, 1f/timeMult, 0f, 0f,
89 1f);
90 }
91 }
92
93 diveFader.advance(amount);
94 ship.setRetreating(true, false);
95
97 diveProgress += amount * ship.getPhaseCloak().getChargeUpDur();
98 float curr = ship.getExtraAlphaMult();
99 ship.getPhaseCloak().forceState(SystemState.IN, Math.min(1f, Math.max(curr, diveProgress)));
101
102 if (diveProgress >= 1f) {
103 if (diveFader.isIdle()) {
104 Global.getSoundPlayer().playSound("phase_anchor_vanish", 1f, 1f, ship.getLocation(), ship.getVelocity());
105 }
106 diveFader.fadeOut();
107 diveFader.advance(amount);
108 float b = diveFader.getBrightness();
109 ship.setExtraAlphaMult2(b);
110
111 float r = ship.getCollisionRadius() * 5f;
112 ship.setJitter(this, c, b, 20, r * (1f - b));
113
114 if (diveFader.isFadedOut()) {
115 ship.getLocation().set(0, -1000000f);
116 }
117 }
118 }
119
120
121 boolean phased = ship.isPhased();
122 if (ship.getPhaseCloak() != null && ship.getPhaseCloak().isChargedown()) {
123 phased = false;
124 }
125
127 if (phased) {
135
136 // doesn't actually work, needs to update the ammo tracker in the system and this isn't handled
137 // probably overpowered anyway...
138 //stats.getSystemRegenBonus().modifyMult(id, PHASE_DISSIPATION_MULT);
139 } else {
142 stats.getEnergyRoFMult().unmodifyMult(id);
147 //stats.getSystemRegenBonus().unmodifyMult(id);
148 }
149 }
150
151 }
152
153 @Override
154 public void applyEffectsAfterShipCreation(ShipAPI ship, String id) {
155 ship.addListener(new PhaseAnchorScript(ship));
156 }
157
158 public void applyEffectsBeforeShipCreation(HullSize hullSize, MutableShipStatsAPI stats, String id) {
160 }
161
162 public String getDescriptionParam(int index, HullSize hullSize) {
163 if (index == 0) return "zero";
164 if (index == 1) return "" + (int)PHASE_DISSIPATION_MULT + Strings.X;
165 if (index == 2) return "" + (int)CR_LOSS_MULT_FOR_EMERGENCY_DIVE + Strings.X;
166
167 // if (index == 1) return "" + (int) Math.round(PHASE_TIME_BONUS) + "%";
168// float multWithoutMod = PhaseCloakStats.MAX_TIME_MULT;
169// float multWithMod = 1f + (multWithoutMod - 1f) * (1f + PHASE_TIME_BONUS/100f);
170// if (index == 2) return "" + (int) Math.round(multWithoutMod) + Strings.X;
171// if (index == 3) return "" + (int) Math.round(multWithMod) + Strings.X;
172//
173// if (index == 4) return "" + (int) Math.round((1f - FLUX_THRESHOLD_DECREASE_MULT) * 100f) + "%";
174// if (index == 5) return "" + (int) Math.round(PhaseCloakStats.BASE_FLUX_LEVEL_FOR_MIN_SPEED * 100f) + "%";
175// if (index == 6) return "" + (int)Math.round(
176// PhaseCloakStats.BASE_FLUX_LEVEL_FOR_MIN_SPEED * 100f * FLUX_THRESHOLD_DECREASE_MULT) + "%";
177//
178 //if (index == 0) return "" + (int) Math.round(PHASE_COOLDOWN_REDUCTION) + "%";
179 return null;
180 }
181
182 @Override
183 public boolean isApplicableToShip(ShipAPI ship) {
184 if (ship.getVariant().hasHullMod(HullMods.ADAPTIVE_COILS)) return false;
185 return ship.getHullSpec().isPhase();
186 }
187
188 @Override
189 public String getUnapplicableReason(ShipAPI ship) {
191 return "Incompatible with Adaptive Phase Coils";
192 }
193 if (!ship.getHullSpec().isPhase()) {
194 return "Can only be installed on phase ships";
195 }
196 return super.getUnapplicableReason(ship);
197 }
198
199}
200
static SoundPlayerAPI getSoundPlayer()
Definition Global.java:49
static CombatEngineAPI getCombatEngine()
Definition Global.java:69
void modifyMult(String source, float value)
void modifyMult(String source, float value)
void applyEffectsBeforeShipCreation(HullSize hullSize, MutableShipStatsAPI stats, String id)
void applyEffectsAfterShipCreation(ShipAPI ship, String id)
String getDescriptionParam(int index, HullSize hullSize)
static Color setAlpha(Color color, int alpha)
Definition Misc.java:1316
static Color interpolateColor(Color from, Color to, float progress)
Definition Misc.java:1261
SoundAPI playSound(String id, float pitch, float volume, Vector2f loc, Vector2f vel)
void addFloatingTextAlways(Vector2f loc, String text, float size, Color color, CombatEntityAPI attachedTo, float flashFrequency, float flashDuration, float durInPlace, float durFloatingUp, float durFadingOut, float baseAlpha)
void setExtraAlphaMult2(float transparency)
MutableShipStatsAPI getMutableStats()
void addListener(Object listener)
void setRetreating(boolean retreating, boolean direct)
void blockCommandForOneFrame(ShipCommand command)
void setJitter(Object source, Color color, float intensity, int copies, float range)
void forceState(SystemState state, float progress)
void applyCREvent(float crChange, String description)