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