001package com.fs.starfarer.api.characters;
002
003import java.awt.Color;
004import java.util.ArrayList;
005import java.util.LinkedHashMap;
006import java.util.List;
007import java.util.Map;
008
009import com.fs.starfarer.api.Global;
010import com.fs.starfarer.api.combat.ShipVariantAPI;
011import com.fs.starfarer.api.fleet.FleetMemberAPI;
012import com.fs.starfarer.api.impl.campaign.plog.PlaythroughLog;
013import com.fs.starfarer.api.impl.campaign.plog.SModRecord;
014import com.fs.starfarer.api.loading.HullModSpecAPI;
015import com.fs.starfarer.api.loading.VariantSource;
016import com.fs.starfarer.api.ui.Alignment;
017import com.fs.starfarer.api.ui.ButtonAPI;
018import com.fs.starfarer.api.ui.TooltipMakerAPI;
019import com.fs.starfarer.api.ui.UIComponentAPI;
020import com.fs.starfarer.api.util.Misc;
021
022public class SkillsChangeRemoveSmodsEffect extends BaseSkillsChangeEffect {
023
024        public static class SmodRemovalEffectData {
025                FleetMemberAPI member;
026                List<SModRecord> records = new ArrayList<SModRecord>();
027                int maxBefore;
028                int maxAfter;
029                int numSmods;
030                int remove;
031                boolean offerChoice = false;
032                List<String> removeList = new ArrayList<String>();
033                
034                List<ButtonAPI> buttons = new ArrayList<ButtonAPI>();
035        }
036        
037        public static class SmodDataMap {
038                Map<FleetMemberAPI, SmodRemovalEffectData> map = new LinkedHashMap<FleetMemberAPI, SmodRemovalEffectData>();
039        }
040        public void setMap(SmodDataMap map, Map<String, Object> dataMap) {
041                String key = getClass().getSimpleName();
042                dataMap.put(key, map);
043        }
044        public SmodDataMap getMap(Map<String, Object> dataMap) {
045                String key = getClass().getSimpleName();
046                SmodDataMap map = (SmodDataMap)dataMap.get(key);
047                if (map == null) {
048                        map = new SmodDataMap();
049                        dataMap.put(key, map);
050                }
051                return map;
052        }
053        
054        public SmodDataMap getEffects(MutableCharacterStatsAPI from, MutableCharacterStatsAPI to) {
055                SmodDataMap result = new SmodDataMap();
056                
057                
058                for (SModRecord record : PlaythroughLog.getInstance().getSModsInstalled()) {
059                        FleetMemberAPI member = record.getMember();
060                        if (member == null) continue;
061                        if (record.getSMods().isEmpty()) continue;
062                        String modId = record.getSMods().get(0);
063                        if (!member.getVariant().getSMods().contains(modId)) continue;
064                        if (!member.getVariant().getHullMods().contains(modId)) continue;
065                        
066                        SmodRemovalEffectData data = result.map.get(member);
067                        if (data == null) {
068                                data = new SmodRemovalEffectData();
069                                data.member = member;
070                                data.numSmods = member.getVariant().getSMods().size();
071                                data.maxBefore = Misc.getMaxPermanentMods(member, from);
072                                data.maxAfter = Misc.getMaxPermanentMods(member, to);
073                                result.map.put(member, data);
074                        }
075                        data.records.add(record);
076                }
077                
078                for (FleetMemberAPI member : new ArrayList<FleetMemberAPI>(result.map.keySet())) {
079                        SmodRemovalEffectData data = result.map.get(member);
080                        if (data.maxBefore <= data.maxAfter || data.records.isEmpty() ||
081                                        data.numSmods <= data.maxAfter) {
082                                result.map.remove(member);
083                        } else {
084                                data.remove = Math.min(data.numSmods - data.maxAfter, data.records.size());
085                                data.offerChoice = data.remove <= 1 && 
086                                                Global.getSector().getPlayerFleet().getFleetData().getMembersListCopy().contains(data.member);
087                                if (!data.offerChoice) {
088                                        List<SModRecord> copy = new ArrayList<SModRecord>(data.records);
089                                        for (int i = 0; i < data.remove; i++) {
090                                                int minCost = 10000;
091                                                SModRecord minCostMod = null;
092                                                for (SModRecord record : data.records) {
093                                                        HullModSpecAPI mod = Global.getSettings().getHullModSpec(record.getSMods().get(0));
094                                                        int cost = mod.getCostFor(member.getHullSpec().getHullSize());
095                                                        if (cost < minCost) {
096                                                                minCostMod = record;
097                                                                minCost = cost;
098                                                        }
099                                                }
100                                                if (minCostMod != null) {
101                                                        data.removeList.add(minCostMod.getSMods().get(0));
102                                                        copy.remove(minCostMod);
103                                                }
104                                        }
105                                }
106                        }
107                }
108                
109                return result;
110        }
111        
112        
113        @Override
114        public boolean hasEffects(MutableCharacterStatsAPI from, MutableCharacterStatsAPI to) {
115                return !getEffects(from, to).map.isEmpty();
116        }
117
118        @Override
119        public void printEffects(MutableCharacterStatsAPI from, MutableCharacterStatsAPI to, TooltipMakerAPI info, Map<String, Object> dataMap) {
120                super.prepare();
121                
122                SmodDataMap map = getEffects(from, to);
123                setMap(map, dataMap);
124                
125                float pad = 3f;
126                float opad = 10f;
127                Color h = Misc.getHighlightColor();
128                
129                float initPad = 15f;
130                info.addSectionHeading("S-mods", base, dark, Alignment.MID, initPad);
131                initPad = opad;
132//              for (SmodRemovalEffectData data : map.map.values()) {
133//                      if (!data.offerChoice) {
134                                info.addPara("Ships that you've built s-mods into that now have more than their maximum"
135                                                + " number of s-mods will have the cheapest s-mods removed.", initPad, 
136                                                Misc.getNegativeHighlightColor(),
137                                                "cheapest s-mods removed");
138                                initPad = 15f;
139                                info.addPara("If only one s-mod is being removed, and the ship is currently in your fleet, "
140                                                + "you can select which s-mod to remove. S-mods you did not build into a ship will not be removed, even if the ship is over the limit.", opad);
141//                              break;
142//                      }
143//              }
144                
145                for (SmodRemovalEffectData data : map.map.values()) {
146                        final FleetMemberAPI member = data.member;
147                        
148                        if (data.offerChoice) {
149                                String str = "The " + member.getShipName() +
150                                " (" + member.getHullSpec().getHullNameWithDashClass() + "), will lose its built-in...";
151                                info.addPara(str, initPad);
152                                
153                                float bw = 470;
154                                float bh = 25;
155                                float indent = 40f;
156                                UIComponentAPI prev = null;
157                                int minCost = 10000;
158                                ButtonAPI minCostButton = null;
159                                for (SModRecord record : data.records) {
160                                        HullModSpecAPI mod = Global.getSettings().getHullModSpec(record.getSMods().get(0));
161                                        float p = opad;
162                                        if (prev != null) p = pad;
163                                        int cost = mod.getCostFor(member.getHullSpec().getHullSize());
164                                        ButtonAPI b = info.addAreaCheckbox(
165                                                        mod.getDisplayName() + " (" + cost + " OP)", new Object(), base, dark, bright, bw, bh, p, true);
166                                        data.buttons.add(b);
167
168                                        if (prev == null) {
169                                                b.getPosition().setXAlignOffset(indent);
170                                        }
171                                        prev = b;
172                                        if (cost < minCost) {
173                                                minCostButton = b;
174                                                minCost = cost;
175                                        }
176                                }
177                                if (minCostButton != null) {
178                                        minCostButton.setChecked(true);
179                                }
180                                
181                                info.addSpacer(0).getPosition().setXAlignOffset(-indent);
182                        }
183                }
184        }
185        
186        @Override
187        public void infoButtonPressed(ButtonAPI button, Object param, Map<String, Object> dataMap) {
188                SmodDataMap map = getMap(dataMap);
189                
190                for (SmodRemovalEffectData data : map.map.values()) {
191                        boolean found = false;
192                        for (ButtonAPI b : data.buttons) {
193                                if (b == button) {
194                                        found = true;
195                                        break;
196                                }
197                        }
198                        if (found) {
199                                for (ButtonAPI b : data.buttons) {
200                                        if (b == button) {
201                                                b.setChecked(true);
202                                        } else {
203                                                b.setChecked(false);
204                                        }
205                                }
206                                break;
207                        }
208                }
209        }
210        
211        @Override
212        public void applyEffects(MutableCharacterStatsAPI from, MutableCharacterStatsAPI to, Map<String, Object> dataMap) {
213                SmodDataMap map = getMap(dataMap);
214                
215                for (SmodRemovalEffectData data : map.map.values()) {
216                        ShipVariantAPI variant = data.member.getVariant();
217                        variant = variant.clone();
218                        variant.setSource(VariantSource.REFIT);
219                        
220                        if (data.offerChoice) {
221                                int index = 0;
222                                for (ButtonAPI b : data.buttons) {
223                                        if (b.isChecked()) {
224                                                SModRecord record = data.records.get(index);
225                                                data.removeList.add(record.getSMods().get(0));
226                                        }
227                                        index++;
228                                }
229                        }
230                        for (String modId : data.removeList) {
231                                variant.removePermaMod(modId);
232                        }
233                        data.member.setVariant(variant, false, false);
234                }
235        }
236        
237}
238
239
240
241
242
243
244