001package com.fs.starfarer.api.impl.campaign.skills;
002
003import com.fs.starfarer.api.Global;
004import com.fs.starfarer.api.campaign.FleetDataAPI;
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.MutableStat.StatMod;
011import com.fs.starfarer.api.combat.ShipAPI.HullSize;
012import com.fs.starfarer.api.combat.StatBonus;
013import com.fs.starfarer.api.fleet.FleetMemberAPI;
014import com.fs.starfarer.api.fleet.MutableFleetStatsAPI;
015import com.fs.starfarer.api.impl.campaign.ids.Stats;
016import com.fs.starfarer.api.ui.TooltipMakerAPI;
017import com.fs.starfarer.api.util.Misc;
018
019public class Salvaging {
020        
021        public static float CREW_LOSS_REDUCTION = 75f;
022        public static float SALVAGE_BONUS = 50f;
023        public static final float COMBAT_SALVAGE = 20f;
024        
025        public static float CARGO_CAPACITY_MAX_PERCENT = 50;
026        public static float CARGO_CAPACITY_MAX_VALUE = 1000;
027        public static float FUEL_SALVAGE_BONUS = 25f;
028        
029
030        public static class Level1 implements FleetStatsSkillEffect {
031                public void apply(MutableFleetStatsAPI stats, String id, float level) {
032                        String desc = "Salvaging skill";
033                        stats.getDynamic().getStat(Stats.SALVAGE_VALUE_MULT_FLEET_NOT_RARE).modifyFlat(id, SALVAGE_BONUS * 0.01f, desc);
034                }
035
036                public void unapply(MutableFleetStatsAPI stats, String id) {
037                        stats.getDynamic().getStat(Stats.SALVAGE_VALUE_MULT_FLEET_NOT_RARE).unmodify(id);
038                }
039
040                public String getEffectDescription(float level) {
041                        //return "+" + (int) max + "% resources and rare items recovered from abandoned stations and other derelicts";
042                        return "+" + (int) SALVAGE_BONUS + "% resources - but not rare items, such as blueprints - recovered from abandoned stations and other derelicts";
043                }
044
045                public String getEffectPerLevelDescription() {
046                        return null;
047                }
048
049                public ScopeDescription getScopeDescription() {
050                        return ScopeDescription.FLEET;
051                }
052        }
053        
054        public static class Level2 implements FleetStatsSkillEffect {
055                public void apply(MutableFleetStatsAPI stats, String id, float level) {
056                        stats.getDynamic().getStat(Stats.FUEL_SALVAGE_VALUE_MULT_FLEET).modifyFlat(id, FUEL_SALVAGE_BONUS * 0.01f);
057                }
058                
059                public void unapply(MutableFleetStatsAPI stats, String id) {
060                        stats.getDynamic().getStat(Stats.FUEL_SALVAGE_VALUE_MULT_FLEET).unmodify(id);
061                }
062                
063                public String getEffectDescription(float level) {
064                        float max = 0f;
065                        max += FUEL_SALVAGE_BONUS;
066                        return "+" + (int) max + "% fuel salvaged";
067                }
068                
069                public String getEffectPerLevelDescription() {
070                        return null;
071                }
072                
073                public ScopeDescription getScopeDescription() {
074                        return ScopeDescription.FLEET;
075                }
076        }
077        
078        public static class Level3 implements FleetStatsSkillEffect {
079                public void apply(MutableFleetStatsAPI stats, String id, float level) {
080                        stats.getDynamic().getStat(Stats.BATTLE_SALVAGE_MULT_FLEET).modifyFlat(id, COMBAT_SALVAGE * 0.01f);
081                }
082                
083                public void unapply(MutableFleetStatsAPI stats, String id) {
084                        stats.getDynamic().getStat(Stats.BATTLE_SALVAGE_MULT_FLEET).unmodify(id);
085                }
086                
087                public String getEffectDescription(float level) {
088                        return "+" + (int) COMBAT_SALVAGE + "% post-battle salvage";
089                }
090                
091                public String getEffectPerLevelDescription() {
092                        return null;
093                }
094                
095                public ScopeDescription getScopeDescription() {
096                        return ScopeDescription.FLEET;
097                }
098        }
099        
100        public static class Level5 implements FleetStatsSkillEffect {
101                public void apply(MutableFleetStatsAPI stats, String id, float level) {
102                        stats.getDynamic().getStat(Stats.NON_COMBAT_CREW_LOSS_MULT).modifyMult(id, 1f - CREW_LOSS_REDUCTION / 100f);
103                }
104
105                public void unapply(MutableFleetStatsAPI stats, String id) {
106                        stats.getDynamic().getStat(Stats.NON_COMBAT_CREW_LOSS_MULT).unmodify(id);
107                }       
108
109                public String getEffectDescription(float level) {
110                        return "-" + (int)(CREW_LOSS_REDUCTION) + "% crew lost in non-combat operations";
111                }
112
113                public String getEffectPerLevelDescription() {
114                        return null;
115                }
116
117                public ScopeDescription getScopeDescription() {
118                        return ScopeDescription.FLEET;
119                }
120        }
121
122        
123        public static String CARGO_EFFECT_ID = "sal_cargo_cap_mod";
124        public static class Level4 extends BaseSkillEffectDescription implements ShipSkillEffect {
125                public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
126                        id = CARGO_EFFECT_ID;
127                        float capMult = getCargoCapacityMult(id, getFleetData(stats));
128                        stats.getCargoMod().modifyMult(id, capMult);
129                }
130                
131                public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
132                        id = CARGO_EFFECT_ID;
133                        stats.getCargoMod().unmodifyMult(id);
134                }
135                
136                public String getEffectDescription(float level) {
137                        return null;
138                }
139                
140                protected float getCargoCapacityBase(String id, FleetDataAPI data) {
141                        if (data == null) return 0f;
142                        
143                        float cargoCap = 0;
144                        for (FleetMemberAPI curr : data.getMembersListCopy()) {
145                                StatBonus stat = curr.getStats().getCargoMod();
146                                StatMod mod = stat.getMultBonus(id);
147                                if (mod != null) {
148                                        stat.unmodifyMult(mod.source);
149                                }
150                                cargoCap += curr.getCargoCapacity();
151                                if (mod != null) {
152                                        stat.modifyMult(mod.source, mod.value, mod.desc);
153                                }
154                        }
155                        return cargoCap;
156                }
157                
158                protected float getCargoCapacityMult(String id, FleetDataAPI data) {
159                        if (data == null) return 0f;
160                        
161                        String key = "salvaging1";
162                        Float bonus = (Float) data.getCacheClearedOnSync().get(key);
163                        if (bonus != null) return bonus;
164                        
165                        float cargoBase = getCargoCapacityBase(id, data);
166
167                        float capMult = 0f;
168                        
169                        if (cargoBase > 0) {
170                                float addCapacity = Math.min(cargoBase * (CARGO_CAPACITY_MAX_PERCENT * 0.01f), 
171                                                                                        CARGO_CAPACITY_MAX_VALUE);
172                                capMult = 1f + addCapacity / cargoBase;
173                                capMult = Math.round(capMult * 100f) / 100f;
174                        }
175                        
176                        data.getCacheClearedOnSync().put(key, capMult);
177                        return capMult;
178                }
179                
180                public void createCustomDescription(MutableCharacterStatsAPI stats, SkillSpecAPI skill, 
181                                                                                        TooltipMakerAPI info, float width) {
182                        init(stats, skill);
183                        
184                        info.addSpacer(5f);
185                        info.addPara("Cargo capacity increased by %s or %s units, whichever is lower",
186                                        0f, hc, hc,
187                                        "" + (int) CARGO_CAPACITY_MAX_PERCENT + "%", 
188                                        "" + (int) CARGO_CAPACITY_MAX_VALUE
189                                        );
190                        
191                        if (isInCampaign()) {
192                                FleetDataAPI data = Global.getSector().getPlayerFleet().getFleetData();
193                                String id = CARGO_EFFECT_ID;
194                                float cargoCap = getCargoCapacityBase(id, data);
195                                float capMult = getCargoCapacityMult(id, data);
196                                
197                                float increase = cargoCap * (capMult - 1f);
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 cargo capacity of %s, which " + is + " increased by %s, or approximately %s units",
203                                                0f, tc, hc, 
204                                                "" + Misc.getRoundedValueMaxOneAfterDecimal(cargoCap), 
205                                                "" + (int)(Math.round((capMult - 1f) * 100f)) + "%",
206                                                "" + Misc.getRoundedValueMaxOneAfterDecimal(increase) 
207                                                );
208                                //info.addSpacer(5f);
209                        }
210                }
211                
212                public ScopeDescription getScopeDescription() {
213                        return ScopeDescription.FLEET;
214                }
215        }
216}
217
218
219