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.characters.CharacterStatsSkillEffect;
007import com.fs.starfarer.api.characters.DescriptionSkillEffect;
008import com.fs.starfarer.api.characters.MutableCharacterStatsAPI;
009import com.fs.starfarer.api.characters.MutableCharacterStatsAPI.SkillLevelAPI;
010import com.fs.starfarer.api.characters.PersonAPI;
011import com.fs.starfarer.api.characters.ShipSkillEffect;
012import com.fs.starfarer.api.characters.SkillSpecAPI;
013import com.fs.starfarer.api.combat.MutableShipStatsAPI;
014import com.fs.starfarer.api.combat.ShipAPI;
015import com.fs.starfarer.api.combat.ShipAPI.HullSize;
016import com.fs.starfarer.api.fleet.FleetMemberAPI;
017import com.fs.starfarer.api.impl.campaign.ids.Stats;
018import com.fs.starfarer.api.ui.TooltipMakerAPI;
019import com.fs.starfarer.api.util.Misc;
020
021public class CyberneticAugmentation {
022        
023        public static float MAX_ELITE_SKILLS_BONUS = 1;
024        public static float ECCM_BONUS = 5;
025        
026        public static float BONUS_PER_ELITE_SKILL = 1f;
027        
028        public static boolean isOfficer(MutableShipStatsAPI stats) {
029                if (stats.getEntity() instanceof ShipAPI) {
030                        ShipAPI ship = (ShipAPI) stats.getEntity();
031                        if (ship.getCaptain().isAICore()) return false;
032                        return !ship.getCaptain().isDefault();
033                } else {
034                        FleetMemberAPI member = stats.getFleetMember();
035                        if (member == null) return false;
036                        if (member.getCaptain().isAICore()) return false;
037                        return !member.getCaptain().isDefault();
038                }
039        }
040        
041        public static boolean isFlagship(MutableShipStatsAPI stats) {
042                if (stats.getEntity() instanceof ShipAPI) {
043                        ShipAPI ship = (ShipAPI) stats.getEntity();
044                        if (ship.getFleetMember() != null && 
045                                        ship.getFleetMember().getFleetCommander() == ship.getCaptain()) {
046                                return true;
047                        }
048                        return ship.getCaptain().isPlayer();
049                } else {
050                        FleetMemberAPI member = stats.getFleetMember();
051                        if (member == null) return false;
052                        if (member.isFlagship()) {
053                                return true;
054                        }
055                        return member.getCaptain().isPlayer();
056                }
057        }
058        
059        public static float getNumEliteSkillsOfFleetCommander(MutableShipStatsAPI stats) {
060                FleetMemberAPI member = stats.getFleetMember();
061                if (member == null && stats.getEntity() instanceof ShipAPI) {
062                        ShipAPI ship = (ShipAPI) stats.getEntity();
063                        member = ship.getFleetMember();
064                }
065                
066                if (member == null) return 0f;
067                PersonAPI person = member.getFleetCommanderForStats();
068                if (person ==  null) person = member.getFleetCommander();
069                if (person == null) return 0f;
070                
071                MutableCharacterStatsAPI fcStats = person.getStats();
072                if (fcStats == null) return 0f;
073                return getNumEliteSkills(fcStats);
074        }
075        
076        public static float getNumEliteSkills(MutableCharacterStatsAPI stats) {
077                float count = 0f;
078                for (SkillLevelAPI sl : stats.getSkillsCopy()) {
079                        if (sl.getLevel() >= 2f && sl.getSkill().isElite()) {
080                                count++;
081                        }
082                }
083                return count;
084        }
085        
086        public static class Level0 implements DescriptionSkillEffect {
087                public String getString() {
088                        int base = (int)Global.getSettings().getInt("officerMaxEliteSkills");
089                        return "\n*The base maximum number of elite skills per officer is " + base + "."; 
090                }
091                public Color[] getHighlightColors() {
092                        Color h = Misc.getDarkHighlightColor();
093                        return new Color[] {h};
094                }
095                public String[] getHighlights() {
096                        int base = (int)Global.getSettings().getInt("officerMaxEliteSkills");
097                        return new String [] {"" + base};
098                }
099                public Color getTextColor() {
100                        return null;
101                }
102        }
103        
104        public static class Level1 implements CharacterStatsSkillEffect {
105                
106                public void apply(MutableCharacterStatsAPI stats, String id, float level) {
107                        stats.getDynamic().getMod(Stats.OFFICER_MAX_ELITE_SKILLS_MOD).modifyFlat(id, MAX_ELITE_SKILLS_BONUS);
108                }
109                
110                public void unapply(MutableCharacterStatsAPI stats, String id) {
111                        stats.getDynamic().getMod(Stats.OFFICER_MAX_ELITE_SKILLS_MOD).unmodify(id);
112                }
113                
114                public String getEffectDescription(float level) {
115                        return "+" + (int) MAX_ELITE_SKILLS_BONUS + " to maximum number of elite skills* for officers under your command";
116                }
117                
118                public String getEffectPerLevelDescription() {
119                        return null;
120                }
121                
122                public ScopeDescription getScopeDescription() {
123                        return ScopeDescription.NONE;
124                }
125        }
126        
127        public static class Level2 extends BaseSkillEffectDescription implements ShipSkillEffect {
128                public void createCustomDescription(MutableCharacterStatsAPI stats, SkillSpecAPI skill, 
129                                TooltipMakerAPI info, float width) {
130                        init(stats, skill);
131                        float opad = 10f;
132                        Color c = Misc.getBasePlayerColor();
133                        //info.addPara("Affects: %s", opad + 5f, Misc.getGrayColor(), c, "fleet");
134                        info.addPara("Affects: %s", opad + 5f, Misc.getGrayColor(), c, "all ships with officers, including flagship");
135                        info.addSpacer(opad);
136                        
137//                      info.addPara("Negates up to %s of the weapon range penalty for superior enemy Electronic Warfare", 0f, hc, hc,
138//                                      "" + (int) ECCM_BONUS + "%");
139                        info.addPara("Reduces the weapon range penalty due to superior enemy Electronic Warfare by up to %s percentage points", 0f, hc, hc,
140                                        "" + (int) ECCM_BONUS + "");
141                }
142
143                public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
144                        if (isOfficer(stats)) {
145                                stats.getDynamic().getMod(Stats.ELECTRONIC_WARFARE_PENALTY_MOD).modifyFlat(id, -ECCM_BONUS);
146                        }
147                }
148
149                public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
150                        stats.getDynamic().getMod(Stats.ELECTRONIC_WARFARE_PENALTY_MOD).unmodifyFlat(id);
151                }
152        }
153        
154        public static class Level3 extends BaseSkillEffectDescription implements ShipSkillEffect {
155                public void createCustomDescription(MutableCharacterStatsAPI stats, SkillSpecAPI skill, 
156                                TooltipMakerAPI info, float width) {
157                        init(stats, skill);
158                        float opad = 10f;
159                        Color c = Misc.getBasePlayerColor();
160                        //info.addPara("Affects: %s", opad + 5f, Misc.getGrayColor(), c, "fleet");
161                        info.addPara("Affects: %s", opad + 5f, Misc.getGrayColor(), c, "all ships with officers (but not AI cores), including flagship");
162                        info.addSpacer(opad);
163                        
164                        
165                        float count = getNumEliteSkills(stats);
166                        float bonus = count * BONUS_PER_ELITE_SKILL;
167                        
168                        info.addPara("%s damage dealt and %s damage taken (%s for each elite skill you have)", 0f, hc, hc,
169                                        "+" + (int) Math.round(bonus) + "%",
170                                        "-" + (int) Math.round(bonus) + "%",
171                                        "" + (int) Math.round(BONUS_PER_ELITE_SKILL) + "%"
172                                        );
173                        info.addPara("The damage-dealt bonus is doubled for the flagship", hc, 0f);
174//                      info.addPara("%s damage taken (%s per your elite skill), doubled for flagship", 0f, hc, hc,
175//                                      "-" + (int) Math.round(bonus) + "%",
176//                                      "" + (int) Math.round(BONUS_PER_ELITE_SKILL) + "%"
177//                                      );
178                }
179
180                public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) {
181                        if (isOfficer(stats)) {
182                                float count = getNumEliteSkillsOfFleetCommander(stats);
183                                float bonusDealt = count * BONUS_PER_ELITE_SKILL;
184                                float bonusTaken = count * BONUS_PER_ELITE_SKILL;
185                                if (isFlagship(stats)) {
186                                        bonusDealt *= 2f;
187                                        //bonusTaken *= 2f;
188                                }
189                                
190                                stats.getArmorDamageTakenMult().modifyMult(id, 1f - bonusTaken / 100f);
191                                stats.getHullDamageTakenMult().modifyMult(id, 1f - bonusTaken / 100f);
192                                stats.getShieldDamageTakenMult().modifyMult(id, 1f - bonusTaken / 100f);
193                                
194                                stats.getBallisticWeaponDamageMult().modifyPercent(id, bonusDealt);
195                                stats.getEnergyWeaponDamageMult().modifyPercent(id, bonusDealt);
196                                stats.getMissileWeaponDamageMult().modifyPercent(id, bonusDealt);
197                        }
198                }
199
200                public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) {
201                        stats.getArmorDamageTakenMult().unmodifyMult(id);
202                        stats.getHullDamageTakenMult().unmodifyMult(id);
203                        stats.getShieldDamageTakenMult().unmodifyMult(id);
204                        
205                        stats.getBallisticWeaponDamageMult().unmodify(id);
206                        stats.getEnergyWeaponDamageMult().unmodify(id);
207                        stats.getMissileWeaponDamageMult().unmodify(id);
208                }
209        }
210}
211
212
213
214