001package com.fs.starfarer.api.impl.campaign.skills;
002
003import java.awt.Color;
004
005import com.fs.starfarer.api.Global;
006import com.fs.starfarer.api.campaign.FleetDataAPI;
007import com.fs.starfarer.api.characters.CharacterStatsSkillEffect;
008import com.fs.starfarer.api.characters.FleetStatsSkillEffect;
009import com.fs.starfarer.api.characters.FleetTotalItem;
010import com.fs.starfarer.api.characters.FleetTotalSource;
011import com.fs.starfarer.api.characters.MutableCharacterStatsAPI;
012import com.fs.starfarer.api.characters.ShipSkillEffect;
013import com.fs.starfarer.api.characters.SkillSpecAPI;
014import com.fs.starfarer.api.combat.MutableShipStatsAPI;
015import com.fs.starfarer.api.combat.MutableStat.StatMod;
016import com.fs.starfarer.api.combat.ShipAPI.HullSize;
017import com.fs.starfarer.api.combat.StatBonus;
018import com.fs.starfarer.api.fleet.FleetMemberAPI;
019import com.fs.starfarer.api.fleet.MutableFleetStatsAPI;
020import com.fs.starfarer.api.impl.campaign.ids.Stats;
021import com.fs.starfarer.api.ui.TooltipMakerAPI;
022import com.fs.starfarer.api.util.Misc;
023
024public class ContainmentProcedures {
025        
026//      public static final float CR_MALFUNCTION_RANGE_MULT = 0.5f;
027        //public static final float DMOD_EFFECT_MULT = 0.5f;
028        
029        public static float FUEL_PROD_BONUS = 1f;
030        public static float CREW_LOSS_REDUCTION = 50f;
031        public static float FUEL_SALVAGE_BONUS = 25f;
032        public static float FUEL_USE_REDUCTION_MAX_PERCENT = 25;
033        public static float FUEL_USE_REDUCTION_MAX_FUEL = 25;
034        
035
036        public static class Level1 extends BaseSkillEffectDescription implements ShipSkillEffect, FleetTotalSource {
037                
038                public FleetTotalItem getFleetTotalItem() {
039                        return getOPTotal();
040                }
041                
042                public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
043                        float lossPercent = computeAndCacheThresholdBonus(stats, "sp_crewloss", CREW_LOSS_REDUCTION, ThresholdBonusType.OP_ALL);
044                        stats.getCrewLossMult().modifyMult(id, 1f - (lossPercent * 0.01f));
045                }
046                        
047                public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
048                        stats.getCrewLossMult().unmodify(id);
049                }
050                
051                public String getEffectDescription(float level) {
052                        return null;
053                }
054                        
055                public void createCustomDescription(MutableCharacterStatsAPI stats, SkillSpecAPI skill, 
056                                                                                        TooltipMakerAPI info, float width) {
057                        init(stats, skill);
058                        
059                        //info.addSpacer(5f);
060                        FleetDataAPI data = getFleetData(null);
061                        float damBonus = computeAndCacheThresholdBonus(data, stats, "sp_crewloss", CREW_LOSS_REDUCTION, ThresholdBonusType.OP_ALL);
062                        
063                        info.addPara("-%s crew lost due to hull damage in combat (maximum: %s)", 0f, hc, hc,
064                                        "" + (int) damBonus + "%",
065                                        "" + (int) CREW_LOSS_REDUCTION + "%");
066                        addOPThresholdAll(info, data, stats, OP_ALL_THRESHOLD);
067                        
068                }
069                
070                public ScopeDescription getScopeDescription() {
071                        return ScopeDescription.ALL_SHIPS;
072                }
073        }       
074        
075        public static class Level2 implements FleetStatsSkillEffect {
076                public void apply(MutableFleetStatsAPI stats, String id, float level) {
077                        stats.getDynamic().getStat(Stats.EMERGENCY_BURN_CR_MULT).modifyMult(id, 0f);
078                }
079                
080                public void unapply(MutableFleetStatsAPI stats, String id) {
081                        stats.getDynamic().getStat(Stats.EMERGENCY_BURN_CR_MULT).unmodify(id);
082                }       
083                
084                public String getEffectDescription(float level) {
085                        return "The \"Emergency Burn\" ability no longer reduces combat readiness";
086                }
087                
088                public String getEffectPerLevelDescription() {
089                        return null;
090                }
091                
092                public ScopeDescription getScopeDescription() {
093                        return ScopeDescription.FLEET;
094                }
095        }
096        
097        public static class Level3 implements FleetStatsSkillEffect {
098                public void apply(MutableFleetStatsAPI stats, String id, float level) {
099                        stats.getDynamic().getStat(Stats.FUEL_SALVAGE_VALUE_MULT_FLEET).modifyFlat(id, FUEL_SALVAGE_BONUS * 0.01f);
100                }
101                
102                public void unapply(MutableFleetStatsAPI stats, String id) {
103                        stats.getDynamic().getStat(Stats.FUEL_SALVAGE_VALUE_MULT_FLEET).unmodify(id);
104                }
105                
106                public String getEffectDescription(float level) {
107                        float max = 0f;
108                        max += FUEL_SALVAGE_BONUS;
109                        return "+" + (int) max + "% fuel salvaged";
110                }
111                
112                public String getEffectPerLevelDescription() {
113                        return null;
114                }
115                
116                public ScopeDescription getScopeDescription() {
117                        return ScopeDescription.FLEET;
118                }
119        }
120        
121        public static String FUEL_EFFECT_ID = "sp_fuel_use_mod";
122        public static class Level4 extends BaseSkillEffectDescription implements ShipSkillEffect {
123                public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
124                        id = FUEL_EFFECT_ID;
125                        float useMult = getFuelUseMult(id, getFleetData(stats));
126                        stats.getFuelUseMod().modifyMult(id, useMult);
127                }
128                
129                public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
130                        id = FUEL_EFFECT_ID;
131                        stats.getFuelUseMod().unmodifyMult(id);
132                }
133                
134                public String getEffectDescription(float level) {
135                        return null;
136                }
137                
138                protected float getFuelUseBase(String id, FleetDataAPI data) {
139                        if (data == null) return 0f;
140                        
141                        float fuelUse = 0;
142                        for (FleetMemberAPI curr : data.getMembersListCopy()) {
143                                StatBonus stat = curr.getStats().getFuelUseMod();
144                                StatMod mod = stat.getMultBonus(id);
145                                if (mod != null) {
146                                        stat.unmodifyMult(mod.source);
147                                }
148                                fuelUse += curr.getFuelUse();
149                                if (mod != null) {
150                                        stat.modifyMult(mod.source, mod.value, mod.desc);
151                                }
152                        }
153                        return fuelUse;
154                }
155                
156                protected float getFuelUseMult(String id, FleetDataAPI data) {
157                        if (data == null) return 0f;
158                        
159                        String key = "conproc1";
160                        Float bonus = (Float) data.getCacheClearedOnSync().get(key);
161                        if (bonus != null) return bonus;
162                        
163                        float fuelUse = getFuelUseBase(id, data);
164
165                        float useMult = 0f;
166                        
167                        if (fuelUse > 0) {
168                                float maxReduced = Math.min(fuelUse * (FUEL_USE_REDUCTION_MAX_PERCENT * 0.01f), 
169                                                                                        FUEL_USE_REDUCTION_MAX_FUEL);
170                                useMult = 1f - maxReduced / fuelUse;
171                                //useMult = Math.round(useMult * 100f) / 100f;
172                        }
173                        
174                        data.getCacheClearedOnSync().put(key, useMult);
175                        return useMult;
176                }
177                
178                public void createCustomDescription(MutableCharacterStatsAPI stats, SkillSpecAPI skill, 
179                                                                                        TooltipMakerAPI info, float width) {
180                        init(stats, skill);
181//                      FUEL_USE_REDUCTION_MAX_PERCENT = 25;
182//                      FUEL_USE_REDUCTION_MAX_FUEL = 20;
183                        
184                        info.addSpacer(5f);
185                        info.addPara("Reduces fuel consumption by %s or %s units, whichever is lower",
186                                        0f, hc, hc,
187                                        "" + (int) FUEL_USE_REDUCTION_MAX_PERCENT + "%", 
188                                        "" + (int) FUEL_USE_REDUCTION_MAX_FUEL
189                                        );
190                        
191                        if (isInCampaign()) {
192                                FleetDataAPI data = Global.getSector().getPlayerFleet().getFleetData();
193                                String id = FUEL_EFFECT_ID;
194                                float fuelUse = getFuelUseBase(id, data);
195                                float useMult = getFuelUseMult(id, data);
196                                
197                                float reduction = fuelUse * (1f - useMult);
198                                
199                                boolean has = stats.getSkillLevel(skill.getId()) > 0;
200                                String is = "is";
201                                if (!has) is = "would be";
202                                info.addPara(indent + "Your fleet has a base fuel consumption of %s, which " + is + " reduced by %s, or %s units",
203                                                0f, tc, hc, 
204                                                "" + Misc.getRoundedValueMaxOneAfterDecimal(fuelUse), 
205                                                "" + (int)(Math.round((1f - useMult) * 100f)) + "%",
206                                                "" + Misc.getRoundedValueMaxOneAfterDecimal(reduction) 
207                                                );
208                                info.addSpacer(5f);
209                        }
210//                      float opad = 10f;
211//                      Color c = Misc.getBasePlayerColor();
212//                      info.addPara("Affects: %s", opad + 5f, Misc.getGrayColor(), c, "governed colony");
213//                      info.addSpacer(opad);
214//                      info.addPara("+%s fuel production", 0f, hc, hc,
215//                                      "" + (int) 1f);
216                }
217                
218                public ScopeDescription getScopeDescription() {
219                        return ScopeDescription.FLEET;
220                }
221        }
222        
223        public static class Level5 extends BaseSkillEffectDescription implements CharacterStatsSkillEffect {
224
225                public void apply(MutableCharacterStatsAPI stats, String id, float level) {
226                        stats.getDynamic().getMod(Stats.FUEL_SUPPLY_BONUS_MOD).modifyFlat(id, FUEL_PROD_BONUS);
227                }
228
229                public void unapply(MutableCharacterStatsAPI stats, String id) {
230                        stats.getDynamic().getMod(Stats.FUEL_SUPPLY_BONUS_MOD).unmodifyFlat(id);
231                }
232                
233                public void createCustomDescription(MutableCharacterStatsAPI stats, SkillSpecAPI skill, 
234                                TooltipMakerAPI info, float width) {
235                        init(stats, skill);
236
237                        float opad = 10f;
238                        Color c = Misc.getBasePlayerColor();
239                        info.addPara("Affects: %s", opad + 5f, Misc.getGrayColor(), c, "governed colony");
240                        info.addSpacer(opad);
241                        info.addPara("+%s fuel production", 0f, hc, hc,
242                        "" + (int) FUEL_PROD_BONUS);
243                }
244                
245                public ScopeDescription getScopeDescription() {
246                        return ScopeDescription.GOVERNED_OUTPOST;
247                }
248        }
249        
250//      public static class Level1 implements ShipSkillEffect {
251//              public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
252//                      stats.getCrewLossMult().modifyMult(id, 1f - CREW_LOSS_REDUCTION / 100f);
253//              }
254//              
255//              public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
256//                      stats.getCrewLossMult().unmodify(id);
257//              }       
258//              
259//              public String getEffectDescription(float level) {
260//                      //return "-" + (int)(CREW_LOSS_REDUCTION) + "% crew lost due to hull damage in combat";
261//                      return "-" + (int)(CREW_LOSS_REDUCTION) + "% crew lost in combat and non-combat operations";
262//              }
263//              
264//              public String getEffectPerLevelDescription() {
265//                      return null;
266//              }
267//              
268//              public ScopeDescription getScopeDescription() {
269//                      return ScopeDescription.ALL_SHIPS;
270//              }
271//      }
272//      
273//      public static class Level2 implements FleetStatsSkillEffect {
274//              public void apply(MutableFleetStatsAPI stats, String id, float level) {
275//                      stats.getDynamic().getStat(Stats.NON_COMBAT_CREW_LOSS_MULT).modifyMult(id, 1f - CREW_LOSS_REDUCTION / 100f);
276//              }
277//              
278//              public void unapply(MutableFleetStatsAPI stats, String id) {
279//                      stats.getDynamic().getStat(Stats.NON_COMBAT_CREW_LOSS_MULT).unmodify(id);
280//              }       
281//              
282//              public String getEffectDescription(float level) {
283//                      //return "-" + (int)(CREW_LOSS_REDUCTION) + "% crew lost in non-combat operations";
284//                      return null;
285//              }
286//              
287//              public String getEffectPerLevelDescription() {
288//                      return null;
289//              }
290//              
291//              public ScopeDescription getScopeDescription() {
292//                      return ScopeDescription.FLEET;
293//              }
294//      }
295//      
296//      public static class Level3 implements ShipSkillEffect {
297//              public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
298//                      //stats.getDynamic().getStat(Stats.HULL_DAMAGE_CR_LOSS).modifyMult(id, HULL_DAMAGE_CR_MULT);
299//                      stats.getDynamic().getStat(Stats.CORONA_EFFECT_MULT).modifyMult(id, CORONA_EFFECT_MULT);
300//              }
301//              
302//              public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
303//                      //stats.getDynamic().getStat(Stats.HULL_DAMAGE_CR_LOSS).unmodify(id);
304//                      stats.getDynamic().getStat(Stats.CORONA_EFFECT_MULT).unmodify(id);
305//              }       
306//              
307//              public String getEffectDescription(float level) {
308//                      return "-" + (int) Math.round((1f - CORONA_EFFECT_MULT) * 100f) + "% combat readiness lost from being in star corona or similar terrain";
309//              }
310//              
311//              public String getEffectPerLevelDescription() {
312//                      return null;
313//              }
314//              
315//              public ScopeDescription getScopeDescription() {
316//                      return ScopeDescription.ALL_SHIPS;
317//              }
318//      }
319        
320//      public static class Level2B implements ShipSkillEffect {
321//              public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
322//                      stats.getDynamic().getStat(Stats.DMOD_EFFECT_MULT).modifyMult(id, DMOD_EFFECT_MULT);
323//              }
324//              
325//              public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
326//                      stats.getDynamic().getStat(Stats.DMOD_EFFECT_MULT).unmodify(id);
327//              }       
328//              
329//              public String getEffectDescription(float level) {
330//                      return "Negative effects of \"lasting damage\" hullmods (d-mods) reduced by 50%";
331//              }
332//              
333//              public String getEffectPerLevelDescription() {
334//                      return null;
335//              }
336//              
337//              public ScopeDescription getScopeDescription() {
338//                      return ScopeDescription.ALL_SHIPS;
339//              }
340//      }
341//
342//      
343//      public static class Level3 implements ShipSkillEffect {
344//
345//              public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
346//                      stats.getDynamic().getStat(Stats.CR_MALFUNCION_RANGE).modifyMult(id, CR_MALFUNCTION_RANGE_MULT);
347//              }
348//              
349//              public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
350//                      stats.getDynamic().getStat(Stats.CR_MALFUNCION_RANGE).unmodify(id);
351//              }
352//              
353//              public String getEffectDescription(float level) {
354//                      return "" + (int) (100f * (1f - CR_MALFUNCTION_RANGE_MULT)) + "% reduced combat readiness range in which malfunctions and other negative effects occur";
355//              }
356//              
357//              public String getEffectPerLevelDescription() {
358//                      return null;
359//              }
360//
361//              public ScopeDescription getScopeDescription() {
362//                      return ScopeDescription.ALL_SHIPS;
363//              }
364//      }
365
366        
367}