001package com.fs.starfarer.api.impl.campaign.intel.events.ttcr; 002 003import java.awt.Color; 004import java.util.EnumSet; 005import java.util.Random; 006import java.util.Set; 007 008import org.lwjgl.util.vector.Vector2f; 009 010import com.fs.starfarer.api.Global; 011import com.fs.starfarer.api.campaign.FactionAPI; 012import com.fs.starfarer.api.campaign.InteractionDialogAPI; 013import com.fs.starfarer.api.campaign.TextPanelAPI; 014import com.fs.starfarer.api.impl.campaign.ids.Factions; 015import com.fs.starfarer.api.impl.campaign.ids.FleetTypes; 016import com.fs.starfarer.api.impl.campaign.ids.Skills; 017import com.fs.starfarer.api.impl.campaign.ids.Tags; 018import com.fs.starfarer.api.impl.campaign.intel.events.BaseEventIntel; 019import com.fs.starfarer.api.impl.campaign.intel.events.BaseFactorTooltip; 020import com.fs.starfarer.api.impl.campaign.intel.events.EventFactor; 021import com.fs.starfarer.api.impl.campaign.intel.events.TriTachyonHostileActivityFactor; 022import com.fs.starfarer.api.impl.campaign.missions.DelayedFleetEncounter; 023import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.FleetQuality; 024import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.FleetSize; 025import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.OfficerNum; 026import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.OfficerQuality; 027import com.fs.starfarer.api.ui.LabelAPI; 028import com.fs.starfarer.api.ui.SectorMapAPI; 029import com.fs.starfarer.api.ui.TooltipMakerAPI; 030import com.fs.starfarer.api.ui.TooltipMakerAPI.TooltipCreator; 031import com.fs.starfarer.api.util.Misc; 032import com.fs.starfarer.api.util.WeightedRandomPicker; 033 034public class TriTachyonCommerceRaiding extends BaseEventIntel { 035 036 public static int PROGRESS_MAX = 300; 037 public static int PROGRESS_1 = 150; 038 039 public static String KEY = "$ttcr_ref"; 040 041 public static enum Stage { 042 START, 043 SEND_MERC, 044 SUCCESS, 045 } 046 047 048 public static void addFactorCreateIfNecessary(EventFactor factor, InteractionDialogAPI dialog) { 049 if (get() == null) { 050 new TriTachyonCommerceRaiding(null, false); 051 } 052 if (get() != null) { 053 get().addFactor(factor, dialog); 054 } 055 } 056 057 public static TriTachyonCommerceRaiding get() { 058 return (TriTachyonCommerceRaiding) Global.getSector().getMemoryWithoutUpdate().get(KEY); 059 } 060 061 062 public TriTachyonCommerceRaiding(TextPanelAPI text, boolean withIntelNotification) { 063 super(); 064 065 Global.getSector().getMemoryWithoutUpdate().set(KEY, this); 066 067 setup(); 068 069 // now that the event is fully constructed, add it and send notification 070 Global.getSector().getIntelManager().addIntel(this, !withIntelNotification, text); 071 } 072 073 protected void setup() { 074 factors.clear(); 075 stages.clear(); 076 077 setMaxProgress(PROGRESS_MAX); 078 079 addStage(Stage.START, 0); 080 addStage(Stage.SEND_MERC, PROGRESS_1, true, StageIconSize.MEDIUM); 081 addStage(Stage.SUCCESS, PROGRESS_MAX, true, StageIconSize.LARGE); 082 083 // not actualy repeatable since no way to reduce progress 084 // but this will keep the icon and the stage description showing 085 //getDataFor(Stage.SEND_MERC).isRepeatable = false; 086 087 addFactor(new TTCRCommerceRaidersDestroyedFactorHint()); 088 addFactor(new TTCRTradeFleetsDestroyedFactorHint()); 089 addFactor(new TTCRIndustryDisruptedFactorHint()); 090 091 } 092 093 protected Object readResolve() { 094 return this; 095 } 096 097 098 @Override 099 protected void notifyEnding() { 100 super.notifyEnding(); 101 } 102 103 @Override 104 protected void notifyEnded() { 105 super.notifyEnded(); 106 Global.getSector().getMemoryWithoutUpdate().unset(KEY); 107 } 108 109 protected void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode, boolean isUpdate, 110 Color tc, float initPad) { 111 112 if (addEventFactorBulletPoints(info, mode, isUpdate, tc, initPad)) { 113 return; 114 } 115 116 Color h = Misc.getHighlightColor(); 117 if (isUpdate && getListInfoParam() instanceof EventStageData) { 118 EventStageData esd = (EventStageData) getListInfoParam(); 119 if (esd.id == Stage.SEND_MERC) { 120 info.addPara("Several bounty hunters were recently hired to eliminate you", tc, initPad); 121 } 122 if (esd.id == Stage.SUCCESS) { 123 info.addPara("You've convincied Tri-Tachyon to stop attacking your interests", tc, initPad); 124 } 125 return; 126 } 127 128 } 129 130 @Override 131 public void addStageDescriptionText(TooltipMakerAPI info, float width, Object stageId) { 132 float opad = 10f; 133 float small = 0f; 134 Color h = Misc.getHighlightColor(); 135 136 //setProgress(0); 137 //setProgress(199); 138 //setProgress(600); 139 //setProgress(899); 140 //setProgress(1000); 141 //setProgress(499); 142 //setProgress(600); 143 144 EventStageData stage = getDataFor(stageId); 145 if (stage == null) return; 146 147 if (isStageActive(stageId)) { 148 addStageDesc(info, stageId, small, false); 149 } 150 } 151 152 public FactionAPI getFaction() { 153 return Global.getSector().getFaction(Factions.TRITACHYON); 154 } 155 156 157 public void addStageDesc(TooltipMakerAPI info, Object stageId, float initPad, boolean forTooltip) { 158 float opad = 10f; 159 Color h = Misc.getHighlightColor(); 160 161 FactionAPI faction = getFaction(); 162 Color tt = faction.getBaseUIColor(); 163 164 if (stageId == Stage.START) { 165 LabelAPI label = info.addPara("The %s needs to be convinced that continued investment in " 166 + "acting against your interests is unprofitable in the long term. If you are " 167 + "able to send this message without becoming openly hostile - or smooth any ruffled feathers " 168 + "afterwards - this may even " 169 + "mark you as someone whose understanding of business realities makes them worth working with.", 170 initPad, tt, faction.getDisplayNameLong()); 171 label.setHighlight(faction.getDisplayNameLong(), "worth working with"); 172 label.setHighlightColors(tt, 173 Misc.getPositiveHighlightColor()); 174 } else if (stageId == Stage.SUCCESS) { 175 info.addPara("You've convinced the %s to stop attacking your interests.", initPad, 176 tt, faction.getDisplayNameLong()); 177 } else if (stageId == Stage.SEND_MERC) { 178 info.addPara("Several bounty hunters were recently hired to eliminate you. You are likely " 179 + "to encounter them in the coming months. Resolving the matter with Tri-Tachyon before then " 180 + "is unlikely to make a difference in this; a contract is a contract.", initPad); 181 } 182 } 183 184 public TooltipCreator getStageTooltipImpl(Object stageId) { 185 final EventStageData esd = getDataFor(stageId); 186 187 if (esd != null && EnumSet.of(Stage.SEND_MERC, Stage.SUCCESS).contains(esd.id)) { 188 return new BaseFactorTooltip() { 189 @Override 190 public void createTooltip(TooltipMakerAPI tooltip, boolean expanded, Object tooltipParam) { 191 float opad = 10f; 192 193 if (esd.id == Stage.SEND_MERC) { 194 tooltip.addTitle("Bounty posted"); 195 } else if (esd.id == Stage.SUCCESS) { 196 tooltip.addTitle("Success!"); 197 } 198 199 addStageDesc(tooltip, esd.id, opad, true); 200 201 esd.addProgressReq(tooltip, opad); 202 } 203 }; 204 } 205 206 return null; 207 } 208 209 210 211 @Override 212 public String getIcon() { 213 return Global.getSettings().getSpriteName("events", "triTachyonCR_START"); 214 } 215 216 protected String getStageIconImpl(Object stageId) { 217 EventStageData esd = getDataFor(stageId); 218 if (esd == null) return null; 219 220 return Global.getSettings().getSpriteName("events", "triTachyonCR_" + ((Stage)esd.id).name()); 221 } 222 223 224 @Override 225 public Set<String> getIntelTags(SectorMapAPI map) { 226 Set<String> tags = super.getIntelTags(map); 227 tags.add(Tags.INTEL_COLONIES); 228 tags.add(Factions.TRITACHYON); 229 return tags; 230 } 231 232 @Override 233 public Color getBarColor() { 234 Color color = getFaction().getBaseUIColor(); 235 color = Misc.interpolateColor(color, Color.black, 0.25f); 236 return color; 237 } 238 239 @Override 240 public Color getBarProgressIndicatorColor() { 241 return super.getBarProgressIndicatorColor(); 242 } 243 244 @Override 245 protected int getStageImportance(Object stageId) { 246 return super.getStageImportance(stageId); 247 } 248 249 250 @Override 251 protected String getName() { 252 return "Tri-Tachyon Commerce Raiding"; 253 } 254 255 256 257 @Override 258 protected void advanceImpl(float amount) { 259 super.advanceImpl(amount); 260 261 //setProgress(500); 262 //float days = Global.getSector().getClock().convertToDays(amount); 263 } 264 265 266 @Override 267 protected void notifyStageReached(EventStageData stage) { 268 //applyFleetEffects(); 269 270 if (stage.id == Stage.SEND_MERC) { 271 sendBountyHunters(); 272 } 273 274 if (stage.id == Stage.SUCCESS) { 275 TriTachyonHostileActivityFactor.setPlayerCounterRaidedTriTach(); 276 endAfterDelay(); 277 } 278 } 279 280 public boolean withMonthlyFactors() { 281 return false; 282 } 283 284 protected String getSoundForStageReachedUpdate(Object stageId) { 285// if (stageId == Stage.SEND_MERC) { 286// return "ui_learned_ability"; 287// } 288 return super.getSoundForStageReachedUpdate(stageId); 289 } 290 291 @Override 292 protected String getSoundForOneTimeFactorUpdate(EventFactor factor) { 293 return null; 294 } 295 296 protected void sendBountyHunters() { 297 // wolfpack 298 { 299 Random r = Misc.getRandom(random.nextLong(), 7); 300 DelayedFleetEncounter e = new DelayedFleetEncounter(r, "TTCRBountyHunterWolfpack"); 301 e.setDelayVeryShort(); 302 //e.setDelayNone(); 303 e.setDoNotAbortWhenPlayerFleetTooStrong(); // small ships, few FP, but a strong fleet 304 e.setLocationOuterSector(true, Factions.INDEPENDENT); 305 e.beginCreate(); 306 e.triggerCreateFleet(FleetSize.LARGE, FleetQuality.SMOD_3, Factions.MERCENARY, FleetTypes.MERC_BOUNTY_HUNTER, new Vector2f()); 307 e.triggerSetFleetMaxShipSize(1); 308 e.triggerSetFleetDoctrineOther(5, 4); 309 310 311 WeightedRandomPicker<String> picker = new WeightedRandomPicker<String>(r); 312 picker.add("tempest_Attack", 10); 313 picker.add("tempest_Attack", 10); 314 picker.add("tempest_Attack", 10); 315 picker.add("scarab_Experimental", 10); 316 picker.add("scarab_Experimental", 10); 317 picker.add("scarab_Experimental", 10); 318 picker.add("hyperion_Attack", 10); 319 picker.add("hyperion_Strike", 10); 320 picker.add("omen_PD", 5); 321 picker.add("omen_PD", 5); 322 picker.add("monitor_Escort", 5); 323 picker.add("monitor_Escort", 5); 324 picker.add("shade_Assault", 5); 325 picker.add("shade_Assault", 5); 326 picker.add("afflictor_Strike", 5); 327 picker.add("afflictor_Strike", 5); 328 329// for (ShipHullSpecAPI spec : Global.getSettings().getAllShipHullSpecs()) { 330// if (spec.hasTag("merc") && spec.hasTag("wolfpack")) { 331// List<String> variants = Global.getSettings().getHullIdToVariantListMap().get(spec.getHullId()); 332// for (String variantId : variants) { 333// ShipVariantAPI v = Global.getSettings().getVariant(variantId); 334// if (v.isGoalVariant() && v.isStockVariant()) { 335// picker.add(variantId); 336// } 337// } 338// } 339// } 340 341 int add = 9; 342 while (!picker.isEmpty() && add > 0) { 343 e.triggerAddShips(picker.pickAndRemove()); 344 add--; 345 } 346 347 348 349 e.triggerSetFleetMaxNumShips(14); 350 e.triggerSetFleetDoctrineComp(5, 0, 0); 351 352 e.triggerFleetAddCommanderSkill(Skills.COORDINATED_MANEUVERS, 1); 353 e.triggerFleetAddCommanderSkill(Skills.WOLFPACK_TACTICS, 1); 354 e.triggerFleetAddCommanderSkill(Skills.ELECTRONIC_WARFARE, 1); 355 e.triggerFleetAddCommanderSkill(Skills.FLUX_REGULATION, 1); 356 e.triggerFleetAddCommanderSkill(Skills.TACTICAL_DRILLS, 1); 357 e.triggerSetFleetOfficers(OfficerNum.MORE, OfficerQuality.UNUSUALLY_HIGH); 358 359 e.triggerFleetMakeFaster(true, 0, true); 360 361 e.triggerSetFleetFaction(Factions.INDEPENDENT); 362 e.triggerMakeNoRepImpact(); 363 e.triggerSetStandardAggroInterceptFlags(); 364 e.triggerMakeFleetIgnoreOtherFleets(); 365 e.triggerSetFleetGenericHailPermanent("TTCRBountyHunterHail"); 366 e.triggerSetFleetFlagPermanent("$ttcr_wolfpack"); 367 e.endCreate(); 368 } 369 370 // phase 371 { 372 Random r = Misc.getRandom(random.nextLong(), 3); 373 DelayedFleetEncounter e = new DelayedFleetEncounter(r, "TTCRBountyHunterPhase"); 374 e.setDelayVeryShort(); 375 //e.setDelayNone(); 376 e.setLocationInnerSector(true, Factions.INDEPENDENT); 377 e.beginCreate(); 378 e.triggerCreateFleet(FleetSize.LARGE, FleetQuality.SMOD_3, Factions.MERCENARY, FleetTypes.MERC_BOUNTY_HUNTER, new Vector2f()); 379 380 e.triggerSetFleetDoctrineComp(0, 0, 5); 381 382 e.triggerFleetAddCommanderSkill(Skills.COORDINATED_MANEUVERS, 1); 383 e.triggerFleetAddCommanderSkill(Skills.PHASE_CORPS, 1); 384 e.triggerFleetAddCommanderSkill(Skills.ELECTRONIC_WARFARE, 1); 385 e.triggerFleetAddCommanderSkill(Skills.FLUX_REGULATION, 1); 386 e.triggerFleetAddCommanderSkill(Skills.TACTICAL_DRILLS, 1); 387 e.triggerSetFleetOfficers(OfficerNum.MORE, OfficerQuality.HIGHER); 388 389 e.triggerFleetMakeFaster(true, 0, true); 390 391 e.triggerSetFleetFaction(Factions.INDEPENDENT); 392 e.triggerMakeNoRepImpact(); 393 e.triggerSetStandardAggroInterceptFlags(); 394 e.triggerMakeFleetIgnoreOtherFleets(); 395 e.triggerSetFleetGenericHailPermanent("TTCRBountyHunterHail"); 396 e.triggerSetFleetFlagPermanent("$ttcr_phase"); 397 e.endCreate(); 398 } 399 400 401 // derelict 402 { 403 Random r = Misc.getRandom(random.nextLong(), 11); 404 DelayedFleetEncounter e = new DelayedFleetEncounter(r, "TTCRBountyHunterDerelict"); 405 e.setDelayVeryShort(); 406 //e.setDelayNone(); 407 //e.setLocationCoreOnly(true, market.getFactionId()); 408 e.setLocationCoreOnly(true, Factions.INDEPENDENT); 409 e.beginCreate(); 410 e.triggerCreateFleet(FleetSize.HUGE, FleetQuality.VERY_LOW, Factions.LUDDIC_CHURCH, FleetTypes.MERC_BOUNTY_HUNTER, new Vector2f()); 411 412 //e.triggerSetFleetDoctrineComp(4, 2, 1); 413 e.triggerSetFleetDoctrineOther(5, 5); 414 415 e.triggerFleetAddCommanderSkill(Skills.DERELICT_CONTINGENT, 1); 416 e.triggerFleetAddCommanderSkill(Skills.SUPPORT_DOCTRINE, 1); 417 e.triggerFleetAddCommanderSkill(Skills.COORDINATED_MANEUVERS, 1); 418 e.triggerSetFleetOfficers(OfficerNum.MORE, OfficerQuality.LOWER); 419 420 e.triggerFleetMakeFaster(true, 2, true); 421 422 e.triggerSetFleetFaction(Factions.INDEPENDENT); 423 e.triggerMakeNoRepImpact(); 424 e.triggerSetStandardAggroInterceptFlags(); 425 e.triggerMakeFleetIgnoreOtherFleets(); 426 e.triggerSetFleetGenericHailPermanent("TTCRBountyHunterHail"); 427 e.triggerSetFleetFlagPermanent("$ttcr_derelict"); 428 e.endCreate(); 429 } 430 431 } 432 433} 434 435 436 437 438 439 440 441