001package com.fs.starfarer.api.impl.campaign;
002
003import java.awt.Color;
004import java.util.HashMap;
005import java.util.Map;
006
007import com.fs.starfarer.api.GameState;
008import com.fs.starfarer.api.Global;
009import com.fs.starfarer.api.campaign.CampaignFleetAPI;
010import com.fs.starfarer.api.combat.BaseHullMod;
011import com.fs.starfarer.api.combat.MutableShipStatsAPI;
012import com.fs.starfarer.api.combat.ShipAPI;
013import com.fs.starfarer.api.combat.ShipAPI.HullSize;
014import com.fs.starfarer.api.fleet.FleetMemberAPI;
015import com.fs.starfarer.api.impl.campaign.ids.Stats;
016import com.fs.starfarer.api.ui.LabelAPI;
017import com.fs.starfarer.api.ui.TooltipMakerAPI;
018import com.fs.starfarer.api.util.Misc;
019
020public class RepairGantry extends BaseHullMod {
021        
022        private static Map mag = new HashMap();
023        static {
024                mag.put(HullSize.FRIGATE, 10f);
025                mag.put(HullSize.DESTROYER, 25f);
026                mag.put(HullSize.CRUISER, 30f);
027                mag.put(HullSize.CAPITAL_SHIP, 40f);
028        }
029        
030        public static final float BATTLE_SALVAGE_MULT = .2f;
031        public static final float MIN_CR = 0.1f;
032        
033        public void applyEffectsBeforeShipCreation(HullSize hullSize, MutableShipStatsAPI stats, String id) {
034                //stats.getDynamic().getMod(Stats.SALVAGE_VALUE_MULT_MOD).modifyFlat(id, SALVAGE_MODIFIER);
035                stats.getDynamic().getMod(Stats.SALVAGE_VALUE_MULT_MOD).modifyFlat(id, (Float) mag.get(hullSize) * 0.01f);
036                //stats.getDynamic().getMod(Stats.BATTLE_SALVAGE_VALUE_MULT_MOD).modifyFlat(id, (Float) mag.get(hullSize) * 0.01f * (Float) mag.get(hullSize) * 0.01f);
037        }
038        
039        public String getDescriptionParam(int index, HullSize hullSize) {
040                //if (index == 0) return "" + (int) (SALVAGE_MODIFIER * 100f);
041                //if (index == 1) return "" + (int) (BATTLE_SALVAGE_MODIFIER * 100f);
042                
043                if (index == 0) return "" + ((Float) mag.get(HullSize.FRIGATE)).intValue() + "%";
044                if (index == 1) return "" + ((Float) mag.get(HullSize.DESTROYER)).intValue() + "%";
045                if (index == 2) return "" + ((Float) mag.get(HullSize.CRUISER)).intValue() + "%";
046                if (index == 3) return "" + ((Float) mag.get(HullSize.CAPITAL_SHIP)).intValue() + "%";
047                if (index == 4) return "" + (int)Math.round(BATTLE_SALVAGE_MULT * 100f) + "%";
048                
049                return null;
050        }
051
052        @Override
053        public void advanceInCombat(ShipAPI ship, float amount) {
054                
055        }
056        
057        
058        @Override
059        public boolean shouldAddDescriptionToTooltip(HullSize hullSize, ShipAPI ship, boolean isForModSpec) {
060                return true;
061        }
062
063        @Override
064        public void addPostDescriptionSection(TooltipMakerAPI tooltip, HullSize hullSize, ShipAPI ship, float width, boolean isForModSpec) {
065                float pad = 3f;
066                float opad = 10f;
067                Color h = Misc.getHighlightColor();
068                Color bad = Misc.getNegativeHighlightColor();
069                
070                tooltip.addPara("Each additional ship with a salvage gantry provides diminishing returns. " +
071                                "The higher the highest recovery bonus from a single ship in the fleet, the later diminishing returns kick in.", opad);
072                
073                if (isForModSpec || ship == null) return;
074                if (Global.getSettings().getCurrentState() == GameState.TITLE) return;
075                
076                CampaignFleetAPI fleet = Global.getSector().getPlayerFleet();
077                float fleetMod = getAdjustedGantryModifier(fleet, null, 0f);
078                float currShipMod = (Float) mag.get(hullSize) * 0.01f;
079                
080                float fleetModWithOneMore = getAdjustedGantryModifier(fleet, null, currShipMod);
081                float fleetModWithoutThisShip = getAdjustedGantryModifier(fleet, ship.getFleetMemberId(), 0f);
082                
083                tooltip.addPara("The total resource recovery bonus for your fleet is %s.", opad, h,
084                                "" + (int)Math.round(fleetMod * 100f) + "%");
085                
086                float cr = ship.getCurrentCR();
087                for (FleetMemberAPI member : Global.getSector().getPlayerFleet().getFleetData().getMembersListCopy()) {
088                        if (member.getId().equals(ship.getFleetMemberId())) {
089                                cr = member.getRepairTracker().getCR();
090                        }
091                }
092                
093                if (cr < MIN_CR) {
094                        LabelAPI label = tooltip.addPara("This ship's combat readiness is below %s " +
095                                        "and the gantry can not be utilized. Bringing this ship into readiness " +
096                                        "would increase the fleetwide bonus to %s.",
097                                        opad, h,
098                                        "" + (int) Math.round(MIN_CR * 100f) + "%",
099                                        "" + (int)Math.round(fleetModWithOneMore * 100f) + "%");
100                        label.setHighlightColors(bad, h);
101                        label.setHighlight("" + (int) Math.round(MIN_CR * 100f) + "%", "" + (int)Math.round(fleetModWithOneMore * 100f) + "%");
102                        
103//                      tooltip.addPara("Bringing this ship into readiness " +
104//                                      "would increase the fleet's bonus to %s.", opad, h,
105//                                      "" + (int)Math.round(fleetModWithOneMore * 100f) + "%");
106                } else {
107                        if (fleetMod > currShipMod) {
108                                tooltip.addPara("Removing this ship would decrease it to %s. Adding another ship of the same type " +
109                                                "would increase it to %s.", opad, h,
110                                                "" + (int)Math.round(fleetModWithoutThisShip * 100f) + "%",
111                                                "" + (int)Math.round(fleetModWithOneMore * 100f) + "%");
112                        } else {
113                                tooltip.addPara("Adding another ship of the same type " +
114                                                "would increase it to %s.", opad, h,
115                                                "" + (int)Math.round(fleetModWithOneMore * 100f) + "%");
116                        }
117                }
118                
119                tooltip.addPara("The fleetwide post-battle salvage bonus is %s.", opad, h,
120                                "" + (int)Math.round(getAdjustedGantryModifierForPostCombatSalvage(fleet) * 100f) + "%");
121//                              "" + Misc.getRoundedValueMaxOneAfterDecimal(
122//                                              getAdjustedGantryModifierForPostCombatSalvage(fleet) * 100f) + "%");
123                
124        }
125
126        
127        public static float getAdjustedGantryModifierForPostCombatSalvage(CampaignFleetAPI fleet) {
128                return getAdjustedGantryModifier(fleet, null, 0) * BATTLE_SALVAGE_MULT;
129        }
130        
131        public static float getAdjustedGantryModifier(CampaignFleetAPI fleet, String skipId, float add) {
132                //List<Pair<FleetMemberAPI, Float>> values = new ArrayList<Pair<FleetMemberAPI,Float>>();
133                
134                float max = 0f;
135                float total = 0f;
136                for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
137                        if (member.isMothballed()) continue;
138                        if (member.getRepairTracker().getCR() < MIN_CR) continue;
139                        
140                        if (member.getId().equals(skipId)) { 
141                                continue;
142                        }
143                        float v = member.getStats().getDynamic().getMod(Stats.SALVAGE_VALUE_MULT_MOD).computeEffective(0f);
144                        if (v <= 0) continue;
145                        
146//                      Pair<FleetMemberAPI, Float> p = new Pair<FleetMemberAPI, Float>(member, v);
147//                      values.add(p);
148                        if (v > max) max = v;
149                        total += v;
150                }
151                if (add > max) max = add;
152                total += add;
153                
154                if (max <= 0) return 0f;
155                float units = total / max;
156                if (units <= 1) return max;
157                float mult = Misc.logOfBase(2.5f, units) + 1f;
158                float result = total * mult / units;
159                if (result <= 0) {
160                        result = 0;
161                } else {
162                        result = Math.round(result * 100f) / 100f;
163                        result = Math.max(result, 0.01f);
164                }
165                return result;
166        }
167        
168        
169}
170
171
172
173
174
175
176
177
178