001package com.fs.starfarer.api.impl.campaign.skills;
002
003import java.awt.Color;
004
005import com.fs.starfarer.api.characters.FleetStatsSkillEffect;
006import com.fs.starfarer.api.characters.MutableCharacterStatsAPI;
007import com.fs.starfarer.api.characters.ShipSkillEffect;
008import com.fs.starfarer.api.characters.SkillSpecAPI;
009import com.fs.starfarer.api.combat.MutableShipStatsAPI;
010import com.fs.starfarer.api.combat.ShipAPI.HullSize;
011import com.fs.starfarer.api.fleet.FleetMemberAPI;
012import com.fs.starfarer.api.fleet.MutableFleetStatsAPI;
013import com.fs.starfarer.api.impl.campaign.DModManager;
014import com.fs.starfarer.api.impl.campaign.ids.Stats;
015import com.fs.starfarer.api.ui.TooltipMakerAPI;
016import com.fs.starfarer.api.util.Misc;
017
018public class HullRestoration {
019        
020        public static float RECOVERY_PROB = 2f;
021        public static float CR_PER_SMOD = 5;
022        
023        public static float CR_MAX_BONUS = 15;
024        public static float CR_MINUS_PER_DMOD = 5;
025        
026        public static float DMOD_AVOID_MAX = 0.9f;
027        public static float DMOD_AVOID_MIN = 0.75f;
028        
029        public static float DMOD_AVOID_MIN_DP = 5f;
030        
031        public static float DP_REDUCTION = 0.1f;
032        public static float DP_REDUCTION_MAX = 5f;
033        
034        
035        /**
036         * Lowest probability to avoid d-mods at this DP value and higher.
037         */
038        public static float DMOD_AVOID_MAX_DP = 60f;
039        
040        public static class Level1 implements FleetStatsSkillEffect {
041                public void apply(MutableFleetStatsAPI stats, String id, float level) {
042                        stats.getDynamic().getMod(Stats.SHIP_RECOVERY_MOD).modifyFlat(id, RECOVERY_PROB);       
043                }
044                public void unapply(MutableFleetStatsAPI stats, String id) {
045                        stats.getDynamic().getMod(Stats.SHIP_RECOVERY_MOD).unmodify(id);        
046                }
047                public String getEffectDescription(float level) {
048                        return "All of your ships are almost always recoverable if lost in combat";
049                }
050                public String getEffectPerLevelDescription() {
051                        return null;
052                }
053                public ScopeDescription getScopeDescription() {
054                        return ScopeDescription.FLEET;
055                }
056        }
057        
058        public static class Level2 implements ShipSkillEffect {
059                public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
060                        float dp = DMOD_AVOID_MIN_DP;
061                        if (stats.getFleetMember() != null) {
062                                dp = stats.getFleetMember().getDeploymentPointsCost();
063                        }
064                        float mult = 1f - (dp - DMOD_AVOID_MIN_DP) / (DMOD_AVOID_MAX_DP - DMOD_AVOID_MIN_DP);
065                        if (mult > 1f) mult = 1f;
066                        if (mult < 0f) mult = 0f;
067                        
068                        float probAvoid = DMOD_AVOID_MIN + (DMOD_AVOID_MAX - DMOD_AVOID_MIN) * mult;
069                        
070                        stats.getDynamic().getMod(Stats.DMOD_ACQUIRE_PROB_MOD).modifyMult(id, 1f - probAvoid);
071                }
072                
073                public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
074                        stats.getDynamic().getMod(Stats.DMOD_ACQUIRE_PROB_MOD).unmodify(id);
075                }
076                
077                public String getEffectDescription(float level) {
078                        String lowDP = "" + (int) DMOD_AVOID_MIN_DP;
079                        String highDP = "" + (int) DMOD_AVOID_MAX_DP;
080                        String lowChance = "" + (int) Math.round(DMOD_AVOID_MIN * 100f) + "%";
081                        String highChance = "" + (int) Math.round(DMOD_AVOID_MAX * 100f) + "%";
082                        return "Ships lost in combat have a " + lowChance + " (if " + highDP + " deployment points or higher) to " + highChance + " (" + lowDP + " DP or lower) chance to avoid d-mods";
083                        //"Ships lost in combat have a 90% (if 5 deployment points or lower) to 75% (50 DP or higher) chance to avoid d-mods
084                        //return "+" + (int)(CR_PER_SMOD) + "% maximum combat readiness per s-mod built into the hull";
085                }
086                
087                public String getEffectPerLevelDescription() {
088                        return null;
089                }
090                
091                public ScopeDescription getScopeDescription() {
092                        return ScopeDescription.PILOTED_SHIP;
093                }
094        }
095        public static class Level3 implements ShipSkillEffect {
096                public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
097                        float num = 0f;
098                        if (stats.getVariant() != null) {
099                                num = stats.getVariant().getSMods().size();
100                        }
101                        stats.getMaxCombatReadiness().modifyFlat(id, num * CR_PER_SMOD * 0.01f, "Hull Restoration skill");
102                }
103                
104                public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
105                        stats.getMaxCombatReadiness().unmodify(id);
106                }
107                
108                public String getEffectDescription(float level) {
109                        return "+" + (int)(CR_PER_SMOD) + "% maximum combat readiness per s-mod built into the hull";
110                }
111                
112                public String getEffectPerLevelDescription() {
113                        return null;
114                }
115
116                public ScopeDescription getScopeDescription() {
117                        return ScopeDescription.PILOTED_SHIP;
118                }
119        }
120        
121        public static class Level3B implements ShipSkillEffect {
122                public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
123                        FleetMemberAPI member = stats.getFleetMember();
124                        
125                        
126                        float dmods = 0;
127                        if (member != null) {
128                                dmods = DModManager.getNumDMods(member.getVariant());
129                        } else if (stats.getVariant() != null) {
130                                dmods = DModManager.getNumDMods(stats.getVariant());
131                        }
132                        
133                        float bonus = CR_MAX_BONUS - dmods * CR_MINUS_PER_DMOD;
134                        bonus = Math.round(bonus);
135                        if (bonus < 0) bonus = 0;
136                        
137                        stats.getMaxCombatReadiness().modifyFlat(id, bonus * 0.01f, "Hull Restoration skill");
138                }
139                
140                public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
141                        stats.getMaxCombatReadiness().unmodify(id);
142                }
143                
144                public String getEffectDescription(float level) {
145                        return "+" + (int)(CR_MAX_BONUS) + "% maximum combat readiness for all ships, minus " + (int)CR_MINUS_PER_DMOD + "% per d-mod (minimum of 0%)";
146                }
147                
148                public String getEffectPerLevelDescription() {
149                        return null;
150                }
151                
152                public ScopeDescription getScopeDescription() {
153                        return ScopeDescription.PILOTED_SHIP;
154                }
155        }
156        
157        public static class Level4A implements FleetStatsSkillEffect {
158                public void apply(MutableFleetStatsAPI stats, String id, float level) {
159                }
160                
161                public void unapply(MutableFleetStatsAPI stats, String id) {
162                }
163                
164                public String getEffectDescription(float level) {
165                        if (FieldRepairsScript.MONTHS_PER_DMOD_REMOVAL == 1) {
166                                return "Chance to remove one d-mod per month from a randomly selected ship in your fleet; faster for low-DP ships";
167                        } else if (FieldRepairsScript.MONTHS_PER_DMOD_REMOVAL == 2) {
168                                return "Chance to remove a d-mod from a randomly selected ship in your fleet every two months";
169                        } else {
170                                return "Chance to remove a d-mod from a randomly selected ship in your fleet every " +
171                                                        FieldRepairsScript.MONTHS_PER_DMOD_REMOVAL + " months";
172                        }
173                }
174                public String getEffectPerLevelDescription() {
175                        return null;
176                }
177                public ScopeDescription getScopeDescription() {
178                        return ScopeDescription.FLEET;
179                }
180        }
181        
182        public static class Level4B implements FleetStatsSkillEffect {
183                public void apply(MutableFleetStatsAPI stats, String id, float level) {
184                }
185                
186                public void unapply(MutableFleetStatsAPI stats, String id) {
187                }
188                
189                public String getEffectDescription(float level) {
190                        return "Chance to quickly remove one d-mod from newly acquired ships; higher for ships with more d-mods";
191                }
192                public String getEffectPerLevelDescription() {
193                        return null;
194                }
195                public ScopeDescription getScopeDescription() {
196                        return ScopeDescription.FLEET;
197                }
198        }
199        
200        
201        public static class Level5 extends BaseSkillEffectDescription implements ShipSkillEffect {
202                public void createCustomDescription(MutableCharacterStatsAPI stats, SkillSpecAPI skill, 
203                                TooltipMakerAPI info, float width) {
204                        init(stats, skill);
205                        float opad = 10f;
206                        Color c = Misc.getBasePlayerColor();
207                        //info.addPara("Affects: %s", opad + 5f, Misc.getGrayColor(), c, "fleet");
208                        info.addPara("Affects: %s", opad + 5f, Misc.getGrayColor(), c, "pristine and near-pristine ships (at most one d-mod)");
209                        info.addSpacer(opad);
210
211                        String max = "" + (int) DP_REDUCTION_MAX;
212                        String percent = "" + (int)Math.round(DP_REDUCTION * 100f) + "%";
213                        info.addPara("Deployment point cost reduced by %s or %s points, whichever is less",
214                                        0f, Misc.getHighlightColor(), Misc.getHighlightColor(), percent, max);                  
215                        
216                }
217
218                public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
219                        FleetMemberAPI member = stats.getFleetMember();
220                        float dmods = 0;
221                        if (member != null) {
222                                dmods = DModManager.getNumDMods(member.getVariant());
223                        }
224                        
225                        if (dmods > 1) return;
226                        
227                        float baseCost = stats.getSuppliesToRecover().getBaseValue();
228                        float reduction = Math.min(DP_REDUCTION_MAX, baseCost * DP_REDUCTION);
229                        
230                        stats.getDynamic().getMod(Stats.DEPLOYMENT_POINTS_MOD).modifyFlat(id, -reduction);
231                }
232
233                public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
234                        stats.getDynamic().getMod(Stats.DEPLOYMENT_POINTS_MOD).unmodifyFlat(id);
235                }
236        }
237}