001package com.fs.starfarer.api.characters;
002
003import java.util.LinkedHashMap;
004import java.util.Map;
005
006import com.fs.starfarer.api.Global;
007import com.fs.starfarer.api.combat.ShipHullSpecAPI;
008import com.fs.starfarer.api.combat.ShipVariantAPI;
009import com.fs.starfarer.api.fleet.FleetMemberAPI;
010import com.fs.starfarer.api.loading.HullModSpecAPI;
011import com.fs.starfarer.api.loading.VariantSource;
012import com.fs.starfarer.api.ui.Alignment;
013import com.fs.starfarer.api.ui.ButtonAPI;
014import com.fs.starfarer.api.ui.TooltipMakerAPI;
015import com.fs.starfarer.api.util.Misc;
016
017public class SkillsChangeRemoveExcessOPEffect extends BaseSkillsChangeEffect {
018
019        public static class OPEffectData {
020                FleetMemberAPI member;
021                int maxOP;
022                int currOP;
023        }
024        
025        public static class OPDataMap {
026                Map<FleetMemberAPI, OPEffectData> map = new LinkedHashMap<FleetMemberAPI, OPEffectData>();
027        }
028        public void setMap(OPDataMap map, Map<String, Object> dataMap) {
029                String key = getClass().getSimpleName();
030                dataMap.put(key, map);
031        }
032        public OPDataMap getMap(Map<String, Object> dataMap) {
033                String key = getClass().getSimpleName();
034                OPDataMap map = (OPDataMap)dataMap.get(key);
035                if (map == null) {
036                        map = new OPDataMap();
037                        dataMap.put(key, map);
038                }
039                return map;
040        }
041        
042        public static int getMaxOP(ShipHullSpecAPI hull, MutableCharacterStatsAPI stats) {
043                return hull.getOrdnancePoints(stats);
044        }
045        
046        
047        public OPDataMap getEffects(MutableCharacterStatsAPI from, MutableCharacterStatsAPI to) {
048                OPDataMap result = new OPDataMap();
049                
050                for (FleetMemberAPI member : Global.getSector().getPlayerFleet().getFleetData().getMembersListCopy()) {
051                        OPEffectData data = new OPEffectData();
052                        int maxOPPre = getMaxOP(member.getHullSpec(), from);
053                        int maxOPPost = getMaxOP(member.getHullSpec(), to);
054                        
055                        int op = member.getVariant().computeOPCost(to);
056                        
057                        data.member = member;
058                        data.maxOP = maxOPPost;
059                        data.currOP = op;
060                        
061                        if (maxOPPost < maxOPPre && op > maxOPPost) {
062                                result.map.put(member, data);
063                        }
064                }
065                return result;
066        }
067        
068        
069        @Override
070        public boolean hasEffects(MutableCharacterStatsAPI from, MutableCharacterStatsAPI to) {
071                return !getEffects(from, to).map.isEmpty();
072        }
073
074        @Override
075        public void printEffects(MutableCharacterStatsAPI from, MutableCharacterStatsAPI to, TooltipMakerAPI info, Map<String, Object> dataMap) {
076                super.prepare();
077                
078                OPDataMap map = getEffects(from, to);
079                setMap(map, dataMap);
080                
081                info.addSectionHeading("Excess ordnance points", base, dark, Alignment.MID, 15f);
082                
083                info.addPara("Ships using more than their maximum ordnance points will have "
084                                + "vents, capacitors, hullmods, and other equipment removed to bring them under the limit.", 10f,
085                                Misc.getNegativeHighlightColor(),
086                                "vents, capacitors, hullmods, and other equipment removed"
087                                );
088        }
089        
090        @Override
091        public void infoButtonPressed(ButtonAPI button, Object param, Map<String, Object> dataMap) {
092        }
093        
094        @Override
095        public void applyEffects(MutableCharacterStatsAPI from, MutableCharacterStatsAPI to, Map<String, Object> dataMap) {
096                OPDataMap map = getMap(dataMap);
097                
098                for (OPEffectData data : map.map.values()) {
099                        clampOP(data.member, to);
100                }
101        }
102        
103        public static void clampOP(FleetMemberAPI member, MutableCharacterStatsAPI stats) {
104                int maxOP = getMaxOP(member.getHullSpec(), stats);
105                int op = member.getVariant().computeOPCost(stats);
106                int remove = op - maxOP;
107                if (remove > 0) {
108                        ShipVariantAPI variant = member.getVariant();
109                        variant = variant.clone();
110                        variant.setSource(VariantSource.REFIT);
111                        
112                        int caps = variant.getNumFluxCapacitors();
113                        int curr = Math.min(caps, remove);
114                        variant.setNumFluxCapacitors(caps - curr);
115                        remove -= curr;
116                        if (remove > 0) {
117                                int vents = variant.getNumFluxVents();
118                                curr = Math.min(vents, remove);
119                                variant.setNumFluxVents(vents - curr);
120                                remove -= curr;
121                        }
122                        if (remove > 0) {
123                                for (String modId : variant.getNonBuiltInHullmods()) {
124                                        HullModSpecAPI mod = Global.getSettings().getHullModSpec(modId);
125                                        curr = mod.getCostFor(member.getHullSpec().getHullSize());
126                                        variant.removeMod(modId);
127                                        remove -= curr;
128                                        if (remove <= 0) break;
129                                }
130                        }
131                        // would need to add these to player cargo; gets potentially messy - don't do it
132//                      if (remove > 0) {
133//                              for (String slotId : variant.getNonBuiltInWeaponSlots()) {
134//                                      WeaponSpecAPI spec = variant.getWeaponSpec(slotId);
135//                                      curr = (int)Math.round(spec.getOrdnancePointCost(stats, member.getStats()));
136//                                      variant.clearSlot(slotId);
137//                                      remove -= curr;
138//                                      if (remove <= 0) break;
139//                              }
140//                      }
141//                      if (remove > 0) {
142//                              for (int i = 0; i < variant.getWings().size(); i++) {
143//                                      if (i < variant.getHullSpec().getBuiltInWings().size()) continue;
144//                                      FighterWingSpecAPI spec = variant.getWing(i);
145//                                      curr = (int)Math.round(spec.getOpCost(member.getStats()));
146//                                      variant.setWingId(i, "");
147//                                      remove -= curr;
148//                                      if (remove <= 0) break;
149//                              }
150//                      }
151                        
152                        member.setVariant(variant, false, false);
153                }
154        }
155        
156}
157
158
159
160
161
162
163