001package com.fs.starfarer.api.impl.campaign.intel.events; 002 003import java.util.ArrayList; 004import java.util.LinkedHashSet; 005import java.util.List; 006import java.util.Set; 007 008import java.awt.Color; 009 010import com.fs.starfarer.api.Global; 011import com.fs.starfarer.api.campaign.StarSystemAPI; 012import com.fs.starfarer.api.campaign.comm.IntelInfoPlugin; 013import com.fs.starfarer.api.campaign.econ.MarketAPI; 014import com.fs.starfarer.api.impl.campaign.enc.SlipstreamPirateEPEC; 015import com.fs.starfarer.api.impl.campaign.fleets.EconomyFleetRouteManager; 016import com.fs.starfarer.api.impl.campaign.ids.Factions; 017import com.fs.starfarer.api.impl.campaign.intel.bases.PirateBaseIntel; 018import com.fs.starfarer.api.impl.campaign.rulecmd.HA_CMD; 019import com.fs.starfarer.api.ui.Alignment; 020import com.fs.starfarer.api.ui.MapParams; 021import com.fs.starfarer.api.ui.TooltipMakerAPI; 022import com.fs.starfarer.api.ui.TooltipMakerAPI.TooltipCreator; 023import com.fs.starfarer.api.ui.TooltipMakerAPI.TooltipLocation; 024import com.fs.starfarer.api.ui.UIPanelAPI; 025import com.fs.starfarer.api.util.Misc; 026import com.fs.starfarer.api.util.Range; 027 028public class PirateBasePirateActivityCause2 extends BaseHostileActivityCause2 { 029 030 public static boolean DEAL_PROVIDES_NEGATIVE_PROGRESS = false; 031 032 public static float MAX_MAG = 0.5f; 033 034 035 public static List<MarketAPI> getColoniesAffectedBy(PirateBaseIntel base) { 036 List<MarketAPI> result = new ArrayList<MarketAPI>(); 037 for (StarSystemAPI system : getSystemsAffectedBy(base)) { 038 result.addAll(Misc.getMarketsInLocation(system, Factions.PLAYER)); 039 } 040 return result; 041 } 042 043 public static List<StarSystemAPI> getSystemsAffectedBy(PirateBaseIntel base) { 044 List<StarSystemAPI> result = new ArrayList<StarSystemAPI>(); 045// for (IntelInfoPlugin intel : Global.getSector().getIntelManager().getIntel(HostileActivityIntel.class)) { 046// HostileActivityIntel curr = (HostileActivityIntel) intel; 047 for (StarSystemAPI system : Misc.getSystemsWithPlayerColonies(false)) { 048 if (getBaseIntel(system) == base) { 049 result.add(system); 050 } 051 } 052 return result; 053 } 054 055 056 public static PirateBaseIntel getBaseIntel(StarSystemAPI system) { 057 if (system == null) return null; 058 PirateBaseIntel base = SlipstreamPirateEPEC.getClosestPirateBase(system.getLocation()); 059 return base; 060 } 061 062 transient boolean ignoreDeal = false; 063 064 public PirateBasePirateActivityCause2(HostileActivityEventIntel intel) { 065 super(intel); 066 } 067 068 @Override 069 public void addExtraRows(TooltipMakerAPI info, BaseEventIntel intel) { 070 Set<PirateBaseIntel> seen = new LinkedHashSet<PirateBaseIntel>(); 071 for (final StarSystemAPI system : Misc.getSystemsWithPlayerColonies(false)) { 072 final PirateBaseIntel base = getBaseIntel(system); 073 if (base == null || seen.contains(base)) continue; 074 075 076 int numColonies = 0; 077 final List<String> affected = new ArrayList<String>(); 078 for (StarSystemAPI curr : getSystemsAffectedBy(base)) { 079 affected.add(curr.getNameWithNoType()); 080 numColonies += Misc.getMarketsInLocation(curr, Factions.PLAYER).size(); 081 } 082 if (affected.isEmpty()) continue; 083 084 seen.add(base); 085 086 087 final String colonies = numColonies != 1 ? "colonies" : "colony"; 088 final String isOrAre = numColonies != 1 ? "are" : "is"; 089 090 String desc = "Hidden pirate base near your " + colonies; 091 if (base.isPlayerVisible()) { 092 desc = "Pirate base in the " + base.getSystem().getNameWithLowercaseTypeShort() + ""; 093 } 094 ignoreDeal = true; 095 final int progress = getProgressForBase(base); 096 ignoreDeal = false; 097 String progressStr = "+" + progress; 098 if (progress < 0) progressStr = "" + progress; 099 Color descColor = getDescColor(intel); 100 Color progressColor = getProgressColor(intel); 101 102 //DEAL_PROVIDES_NEGATIVE_PROGRESS = true; 103 //DEAL_PROVIDES_NEGATIVE_PROGRESS = false; 104 105 if (base.playerHasDealWithBaseCommander()) { 106 if (DEAL_PROVIDES_NEGATIVE_PROGRESS) { 107 int p = getProgressForBase(base); 108 progressStr = "+" + p; 109 if (p < 0) progressStr = "" + p; 110 descColor = Misc.getTextColor(); 111 } else { 112 progressStr = EventFactor.NEGATED_FACTOR_PROGRESS; 113 descColor = Misc.getGrayColor(); 114 } 115 progressColor = Misc.getPositiveHighlightColor(); 116 } else { 117 if (DEAL_PROVIDES_NEGATIVE_PROGRESS) { 118 descColor = Misc.getTextColor(); 119 } 120 } 121 122 info.addRowWithGlow(Alignment.LMID, descColor, " " + desc, 123 Alignment.RMID, progressColor, progressStr); 124 125 TooltipCreator t = new BaseFactorTooltip() { 126 @Override 127 public void createTooltip(TooltipMakerAPI tooltip, boolean expanded, Object tooltipParam) { 128 float opad = 10f; 129 130 String aStr = Misc.getAndJoined(affected); 131 String systems = "systems"; 132 if (affected.size() == 1) systems = "system"; 133 134 MapParams params = new MapParams(); 135 for (StarSystemAPI curr : getSystemsAffectedBy(base)) { 136 params.showSystem(curr); 137 } 138 if (base.playerHasDealWithBaseCommander() || base.isPlayerVisible()) { 139 params.showMarket(base.getMarket(), 1f); 140// params.arrows = new ArrayList<ArrowData>(); 141// for (StarSystemAPI curr : getSystemsAffectedBy(base)) { 142// if (curr != base.getEntity().getContainingLocation()) { 143// ArrowData arr = new ArrowData(base.getEntity(), curr.getHyperspaceAnchor()); 144// arr.color = Global.getSector().getFaction(Factions.PIRATES).getBrightUIColor(); 145// params.arrows.add(arr); 146// } 147// } 148 } 149 float w = tooltip.getWidthSoFar(); 150 float h = Math.round(w / 1.6f); 151 params.positionToShowAllMarkersAndSystems(true, Math.min(w, h)); 152 153 //UIPanelAPI map = tooltip.createSectorMap(w, h, params, aStr + " " + Misc.ucFirst(systems)); 154 UIPanelAPI map = tooltip.createSectorMap(w, h, params, aStr + " " + systems); 155 156 if (base.playerHasDealWithBaseCommander()) { 157 String systemStr = "in the " + base.getSystem().getNameWithLowercaseTypeShort() + ""; 158 tooltip.addPara("Your " + colonies + " in the " + aStr + " " + systems + 159 " " + isOrAre + " within range of a pirate base located " + systemStr + ". " + 160 "You have an agreement with " 161 + "the base commander, and fleets from this base do not, as a rule, " 162 + "harass your colonies or shipping.", 0f, 163 Misc.getPositiveHighlightColor(), "agreement"); 164 165 int payment = HA_CMD.computePirateProtectionPaymentPerMonth(base); 166 String extra = ""; 167 if (DEAL_PROVIDES_NEGATIVE_PROGRESS) { 168 extra = " instead of providing a reduction in progress"; 169 } 170 tooltip.addPara("Assuming current colony income levels, this agreement costs " 171 + "you %s per month. If it was not in effect, " 172 + "this base would contribute %s points of event progress per month" + extra + ".", opad, 173 Misc.getHighlightColor(), 174 Misc.getDGSCredits(payment), "" + progress); 175 176 } else { 177 String systemStr = "in a nearby system"; 178 if (base.isPlayerVisible()) { 179 systemStr = "in the " + base.getSystem().getNameWithLowercaseTypeShort() + ""; 180 } 181 tooltip.addPara("Your " + colonies + " in the " + aStr + " " + systems + 182 " " + isOrAre + " within range of a pirate base located " + systemStr + ". " + 183 "This results in a greater volume of pirate " 184 + "fleets preying on trade. %s should address this.", 0f, 185 Misc.getHighlightColor(), "Dealing with the base"); 186 } 187 188 tooltip.addCustom(map, opad); 189 } 190 }; 191 info.addTooltipToAddedRow(t, TooltipLocation.RIGHT, false); 192 } 193 } 194 195 public boolean playerHasDealWithAnyBases() { 196 for (IntelInfoPlugin intel : Global.getSector().getIntelManager().getIntel(PirateBaseIntel.class)) { 197 PirateBaseIntel curr = (PirateBaseIntel) intel; 198 if (curr.playerHasDealWithBaseCommander()) { 199 return true; 200 } 201 } 202 return false; 203 } 204 205 @Override 206 public boolean shouldShow() { 207 return getProgress() != 0 || playerHasDealWithAnyBases(); 208 } 209 210 public int getProgress() { 211 if (PirateHostileActivityFactor.isDefeatedLargePirateRaid()) return 0; 212 213 int total = 0; 214 for (IntelInfoPlugin intel : Global.getSector().getIntelManager().getIntel(PirateBaseIntel.class)) { 215 PirateBaseIntel curr = (PirateBaseIntel) intel; 216 total += getProgressForBase(curr); 217 } 218 return total; 219 } 220 221 222 protected int getProgressForBase(PirateBaseIntel base) { 223 if (!DEAL_PROVIDES_NEGATIVE_PROGRESS) { 224 if (!ignoreDeal && base.playerHasDealWithBaseCommander()) { 225 return 0; 226 } 227 } 228 229 boolean ignore = ignoreDeal; 230 231 if (!ignore && DEAL_PROVIDES_NEGATIVE_PROGRESS) { 232 ignoreDeal = true; 233 } 234 int total = 0; 235 for (StarSystemAPI system : getSystemsAffectedBy(base)) { 236 total += getProgressForSystem(system); 237 } 238 239 if (!ignore && DEAL_PROVIDES_NEGATIVE_PROGRESS) { 240 ignoreDeal = false; 241 } 242 243 if (DEAL_PROVIDES_NEGATIVE_PROGRESS) { 244 if (!ignoreDeal && base.playerHasDealWithBaseCommander()) { 245 total *= -1; 246 } 247 } 248 249 return total; 250 } 251 252 protected int getProgressForSystem(StarSystemAPI system) { 253 float mag = getMagnitudeContribution(system); 254 if (mag <= 0) return 0; 255 mag /= MAX_MAG; 256 if (mag > 1f) mag = 1f; 257 Range r = new Range("pirateBaseProximityPoints"); 258 return r.interpInt(mag); 259// int progress = 3 + (int) Math.round(mag * 7f); 260// return progress; 261 } 262 263 264 public String getDesc() { 265 return null; 266 } 267// protected float getMaxMag() { 268// float max = 0f; 269// for (final StarSystemAPI system : Misc.getSystemsWithPlayerColonies(false)) { 270// float mag = getMagnitudeContribution(system); 271// if (mag > max) { 272// max = mag; 273// } 274// } 275// return max; 276// } 277 278 279 public float getMagnitudeContribution(StarSystemAPI system) { 280 if (EconomyFleetRouteManager.ENEMY_STRENGTH_CHECK_EXCLUDE_PIRATES) { 281 return 0f; 282 } 283 284 List<MarketAPI> markets = Misc.getMarketsInLocation(system, Factions.PLAYER); 285 float maxSize = 0f; 286 for (MarketAPI market : markets) { 287 maxSize = Math.max(maxSize, market.getSize()); 288 } 289 290 PirateBaseIntel base = getBaseIntel(system); 291 float mag = SlipstreamPirateEPEC.getPirateBaseProximityFactor(base, system.getLocation()); 292 //mag = 0.95f; 293 mag *= 0.5f; 294 mag *= maxSize / 6f; 295 if (base != null) { 296 mag *= (float)(base.getTier().ordinal() + 1f) / 5f; 297 } 298 if (mag > MAX_MAG) mag = MAX_MAG; 299 300 mag = Math.round(mag * 100f) / 100f; 301 302 if (base != null && base.playerHasDealWithBaseCommander() && !ignoreDeal) { 303 mag = 0f; 304 } 305 306 return mag; 307 } 308 309 310} 311 312