Starsector API
Loading...
Searching...
No Matches
CombatEndurance.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.skills;
2
3import org.lwjgl.util.vector.Vector2f;
4
5import com.fs.starfarer.api.Global;
6import com.fs.starfarer.api.characters.AfterShipCreationSkillEffect;
7import com.fs.starfarer.api.characters.MutableCharacterStatsAPI;
8import com.fs.starfarer.api.characters.ShipSkillEffect;
9import com.fs.starfarer.api.characters.SkillSpecAPI;
10import com.fs.starfarer.api.combat.CombatEntityAPI;
11import com.fs.starfarer.api.combat.DamageAPI;
12import com.fs.starfarer.api.combat.MutableShipStatsAPI;
13import com.fs.starfarer.api.combat.ShipAPI;
14import com.fs.starfarer.api.combat.ShipAPI.HullSize;
15import com.fs.starfarer.api.combat.listeners.AdvanceableListener;
16import com.fs.starfarer.api.combat.listeners.DamageTakenModifier;
17import com.fs.starfarer.api.ui.TooltipMakerAPI;
18import com.fs.starfarer.api.util.Misc;
19
20public class CombatEndurance {
21
22 public static float PEAK_TIME_BONUS = 60;
23 public static float DEGRADE_REDUCTION_PERCENT = 25f;
24 public static float MAX_CR_BONUS = 15;
25
26 //public static float OVERLOAD_REDUCTION = 30f;
27
28 //public static float MAX_REGEN_LEVEL = 0.5f;
29 public static float MAX_REGEN_LEVEL = 1f;
30 public static float REGEN_RATE = 0.005f;
31 public static float TOTAL_REGEN_MAX_POINTS = 2000f;
32 public static float TOTAL_REGEN_MAX_HULL_FRACTION = 0.5f;
33
34 public static class Level1 implements ShipSkillEffect {
35 public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
36 stats.getPeakCRDuration().modifyFlat(id, PEAK_TIME_BONUS);
37 }
38
39 public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
40 stats.getPeakCRDuration().unmodifyFlat(id);
41 }
42
43 public String getEffectDescription(float level) {
44 return "+" + (int)(PEAK_TIME_BONUS) + " seconds peak operating time";
45 }
46
47 public String getEffectPerLevelDescription() {
48 return null;
49 }
50
51 public ScopeDescription getScopeDescription() {
52 return ScopeDescription.PILOTED_SHIP;
53 }
54 }
55
56 public static class Level2 implements ShipSkillEffect {
57 public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
58 stats.getCRLossPerSecondPercent().modifyMult(id, 1f - DEGRADE_REDUCTION_PERCENT / 100f);
59 }
60
61 public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
62 stats.getCRLossPerSecondPercent().unmodifyMult(id);
63 }
64
65 public String getEffectDescription(float level) {
66 return "-" + (int)(DEGRADE_REDUCTION_PERCENT) + "% combat readiness degradation rate after peak performance time runs out";
67 }
68
69 public String getEffectPerLevelDescription() {
70 return null;
71 }
72
73 public ScopeDescription getScopeDescription() {
74 return ScopeDescription.PILOTED_SHIP;
75 }
76 }
77
78 public static class Level3 implements ShipSkillEffect {
79
80 public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
81 stats.getMaxCombatReadiness().modifyFlat(id, MAX_CR_BONUS * 0.01f, "Combat Endurance skill");
82 }
83
84 public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
85 stats.getMaxCombatReadiness().unmodify(id);
86 }
87
88 public String getEffectDescription(float level) {
89 return "+" + (int)(MAX_CR_BONUS) + "% maximum combat readiness";
90 }
91
92 public String getEffectPerLevelDescription() {
93 return null;
94 }
95
96 public ScopeDescription getScopeDescription() {
97 return ScopeDescription.PILOTED_SHIP;
98 }
99 }
100
101 public static class Level4 extends BaseSkillEffectDescription implements ShipSkillEffect, AfterShipCreationSkillEffect {
102 public void applyEffectsAfterShipCreation(ShipAPI ship, String id) {
103 ship.addListener(new CombatEnduranceRegen(ship));
104 }
105
106 public void unapplyEffectsAfterShipCreation(ShipAPI ship, String id) {
107 ship.removeListenerOfClass(CombatEnduranceRegen.class);
108 }
109
110
111 public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {}
112
113 public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {}
114
115 public void createCustomDescription(MutableCharacterStatsAPI stats, SkillSpecAPI skill,
116 TooltipMakerAPI info, float width) {
117 initElite(stats, skill);
118
119 info.addPara("When below %s hull, repair %s per second; maximum total repair is "
120 + "the higher of %s points or %s of maximum hull", 0f, hc, hc,
121 "" + (int)Math.round(MAX_REGEN_LEVEL * 100f) + "%",
122 //"" + (int)Math.round(REGEN_RATE * 100f) + "%",
123 "" + Misc.getRoundedValueMaxOneAfterDecimal(REGEN_RATE * 100f) + "%",
124 "" + (int)Math.round(TOTAL_REGEN_MAX_POINTS) + "",
125 "" + (int)Math.round(TOTAL_REGEN_MAX_HULL_FRACTION * 100f) + "%"
126 );
127
128 //info.addSpacer(5f);
129 }
130 }
131
132 public static class CombatEnduranceRegen implements DamageTakenModifier, AdvanceableListener {
133 protected ShipAPI ship;
134 protected boolean inited = false;
135 protected float limit = 0f;
136 protected float repaired = 0f;
137 protected String repKey1;
138 protected String repKey2;
139 public CombatEnduranceRegen(ShipAPI ship) {
140 this.ship = ship;
141 }
142
143 protected void init() {
144 inited = true;
145
146 float maxHull = ship.getMaxHitpoints();
147 limit = Math.max(TOTAL_REGEN_MAX_POINTS, TOTAL_REGEN_MAX_HULL_FRACTION * maxHull);
148
149 repKey1 = "CombatEnduranceRegen_ " + ship.getId() + "_repaired";
150 repKey2 = "CombatEnduranceRegen_ " + ship.getCaptain().getId() + "_repaired";
151 float r1 = getRepaired(repKey1);
152 float r2 = getRepaired(repKey2);
153
154 repaired = Math.max(repaired, r1);
155 repaired = Math.max(repaired, r2);
156 }
157
158 protected float getRepaired(String key) {
159 Float r = (Float) Global.getCombatEngine().getCustomData().get(key);
160 if (r == null) r = 0f;
161 return r;
162 }
163
164 public void advance(float amount) {
165 if (!inited) {
166 init();
167 }
168
169 if (repaired >= limit) return;
170 if (ship.getHullLevel() >= MAX_REGEN_LEVEL) return;
171 if (ship.isHulk()) return;
172
173 float maxHull = ship.getMaxHitpoints();
174 float currHull = ship.getHitpoints();
175 float maxPoints = maxHull * MAX_REGEN_LEVEL;
176
177 float repairAmount = Math.min(limit - repaired, maxHull * REGEN_RATE * amount);
178 // fix up remainder instantly so that there's no incentive to wait to finish a fight
179 // so that hull is higher when it's over
180 // actually - don't need to do this due to ship.getLowestHullLevelReached()
181 // always being the hull level after combat
182// if (Global.getCombatEngine().isCombatOver()) {
183// repairAmount = limit - repaired;
184// }
185 if (repairAmount > maxPoints - currHull) repairAmount = maxPoints - currHull;
186
187 if (repairAmount > 0) {
188 ship.setHitpoints(ship.getHitpoints() + repairAmount);
189 repaired += repairAmount;
190 Global.getCombatEngine().getCustomData().put(repKey1, repaired);
191 // allow *some* extra repairs when switching to another ship
192 Global.getCombatEngine().getCustomData().put(repKey2, repaired * 0.5f);
193 }
194 }
195
196 public String modifyDamageTaken(Object param,
197 CombatEntityAPI target, DamageAPI damage,
198 Vector2f point, boolean shieldHit) {
199 return null;
200 }
201
202 }
203
204
205// public static final float MALFUNCTION_REDUCTION = 50f;
206// public static final float CRITICAL_MALFUNCTION_REDUCTION = 50f;
207// public static final float PEAK_TIME_BONUS = 25;
208// public static final float MASTERY_PEAK_TIME_BONUS = 10;
209// //public static final float RECOVERY_RATE_BONUS = 25;
210// public static final float MAX_CR_BONUS = 15;
211//
212// public static class Level1 implements ShipSkillEffect {
213//
214// public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
215// stats.getPeakCRDuration().modifyPercent(id, PEAK_TIME_BONUS);
216// }
217//
218// public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
219// stats.getPeakCRDuration().unmodify(id);
220// }
221//
222// public String getEffectDescription(float level) {
223// return "+" + (int)(PEAK_TIME_BONUS) + "% peak operating time";
224// }
225//
226// public String getEffectPerLevelDescription() {
227// return null;
228// }
229//
230// public ScopeDescription getScopeDescription() {
231// return ScopeDescription.PILOTED_SHIP;
232// }
233// }
234//
235// public static class Level2 implements ShipSkillEffect {
236// public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
237// stats.getCriticalMalfunctionChance().modifyMult(id, 1f - CRITICAL_MALFUNCTION_REDUCTION / 100f);
238// stats.getWeaponMalfunctionChance().modifyMult(id, 1f - MALFUNCTION_REDUCTION / 100f);
239// stats.getEngineMalfunctionChance().modifyMult(id, 1f - MALFUNCTION_REDUCTION / 100f);
240// }
241//
242// public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
243// stats.getCriticalMalfunctionChance().unmodify(id);
244// stats.getWeaponMalfunctionChance().unmodify(id);
245// stats.getEngineMalfunctionChance().unmodify(id);
246// }
247//
248// public String getEffectDescription(float level) {
249// //return "" + (int)(RECOVERY_RATE_BONUS) + "% faster repairs and CR recovery";
250// //return "-" + (int)(CRITICAL_MALFUNCTION_REDUCTION) + "% chance of critical malfunctions when at low combat readiness";
251// return "-" + (int)(CRITICAL_MALFUNCTION_REDUCTION) + "% chance of malfunctions when at low combat readiness";
252// }
253//
254// public String getEffectPerLevelDescription() {
255// return null;
256// }
257//
258// public ScopeDescription getScopeDescription() {
259// return ScopeDescription.PILOTED_SHIP;
260// }
261// }
262//
263//
290//
291// public static class Level3 implements ShipSkillEffect {
292//
293// public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
294// stats.getMaxCombatReadiness().modifyFlat(id, MAX_CR_BONUS * 0.01f, "Combat endurance skill");
295// }
296//
297// public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
298// stats.getMaxCombatReadiness().unmodify(id);
299// }
300//
301// public String getEffectDescription(float level) {
302// return "+" + (int)(MAX_CR_BONUS) + "% maximum combat readiness";
303// }
304//
305// public String getEffectPerLevelDescription() {
306// return null;
307// }
308//
309// public ScopeDescription getScopeDescription() {
310// return ScopeDescription.PILOTED_SHIP;
311// }
312// }
313//
314//
315// public static class Mastery implements ShipSkillEffect {
316//
317// public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
318// stats.getPeakCRDuration().modifyPercent(id, MASTERY_PEAK_TIME_BONUS);
319// }
320//
321// public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
322// stats.getPeakCRDuration().unmodify(id);
323// }
324//
325// public String getEffectDescription(float level) {
326// return "+" + (int)(MASTERY_PEAK_TIME_BONUS) + "% peak operating time";
327// }
328//
329// public String getEffectPerLevelDescription() {
330// return null;
331// }
332//
333// public ScopeDescription getScopeDescription() {
334// return ScopeDescription.ALL_SHIPS;
335// }
336// }
337}
void initElite(MutableCharacterStatsAPI stats, SkillSpecAPI skill)