001package com.fs.starfarer.api.impl.campaign.skills;
002
003import com.fs.starfarer.api.campaign.FleetDataAPI;
004import com.fs.starfarer.api.characters.FleetTotalItem;
005import com.fs.starfarer.api.characters.FleetTotalSource;
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;
011import com.fs.starfarer.api.combat.ShipAPI.HullSize;
012import com.fs.starfarer.api.fleet.FleetMemberAPI;
013import com.fs.starfarer.api.impl.campaign.ids.Stats;
014import com.fs.starfarer.api.impl.campaign.ids.Strings;
015import com.fs.starfarer.api.ui.TooltipMakerAPI;
016import com.fs.starfarer.api.util.Misc;
017
018public class FighterUplink {
019        
020        //public static float DAMAGE_PERCENT = 10;
021        
022        public static float MAX_SPEED_PERCENT = 20;
023        public static float CREW_LOSS_PERCENT = 50;
024        
025        public static float DAMAGE_BONUS_PERCENT = 10;
026        
027        public static float TARGET_LEADING_BONUS = 50f;
028        
029        public static float OFFICER_MULT = 1.5f;
030        public static boolean isOfficer(MutableShipStatsAPI stats) {
031                if (stats.getEntity() instanceof ShipAPI) {
032                        ShipAPI ship = (ShipAPI) stats.getEntity();
033                        if (ship == null) return false;
034                        if (ship.isFighter() && ship.getWing() != null && ship.getWing().getSourceShip() != null) {
035                                ship = ship.getWing().getSourceShip();
036                        }
037                        return ship.getCaptain() != null && !ship.getCaptain().isDefault();
038                } else {
039                        FleetMemberAPI member = stats.getFleetMember();
040                        if (member == null) return false;
041                        return !member.getCaptain().isDefault();
042                }
043        }
044        
045        public static class Level1 extends BaseSkillEffectDescription implements ShipSkillEffect {
046                
047                public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
048                        float crewLossReduction = computeAndCacheThresholdBonus(stats, "fu_crew_loss", CREW_LOSS_PERCENT, ThresholdBonusType.FIGHTER_BAYS);
049                        if (isOfficer(stats)) crewLossReduction *= OFFICER_MULT;
050                        stats.getDynamic().getStat(Stats.FIGHTER_CREW_LOSS_MULT).modifyMult(id, 1f - crewLossReduction / 100f);
051                }
052                
053                public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
054                        stats.getDynamic().getStat(Stats.FIGHTER_CREW_LOSS_MULT).unmodifyMult(id);
055                }
056                
057                public String getEffectDescription(float level) {
058                        return null;
059                }
060                
061                public void createCustomDescription(MutableCharacterStatsAPI stats, SkillSpecAPI skill, 
062                                                                                        TooltipMakerAPI info, float width) {
063                        init(stats, skill);
064
065
066                        FleetDataAPI data = getFleetData(null);
067                        float crewLossReduction = computeAndCacheThresholdBonus(data, stats, "fu_crew_loss", CREW_LOSS_PERCENT, ThresholdBonusType.FIGHTER_BAYS);
068
069                        info.addPara("-%s crew lost due to fighter losses in combat (maximum: %s)", 0f, hc, hc,
070                                        "" + (int) crewLossReduction + "%",
071                                        "" + (int) CREW_LOSS_PERCENT + "%");
072                        //info.addSpacer(5f);
073                }
074                
075                public ScopeDescription getScopeDescription() {
076                        return ScopeDescription.ALL_SHIPS;
077                }
078
079        }
080
081        
082        public static class Level2 extends BaseSkillEffectDescription implements ShipSkillEffect, FleetTotalSource {
083                
084                public FleetTotalItem getFleetTotalItem() {
085                        return getFighterBaysTotal();
086                }
087                
088                public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
089//                      float damBonus = getDamageBonus(stats);
090//                      stats.getBallisticWeaponDamageMult().modifyPercent(id, damBonus);
091//                      stats.getEnergyWeaponDamageMult().modifyPercent(id, damBonus);
092//                      stats.getMissileWeaponDamageMult().modifyPercent(id, damBonus);
093                        
094                        float speedBonus = getMaxSpeedBonus(stats);
095                        if (isOfficer(stats)) speedBonus *= OFFICER_MULT;
096                        stats.getMaxSpeed().modifyPercent(id, speedBonus);
097                        stats.getAcceleration().modifyPercent(id, speedBonus * 2f);
098                        stats.getDeceleration().modifyPercent(id, speedBonus * 2f);
099                        
100                        float aimBonus = getAimBonus(stats);
101                        if (isOfficer(stats)) aimBonus *= OFFICER_MULT;
102                        stats.getAutofireAimAccuracy().modifyFlat(id, aimBonus * 0.01f);
103                        
104                        float damBonus = getDamageBonus(stats);
105                        if (isOfficer(stats)) damBonus *= OFFICER_MULT;
106                        stats.getBallisticWeaponDamageMult().modifyPercent(id, damBonus);
107                        stats.getEnergyWeaponDamageMult().modifyPercent(id, damBonus);
108                        stats.getMissileWeaponDamageMult().modifyPercent(id, damBonus);
109                }
110                
111                public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
112//                      stats.getBallisticWeaponDamageMult().unmodifyPercent(id);
113//                      stats.getEnergyWeaponDamageMult().unmodifyPercent(id);
114//                      stats.getMissileWeaponDamageMult().unmodifyPercent(id);
115                        
116                        stats.getMaxSpeed().unmodifyPercent(id);
117                        stats.getAcceleration().unmodifyPercent(id);
118                        stats.getDeceleration().unmodifyPercent(id);
119                        
120                        stats.getAutofireAimAccuracy().unmodifyFlat(id);
121                        
122                        stats.getBallisticWeaponDamageMult().unmodifyPercent(id);
123                        stats.getEnergyWeaponDamageMult().unmodifyPercent(id);
124                        stats.getMissileWeaponDamageMult().unmodifyPercent(id);
125                }
126                
127                public String getEffectDescription(float level) {
128                        return null;
129                }
130                
131//              protected float getDamageBonus(MutableShipStatsAPI stats) {
132//                      FleetDataAPI data = getFleetData(stats);
133//                      return getDamageBonus(data);
134//              }
135//              protected float getDamageBonus(FleetDataAPI data) {
136//                      if (data == null) return DAMAGE_PERCENT;
137//                      String key = "fighter_uplink_damage";
138//                      Float bonus = (Float) data.getCacheClearedOnSync().get(key);
139//                      if (bonus != null) return bonus;
140//                      
141//                      float bays = getNumFighterBays(data);
142//                      bonus = getThresholdBasedRoundedBonus(DAMAGE_PERCENT, bays, FIGHTER_BAYS_THRESHOLD);
143//                      
144//                      data.getCacheClearedOnSync().put(key, bonus);
145//                      return bonus;
146//              }
147                protected float getMaxSpeedBonus(MutableShipStatsAPI stats) {
148                        FleetDataAPI data = getFleetData(stats);
149                        return getMaxSpeedBonus(data);
150                }
151                
152                protected float getMaxSpeedBonus(FleetDataAPI data) {
153                        if (data == null) return MAX_SPEED_PERCENT;
154                        String key = "fighter_uplink_max_speed";
155                        Float bonus = (Float) data.getCacheClearedOnSync().get(key);
156                        if (bonus != null) return bonus;
157                        
158                        float bays = getNumFighterBays(data);
159                        bonus = getThresholdBasedRoundedBonus(MAX_SPEED_PERCENT, bays, FIGHTER_BAYS_THRESHOLD);
160                        
161                        data.getCacheClearedOnSync().put(key, bonus);
162                        return bonus;
163                }
164                
165                protected float getAimBonus(MutableShipStatsAPI stats) {
166                        FleetDataAPI data = getFleetData(stats);
167                        return getAimBonus(data);
168                }
169                
170                protected float getAimBonus(FleetDataAPI data) {
171                        if (data == null) return TARGET_LEADING_BONUS;
172                        String key = "fighter_uplink_aim";
173                        Float bonus = (Float) data.getCacheClearedOnSync().get(key);
174                        if (bonus != null) return bonus;
175                        
176                        float bays = getNumFighterBays(data);
177                        bonus = getThresholdBasedRoundedBonus(TARGET_LEADING_BONUS, bays, FIGHTER_BAYS_THRESHOLD);
178                        
179                        data.getCacheClearedOnSync().put(key, bonus);
180                        return bonus;
181                }
182                
183                protected float getDamageBonus(MutableShipStatsAPI stats) {
184                        FleetDataAPI data = getFleetData(stats);
185                        return getDamageBonus(data);
186                }
187                
188                protected float getDamageBonus(FleetDataAPI data) {
189                        if (data == null) return DAMAGE_BONUS_PERCENT;
190                        String key = "fighter_uplink_damage";
191                        Float bonus = (Float) data.getCacheClearedOnSync().get(key);
192                        if (bonus != null) return bonus;
193                        
194                        float bays = getNumFighterBays(data);
195                        bonus = getThresholdBasedRoundedBonus(DAMAGE_BONUS_PERCENT, bays, FIGHTER_BAYS_THRESHOLD);
196                        
197                        data.getCacheClearedOnSync().put(key, bonus);
198                        return bonus;
199                }
200                
201                public void createCustomDescription(MutableCharacterStatsAPI stats, SkillSpecAPI skill, 
202                                                                                        TooltipMakerAPI info, float width) {
203                        init(stats, skill);
204                        
205                        /*
206+37% target leading accuracy (maximum: +50%)
207        Maximum at 6 or less fighter bays in fleet, your fleet has 8 fighter bays
208                         */
209                        
210                        FleetDataAPI data = getFleetData(null);
211                        //float damBonus = getDamageBonus(data);
212                        float speedBonus = getMaxSpeedBonus(data);
213                        float aimBonus = getAimBonus(data);
214                        float damBonus = getDamageBonus(data);
215                        //float bays = getNumFighterBays(data);
216                        
217//                      info.addPara("+%s damage dealt (maximum: %s)", 0f, hc, hc,
218//                                      "" + (int) damBonus + "%",
219//                                      "" + (int) DAMAGE_PERCENT + "%");
220//                      addFighterBayThresholdInfo(info, data);
221//                      
222//                      info.addSpacer(5f);
223                        
224                        info.addPara("+%s top speed (maximum: %s)", 0f, hc, hc,
225                                        "" + (int) speedBonus + "%",
226                                        "" + (int) MAX_SPEED_PERCENT + "%");
227                        info.addPara("+%s target leading accuracy (maximum: %s)", 0f, hc, hc,
228                                        "" + (int) aimBonus + "%",
229                                        "" + (int) TARGET_LEADING_BONUS + "%");
230                        info.addPara("+%s damage dealt (maximum: %s)", 0f, hc, hc,
231                                        "" + (int) damBonus + "%",
232                                        "" + (int) DAMAGE_BONUS_PERCENT + "%");                 
233                        addFighterBayThresholdInfo(info, data);
234                        info.addPara(indent + "Effect increased by %s for ships with officers, including flagship",
235                                        0f, tc, hc, 
236                                        "" + Misc.getRoundedValueMaxOneAfterDecimal(OFFICER_MULT) + Strings.X);
237                        
238                        //info.addSpacer(5f);
239                }
240                
241                public ScopeDescription getScopeDescription() {
242                        return ScopeDescription.ALL_FIGHTERS;
243                }
244
245        }
246        
247
248
249}
250
251
252
253
254