001package com.fs.starfarer.api.impl.campaign.rulecmd;
002
003import java.util.ArrayList;
004import java.util.LinkedHashSet;
005import java.util.List;
006import java.util.Map;
007import java.util.Random;
008import java.util.Set;
009
010import org.lwjgl.util.vector.Vector2f;
011
012import com.fs.starfarer.api.EveryFrameScript;
013import com.fs.starfarer.api.Global;
014import com.fs.starfarer.api.campaign.BattleAPI;
015import com.fs.starfarer.api.campaign.CampaignEventListener.FleetDespawnReason;
016import com.fs.starfarer.api.campaign.CampaignFleetAPI;
017import com.fs.starfarer.api.campaign.CargoAPI;
018import com.fs.starfarer.api.campaign.FactionAPI;
019import com.fs.starfarer.api.campaign.FleetAssignment;
020import com.fs.starfarer.api.campaign.InteractionDialogAPI;
021import com.fs.starfarer.api.campaign.JumpPointAPI;
022import com.fs.starfarer.api.campaign.LocationAPI;
023import com.fs.starfarer.api.campaign.OptionPanelAPI;
024import com.fs.starfarer.api.campaign.RepLevel;
025import com.fs.starfarer.api.campaign.SectorEntityToken;
026import com.fs.starfarer.api.campaign.SectorEntityToken.VisibilityLevel;
027import com.fs.starfarer.api.campaign.SpecialItemData;
028import com.fs.starfarer.api.campaign.StarSystemAPI;
029import com.fs.starfarer.api.campaign.TextPanelAPI;
030import com.fs.starfarer.api.campaign.ai.ModularFleetAIAPI;
031import com.fs.starfarer.api.campaign.econ.Industry;
032import com.fs.starfarer.api.campaign.econ.MarketAPI;
033import com.fs.starfarer.api.campaign.econ.MonthlyReport;
034import com.fs.starfarer.api.campaign.econ.MonthlyReport.FDNode;
035import com.fs.starfarer.api.campaign.listeners.ColonyPlayerHostileActListener;
036import com.fs.starfarer.api.campaign.listeners.CurrentLocationChangedListener;
037import com.fs.starfarer.api.campaign.listeners.EconomyTickListener;
038import com.fs.starfarer.api.campaign.listeners.FleetEventListener;
039import com.fs.starfarer.api.campaign.rules.MemKeys;
040import com.fs.starfarer.api.campaign.rules.MemoryAPI;
041import com.fs.starfarer.api.impl.campaign.CargoPodsEntityPlugin;
042import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin;
043import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepRewards;
044import com.fs.starfarer.api.impl.campaign.ids.Conditions;
045import com.fs.starfarer.api.impl.campaign.ids.Entities;
046import com.fs.starfarer.api.impl.campaign.ids.Factions;
047import com.fs.starfarer.api.impl.campaign.ids.Industries;
048import com.fs.starfarer.api.impl.campaign.ids.Items;
049import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
050import com.fs.starfarer.api.impl.campaign.ids.Stats;
051import com.fs.starfarer.api.impl.campaign.intel.GensHannanMachinations;
052import com.fs.starfarer.api.impl.campaign.intel.LuddicChurchImmigrationDeal;
053import com.fs.starfarer.api.impl.campaign.intel.PerseanLeagueMembership;
054import com.fs.starfarer.api.impl.campaign.intel.PerseanLeagueMembership.AgreementEndingType;
055import com.fs.starfarer.api.impl.campaign.intel.SindrianDiktatFuelDeal;
056import com.fs.starfarer.api.impl.campaign.intel.TriTachyonDeal;
057import com.fs.starfarer.api.impl.campaign.intel.bases.LuddicPathBaseManager;
058import com.fs.starfarer.api.impl.campaign.intel.bases.PirateBaseIntel;
059import com.fs.starfarer.api.impl.campaign.intel.bases.PirateBaseIntel.PirateBaseTier;
060import com.fs.starfarer.api.impl.campaign.intel.events.EventFactor;
061import com.fs.starfarer.api.impl.campaign.intel.events.HALuddicPathDealFactor;
062import com.fs.starfarer.api.impl.campaign.intel.events.HAPirateKingDealFactor;
063import com.fs.starfarer.api.impl.campaign.intel.events.HegemonyHostileActivityFactor;
064import com.fs.starfarer.api.impl.campaign.intel.events.HostileActivityCause2;
065import com.fs.starfarer.api.impl.campaign.intel.events.HostileActivityEventIntel;
066import com.fs.starfarer.api.impl.campaign.intel.events.HostileActivityEventIntel.HAERandomEventData;
067import com.fs.starfarer.api.impl.campaign.intel.events.LuddicChurchHostileActivityFactor;
068import com.fs.starfarer.api.impl.campaign.intel.events.LuddicChurchStandardActivityCause;
069import com.fs.starfarer.api.impl.campaign.intel.events.LuddicPathHostileActivityFactor;
070import com.fs.starfarer.api.impl.campaign.intel.events.PerseanLeagueHostileActivityFactor;
071import com.fs.starfarer.api.impl.campaign.intel.events.PirateBasePirateActivityCause2;
072import com.fs.starfarer.api.impl.campaign.intel.events.SindrianDiktatHostileActivityFactor;
073import com.fs.starfarer.api.impl.campaign.intel.events.SindrianDiktatStandardActivityCause;
074import com.fs.starfarer.api.impl.campaign.intel.events.StandardPerseanLeagueActivityCause;
075import com.fs.starfarer.api.impl.campaign.intel.events.TriTachyonHostileActivityFactor;
076import com.fs.starfarer.api.impl.campaign.intel.events.ttcr.TriTachyonCommerceRaiding;
077import com.fs.starfarer.api.impl.campaign.intel.group.GenericRaidFGI.GenericRaidParams;
078import com.fs.starfarer.api.impl.campaign.intel.group.KnightsOfLuddTakeoverExpedition;
079import com.fs.starfarer.api.impl.campaign.intel.group.PerseanLeagueBlockade;
080import com.fs.starfarer.api.impl.campaign.intel.group.PerseanLeaguePunitiveExpedition;
081import com.fs.starfarer.api.impl.campaign.intel.group.SindrianDiktatPunitiveExpedition;
082import com.fs.starfarer.api.impl.campaign.intel.group.TTMercenaryAttack;
083import com.fs.starfarer.api.impl.campaign.intel.group.TTMercenaryReversedAttack;
084import com.fs.starfarer.api.impl.campaign.missions.FleetCreatorMission;
085import com.fs.starfarer.api.impl.campaign.missions.FleetCreatorMission.FleetStyle;
086import com.fs.starfarer.api.impl.campaign.missions.hub.MissionFleetAutoDespawn;
087import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator;
088import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.MarketCMD.TempData;
089import com.fs.starfarer.api.impl.campaign.shared.SharedData;
090import com.fs.starfarer.api.ui.TooltipMakerAPI;
091import com.fs.starfarer.api.ui.TooltipMakerAPI.TooltipCreator;
092import com.fs.starfarer.api.util.Misc;
093import com.fs.starfarer.api.util.Misc.FleetFilter;
094import com.fs.starfarer.api.util.Misc.Token;
095
096/**
097 * For hostile activity ("HA") related tasks.
098 * 
099 *      HA_CMD <action> <parameters>
100 */
101public class HA_CMD extends BaseCommandPlugin {
102
103        public static final String PATHER_AGREEMENT = "$patherAgreement";
104        public static final String PATHER_AGREEMENT_PERMANENT = "$patherAgreementPermanent";
105        
106        
107        public static void setPatherAgreement(boolean agreement, float duration) {
108                if (!agreement) {
109                        Global.getSector().getPlayerMemoryWithoutUpdate().unset(PATHER_AGREEMENT);
110                        Global.getSector().getPlayerMemoryWithoutUpdate().unset(PATHER_AGREEMENT_PERMANENT);
111                        return;
112                }
113                if (duration <= 0) {
114                        Global.getSector().getPlayerMemoryWithoutUpdate().set(PATHER_AGREEMENT_PERMANENT, true);
115                }
116                Global.getSector().getPlayerMemoryWithoutUpdate().set(PATHER_AGREEMENT, true, duration);
117        }
118        public static boolean playerHasPatherAgreement() {
119                //if (true) return true;
120                // second part is to make 0.96a-RC8 saves work now that the correct variable is being set
121                return Global.getSector().getPlayerMemoryWithoutUpdate().getBoolean(PATHER_AGREEMENT) ||
122                                Global.getSector().getMemoryWithoutUpdate().getBoolean(PATHER_AGREEMENT);
123        }
124        public static boolean playerPatherAgreementIsPermanent() {
125                //if (true) return true;
126                // second part is to make 0.96a-RC8 saves work now that the correct variable is being set
127                return Global.getSector().getPlayerMemoryWithoutUpdate().getBoolean(PATHER_AGREEMENT_PERMANENT) || 
128                                Global.getSector().getMemoryWithoutUpdate().getBoolean(PATHER_AGREEMENT_PERMANENT);
129        }
130        
131        public static float getPlayerPatherAgreementDays() {
132                return Global.getSector().getPlayerMemoryWithoutUpdate().getExpire(PATHER_AGREEMENT);
133        }
134
135        
136        public static int computePirateProtectionPaymentPerMonth(PirateBaseIntel intel) {
137                int perTick = computePirateProtectionPaymentPerTick(intel);
138                float numIter = Global.getSettings().getFloat("economyIterPerMonth");
139                return (int) (perTick * numIter);
140        }
141        
142        public static int computePirateProtectionPaymentPerTick(PirateBaseIntel intel) {
143                float numIter = Global.getSettings().getFloat("economyIterPerMonth");
144                float f = 1f / numIter;
145                
146                int payment = 0;
147                float feeFraction = Global.getSettings().getFloat("pirateProtectionPaymentFraction");
148                
149                for (MarketAPI market : PirateBasePirateActivityCause2.getColoniesAffectedBy(intel)) {
150                        //if (market.isHidden()) continue;
151                        //if (!Factions.DIKTAT.equals(market.getFaction().getId()) && !market.isPlayerOwned()) continue;
152                        if (!market.isPlayerOwned()) continue;
153                        
154                        payment += (int) (market.getGrossIncome() * f) * feeFraction;
155                }
156                
157                return payment;
158        }
159        
160        public static class StationKingScript implements EveryFrameScript, TooltipCreator, 
161                                                                                                         EconomyTickListener, 
162                                                                                                         FleetEventListener,
163                                                                                                         CurrentLocationChangedListener,
164                                                                                                         ColonyPlayerHostileActListener {
165
166                protected boolean done = false;
167                protected PirateBaseIntel intel;
168                protected Random random = new Random();
169                //protected IntervalUtil interval;
170                
171                protected float untilMercCheck = 0f;
172                protected float mercProbMult = 1f;
173                protected transient boolean spawnMerc = false;
174                
175                public StationKingScript(PirateBaseIntel intel) {
176                        this.intel = intel;
177                        Global.getSector().getListenerManager().addListener(this);
178                        //interval = new IntervalUtil(0.01f, maxInterval)
179                        resetMercCheckDelay();
180                }
181                
182                protected Object readResolve() {
183                        if (random == null) {
184                                random = new Random();
185                        }
186                        return this;
187                }
188                
189                protected void resetMercCheckDelay() {
190                        untilMercCheck = Global.getSettings().getFloatFromArray("pirateProtectionMercSpawnInterval", 0) +
191                                        (Global.getSettings().getFloatFromArray("pirateProtectionMercSpawnInterval", 1) - 
192                                        Global.getSettings().getFloatFromArray("pirateProtectionMercSpawnInterval", 0)) * Misc.random.nextFloat();                      
193                }
194                
195                protected void setDone() {
196                        done = true;
197                        Global.getSector().getListenerManager().removeListener(this);
198                }
199                
200                public boolean isDone() {
201                        return done;
202                }
203                public boolean runWhilePaused() {
204                        return false;
205                }
206
207                public void reportEconomyTick(int iterIndex) {
208                        MonthlyReport report = SharedData.getData().getCurrentReport();
209                        FDNode marketsNode = report.getNode(MonthlyReport.OUTPOSTS);
210                        
211                        int payment = computePirateProtectionPaymentPerTick(intel);
212                        if (payment <= 0) return;
213                        
214                        FDNode paymentNode = report.getNode(marketsNode, "pirate_payment"); 
215                        paymentNode.name = "Protection payment";
216                        //paymentNode.custom = MonthlyReport.EXPORTS;
217                        //paymentNode.mapEntity = market.getPrimaryEntity();
218                        paymentNode.upkeep += payment;
219                        paymentNode.tooltipCreator = this;
220                        paymentNode.mapEntity = intel.getEntity();
221                        
222                        paymentNode.icon = Global.getSettings().getSpriteName("income_report", "generic_expense");
223                        //paymentNode.icon = intel.getIcon();
224                        //}                     
225                }
226
227                public void reportEconomyMonthEnd() {
228                        
229                }
230                
231                public void createTooltip(TooltipMakerAPI tooltip, boolean expanded, Object tooltipParam) {
232                        float opad = 10f;
233                        tooltip.addSpacer(-10f);
234                        tooltip.addPara("Protection payment to the " + intel.getBaseCommander().getPost() + " of " +  
235                                                        intel.getEntity().getName() + ". The pirate base is located in the " + 
236                                                        intel.getSystem().getNameWithLowercaseTypeShort() + ".", opad);
237                }
238
239                public float getTooltipWidth(Object tooltipParam) {
240                        return 450;
241                }
242
243                public boolean isTooltipExpandable(Object tooltipParam) {
244                        return false;
245                }
246                
247                public void advance(float amount) {
248                        if (isDone()) return;
249
250                        if (intel.isEnded() || intel.isEnding()) {
251                                if (intel.playerHasDealWithBaseCommander()) {
252                                        // the "station destroyed by mercs (or whoever)" case
253                                        intel.setPlayerHasDealWithBaseCommander(false);
254                                }
255                                setDone();
256                                return;
257                        }
258                        
259                        
260                        if (intel.playerHasDealWithBaseCommander() && intel.getSystem().isCurrentLocation()) {
261                                CampaignFleetAPI station = Misc.getStationFleet(intel.getEntity());
262                                List<CampaignFleetAPI> fleets = new ArrayList<CampaignFleetAPI>(intel.getSystem().getFleets());
263                                fleets.add(station);
264                                for (CampaignFleetAPI fleet : fleets) {
265                                        MarketAPI source = Misc.getSourceMarket(fleet);
266                                        if (source == intel.getMarket() || fleet == station) {// &&
267                                                        //fleet.getMemoryWithoutUpdate().getBoolean(MemFlags.MEMORY_KEY_MAKE_NON_HOSTILE)) {
268                                                Misc.setFlagWithReason(fleet.getMemoryWithoutUpdate(),
269                                                                MemFlags.MEMORY_KEY_MAKE_NON_HOSTILE, "psk_deal", true, 0.1f);
270                                                fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_ALLOW_PLAYER_BATTLE_JOIN_TOFF, true, 0.1f);
271                                        }
272                                }
273                        }
274                        
275                        float days = Global.getSector().getClock().convertToDays(amount);
276                        untilMercCheck -= days;
277                        if (untilMercCheck < 0) untilMercCheck = 0;
278                        
279                        if (spawnMerc) {
280                                spawnMerc();
281                                spawnMerc = false;
282                        }
283                }
284
285                public void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param) {
286                }
287
288                public void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle) {
289                        if (!battle.isPlayerInvolved()) return;
290                        
291                        CampaignFleetAPI station = Misc.getStationFleet(intel.getEntity());
292                        if (station == null) return;
293                        if (intel.getEntity() == null) return;
294                        LocationAPI cLoc = null;
295                        if (fleet != null) cLoc = fleet.getContainingLocation();
296                        if (cLoc == null && primaryWinner != null) cLoc = primaryWinner.getContainingLocation();
297                        if (intel.getEntity().getContainingLocation() != cLoc) {
298                                return;
299                        }
300                        
301                        for (CampaignFleetAPI curr : battle.getNonPlayerSideSnapshot()) {
302                                if (!curr.knowsWhoPlayerIs() && curr != station) continue;
303                                
304                                MarketAPI source = Misc.getSourceMarket(curr);
305                                
306                                if (source == intel.getMarket() || curr == station) {
307                                        endDeal(false, null);
308                                        return;
309                                }
310                        }
311                }
312                
313                public void reportRaidForValuablesFinishedBeforeCargoShown(InteractionDialogAPI dialog, MarketAPI market, TempData actionData, CargoAPI cargo) {
314                        if (market == intel.getMarket() && !actionData.secret && !cargo.isEmpty()) {
315                                endDeal(false, dialog);
316                        }
317                }
318
319                public void reportRaidToDisruptFinished(InteractionDialogAPI dialog, MarketAPI market, TempData actionData, Industry industry) {
320                        if (market == intel.getMarket() && !actionData.secret) {
321                                endDeal(false, dialog);
322                        }
323                }
324
325                public void reportTacticalBombardmentFinished(InteractionDialogAPI dialog, MarketAPI market, TempData actionData) {
326                        if (market == intel.getMarket() && !actionData.secret) {
327                                endDeal(false, dialog);
328                        }
329                }
330
331                public void reportSaturationBombardmentFinished(InteractionDialogAPI dialog, MarketAPI market, TempData actionData) {
332                        if (market == intel.getMarket() && !actionData.secret) {
333                                endDeal(false, dialog);
334                        }
335                }
336                
337                public void endDeal(boolean amicable, InteractionDialogAPI dialog) {
338                        if (!intel.playerHasDealWithBaseCommander()) return;
339                        
340                        TextPanelAPI textPanel = dialog == null ? null : dialog.getTextPanel();
341                        
342                        intel.setPlayerHasDealWithBaseCommander(false);
343                        
344                        if (amicable) {
345                                intel.sendUpdateIfPlayerHasIntel(PirateBaseIntel.DEAL_CANCELLED_PARAM, textPanel);
346                        } else {
347                                intel.sendUpdateIfPlayerHasIntel(PirateBaseIntel.DEAL_BROKEN_PARAM, textPanel);
348                        }
349                        
350                        if (!amicable) {
351                                Misc.incrUntrustwortyCount();
352                        }
353                        
354                        if (amicable) {
355                                Misc.adjustRep(intel.getBaseCommander(), -(RepRewards.HIGH + 0.01f), textPanel);
356                                Misc.adjustRep(intel.getBaseCommander().getFaction().getId(), -(RepRewards.MEDIUM + 0.01f), textPanel);
357                        } else {
358                                Misc.adjustRep(intel.getBaseCommander(), -(RepRewards.HIGH * 2f), textPanel);
359                                Misc.adjustRep(intel.getBaseCommander().getFaction().getId(), -(RepRewards.MEDIUM * 2f), textPanel);
360                        }
361                        
362                        
363                        CampaignFleetAPI station = Misc.getStationFleet(intel.getEntity());
364                        List<CampaignFleetAPI> fleets = new ArrayList<CampaignFleetAPI>(intel.getSystem().getFleets());
365                        fleets.add(station);
366                        for (CampaignFleetAPI fleet : fleets) {
367                                MarketAPI source = Misc.getSourceMarket(fleet);
368                                if (source == intel.getMarket() || fleet == station) {// &&
369                                                //fleet.getMemoryWithoutUpdate().getBoolean(MemFlags.MEMORY_KEY_MAKE_NON_HOSTILE)) {
370                                        Misc.setFlagWithReason(fleet.getMemoryWithoutUpdate(),
371                                                        MemFlags.MEMORY_KEY_MAKE_NON_HOSTILE, "psk_deal", false, 0);
372                                        fleet.getMemoryWithoutUpdate().unset(MemFlags.MEMORY_KEY_ALLOW_PLAYER_BATTLE_JOIN_TOFF);
373                                }
374                        }
375                        
376                        setDone();
377                }
378
379                public void reportCurrentLocationChanged(LocationAPI prev, LocationAPI curr) {
380                        if (curr == intel.getSystem()) {
381                                float prob = Global.getSettings().getFloat("pirateProtectionMercSpawnChance");
382                                prob *= mercProbMult;
383                                
384                                // uhcomment to spawn merc whenever the player enters the system with the base
385//                              untilMercCheck = 0f;
386//                              prob = 1f;
387                                
388                                if (untilMercCheck <= 0 && random.nextFloat() < prob) {
389                                        mercProbMult *= Global.getSettings().getFloat("pirateProtectionMercSpawnChanceMult");
390                                        spawnMerc = true;
391                                        resetMercCheckDelay();
392                                }
393                        }
394                }
395                
396                public void spawnMerc() {
397                        
398                        CampaignFleetAPI pf = Global.getSector().getPlayerFleet();
399                        
400                        JumpPointAPI jp = Misc.findNearestJumpPointTo(pf);
401                        float dist = Misc.getDistance(pf, jp);
402                        if (dist > 500f) {
403                                return;
404                        }
405                        
406                        float f = 10f;
407                        StarSystemAPI system = intel.getSystem();
408                        int difficulty = 0;
409                        
410                        
411                        PirateBaseTier tier = intel.getTier();
412                        switch (tier) {
413                        case TIER_1_1MODULE: difficulty = 3; break;
414                        case TIER_2_1MODULE: difficulty = 4; break;
415                        case TIER_3_2MODULE: difficulty = 5; break;
416                        case TIER_4_3MODULE: difficulty = 6; break;
417                        case TIER_5_3MODULE: difficulty = 7; break;
418                        }
419                        difficulty += random.nextInt(3);
420                        
421                        
422                        FleetCreatorMission m = new FleetCreatorMission(random);
423                        m.beginFleet();
424                        
425                        Vector2f hLoc = system.getLocation();
426                        m.createQualityFleet(difficulty, Factions.MERCENARY, hLoc);
427                        //m.triggerFleetAllowLongPursuit();
428                        m.triggerSetFleetFaction(Factions.INDEPENDENT);
429                        m.triggerMakeLowRepImpact();
430                        m.triggerFleetSetAllWeapons();
431                        m.triggerFleetMakeImportantPermanent(null);
432                        m.triggerSetFleetMemoryValue("$psk_merc", true);
433
434                        CampaignFleetAPI fleet = m.createFleet();
435                        if (fleet != null) {
436                                
437                                system.addEntity(fleet);
438                                
439                                Vector2f loc = new Vector2f(pf.getLocation());
440                                loc = Misc.getPointAtRadius(loc, 400f);
441                                fleet.setLocation(loc.x, loc.y);
442                                SectorEntityToken e = system.createToken(loc);
443                                fleet.addAssignment(FleetAssignment.ORBIT_AGGRESSIVE, e, 2f + 3f * random.nextFloat(), "preparing to attack " + intel.getEntity().getName());
444                                //CampaignFleetAPI station = Misc.getStationFleet(intel.getEntity()); 
445                                fleet.addAssignment(FleetAssignment.GO_TO_LOCATION, intel.getEntity(), 20f, "moving to attack " + intel.getEntity().getName());
446                                //Misc.giveStandardReturnToSourceAssignments(fleet, false);
447                                fleet.addScript(new MissionFleetAutoDespawn(null, fleet));
448                                
449                                fleet.addAssignmentAtStart(FleetAssignment.INTERCEPT, pf, 1f, null);
450                                
451                        }
452                        
453                }
454        }
455
456        protected SectorEntityToken other;
457        
458        public boolean execute(String ruleId, InteractionDialogAPI dialog, List<Token> params, Map<String, MemoryAPI> memoryMap) {
459                if (dialog == null) return false;
460                
461                OptionPanelAPI options = dialog.getOptionPanel();
462                TextPanelAPI text = dialog.getTextPanel();
463                CampaignFleetAPI pf = Global.getSector().getPlayerFleet();
464                other = dialog.getInteractionTarget();
465                CargoAPI cargo = pf.getCargo();
466                
467                
468                String action = params.get(0).getString(memoryMap);
469                
470                MemoryAPI memory = memoryMap.get(MemKeys.LOCAL);
471                if (memory == null) return false; // should not be possible unless there are other big problems already
472                
473                
474                //MarketAPI market = dialog.getInteractionTarget().getMarket();
475                StarSystemAPI system = null;
476                if (dialog.getInteractionTarget().getContainingLocation() instanceof StarSystemAPI) {
477                        system = (StarSystemAPI) dialog.getInteractionTarget().getContainingLocation();
478                }
479                                
480                if ("baseInvolved".equals(action)) {
481                        if (system == null) return false;
482                        PirateBaseIntel base = PirateBaseIntel.getIntelFor(dialog.getInteractionTarget());
483                        if (base == null) return false;
484                        
485                        return baseInvolved(system, base);
486                } else if ("addStationKingScript".equals(action)) {
487                        Global.getSoundPlayer().playUISound("ui_rep_raise", 1f, 1f);
488                        PirateBaseIntel base = PirateBaseIntel.getIntelFor(dialog.getInteractionTarget());
489                        if (base == null) return false;
490                        base.getSystem().addScript(new StationKingScript(base));
491                        
492                        // feels extraneous given the below also sending an update
493                        //base.sendUpdate(PirateBaseIntel.DEAL_MADE_PARAM, text);
494                        
495                        HostileActivityEventIntel ha = HostileActivityEventIntel.get();
496                        if (ha != null) {
497                                int tier = base.getTier().ordinal();
498                                if (tier < 0) tier = 0;
499                                if (tier > 4) tier = 4;
500                                int points = -1 * Global.getSettings().getIntFromArray("HA_pirateBase", tier);
501                                HAPirateKingDealFactor factor = new HAPirateKingDealFactor(points);
502                                ha.addFactor(factor, dialog);
503                        }
504                        
505                        Misc.adjustRep(base.getBaseCommander(), RepRewards.HIGH, text);
506                        Misc.adjustRep(base.getBaseCommander().getFaction().getId(), RepRewards.MEDIUM, text);
507                } else if ("endStationKingDeal".equals(action)) {
508                        PirateBaseIntel base = PirateBaseIntel.getIntelFor(dialog.getInteractionTarget());
509                        if (base == null) return false;
510                        for (EveryFrameScript curr : base.getSystem().getScripts()) {
511                                if (curr instanceof StationKingScript) {
512                                        StationKingScript script = (StationKingScript) curr;
513                                        script.endDeal(true, dialog);
514                                        return true;
515                                }
516                        }
517                        return false;
518                } else if ("playerColoniesHavePatherActvity".equals(action)) {
519                        for (MarketAPI market : Misc.getPlayerMarkets(false)) {
520                                float interest = LuddicPathBaseManager.getLuddicPathMarketInterest(market);
521                                if (market.hasCondition(Conditions.PATHER_CELLS) && interest > 0) {
522                                        return true;
523                                }
524                        }
525//                      for (IntelInfoPlugin intel : Global.getSector().getIntelManager().getIntel(HostileActivityIntel.class)) {
526//                              HostileActivityIntel curr = (HostileActivityIntel) intel;
527//                              HostileActivityPlugin a = curr.getActivityOfClass(LuddicPathHostileActivityPluginImpl.class);
528//                              if (a != null && a.getEffectMagnitude() > 0f) {
529//                                      return true;
530//                              }
531//                      }
532                } else if ("payMegaTithe".equals(action)) {
533                        int megaTithe = memory.getInt("$LP_megaTithe");
534                        int dur = memory.getInt("$LP_megaTitheDuration"); 
535                        cargo.getCredits().subtract(megaTithe);
536                        AddRemoveCommodity.addCreditsLossText(megaTithe, text);
537                        if (cargo.getCredits().get() <= 0) {
538                                cargo.getCredits().set(0);
539                        }
540                        setPatherAgreement(true, dur);
541                        LuddicPathHostileActivityFactor.avertOrAbortAttack();
542                        
543                        final String factionId = Factions.LUDDIC_PATH;
544                        float range = 100000f;
545                        List<CampaignFleetAPI> fleets = Misc.findNearbyFleets(pf, range, new FleetFilter() {
546                                public boolean accept(CampaignFleetAPI curr) {
547                                        return curr.getFaction().getId().equals(factionId);
548                                }
549                        });
550                        
551                        for (CampaignFleetAPI curr : fleets) {
552                                if (curr.getAI() != null) {
553                                        curr.getAI().setActionTextOverride(null);
554                                }
555                                if (curr.getAI() instanceof ModularFleetAIAPI) {
556                                        ModularFleetAIAPI mAI = (ModularFleetAIAPI) curr.getAI();
557                                        mAI.getTacticalModule().forceTargetReEval();
558                                }
559                                Misc.giveStandardReturnToSourceAssignments(curr, true);
560                        }
561                        
562                        HostileActivityEventIntel ha = HostileActivityEventIntel.get();
563                        if (ha != null) {
564                                int points = -1 * Global.getSettings().getInt("HA_megaTithe");
565                                HALuddicPathDealFactor factor = new HALuddicPathDealFactor(points);
566                                ha.addFactor(factor, dialog);
567                        }
568                        
569                        return true;
570                } else if ("gavePKToPather".equals(action)) {
571                        HostileActivityEventIntel ha = HostileActivityEventIntel.get();
572                        if (ha != null) {
573                                int points = -1 * Global.getSettings().getInt("HA_givePK");
574                                HALuddicPathDealFactor factor = new HALuddicPathDealFactor(points);
575                                ha.addFactor(factor, dialog);
576                        }
577                        LuddicPathHostileActivityFactor.avertOrAbortAttack();
578                } else if ("computeMegaTithe".equals(action)) {
579                        float credits = cargo.getCredits().get();
580                        
581                        float normalTithe = (int) Global.getSector().getPlayerFleet().getFleetPoints() * 200;
582                        
583                        int tithe = 0;
584                        
585                        float tithePerPointPerColonySize = Global.getSettings().getFloat("luddicPathTithePerPointOfInterestPerColonySize");
586                        int titheDuration = Global.getSettings().getInt("luddicPathTitheDurationDays");
587                        
588                        for (MarketAPI market : Misc.getPlayerMarkets(false)) {
589                                float interest = LuddicPathBaseManager.getLuddicPathMarketInterest(market);
590                                interest += market.getSize();
591                                tithe += interest * market.getSize() * tithePerPointPerColonySize;
592                        }
593                        
594                        tithe += normalTithe;
595                        
596                        tithe = (int) Misc.getRounded(tithe);
597                        
598                        memoryMap.get(MemKeys.LOCAL).set("$LP_megaTithe", (int)tithe, 0);
599                        memoryMap.get(MemKeys.LOCAL).set("$LP_megaTitheDGS", Misc.getWithDGS(tithe), 0);
600                        memoryMap.get(MemKeys.LOCAL).set("$LP_megaTitheDuration", titheDuration, 0);
601                        
602                        return tithe > 0;
603                } else if ("kazeronInstallNanoforge".equals(action)) {
604                        MarketAPI kazeron = PerseanLeagueHostileActivityFactor.getKazeron(false);
605                        if (kazeron != null) {
606                                SpecialItemData data = new SpecialItemData(Items.PRISTINE_NANOFORGE, null);
607                                for (Industry ind : kazeron.getIndustries()) {
608                                        if (ind.wantsToUseSpecialItem(data)) {
609                                                ind.setSpecialItem(data);
610                                                break;
611                                        }
612                                }
613                        }
614                } else if ("kazeronNanoforgeMissing".equals(action)) {
615                        MarketAPI kazeron = PerseanLeagueHostileActivityFactor.getKazeron(false);
616                        if (kazeron == null) return true;
617                        for (Industry ind : kazeron.getIndustries()) {
618                                if (ind.getSpecialItem() == null) continue;
619                                if (ind.getSpecialItem().getId().equals(Items.PRISTINE_NANOFORGE)) {
620                                        return false;
621                                }
622                        }
623                        return true;
624                } else if ("stopPayingHouseHannan".equals(action)) {
625                        PerseanLeagueMembership.stopPayingHouseHannan(params.get(1).getBoolean(memoryMap), dialog);
626//                      PerseanLeagueMembership.setPayingHouseHannan(false);
627//                      Misc.incrUntrustwortyCount();
628                } else if ("leaveLeague".equals(action)) {
629                        PerseanLeagueMembership m = PerseanLeagueMembership.get();
630                        if (m != null) {
631                                // do this here so that the intel is shown; would also happen automatically
632                                // when the membership is ended
633                                PerseanLeagueMembership.stopPayingHouseHannan(false, dialog);
634                                
635                                m.endMembership(AgreementEndingType.ENDED, dialog);
636                                //m.sendUpdate(new Object(), dialog.getTextPanel());
637                        }
638                } else if ("printTriTachDealRepReq".equals(action)) {
639                        FactionAPI triTach = Global.getSector().getFaction(Factions.TRITACHYON);
640                        CoreReputationPlugin.addRequiredStanding(triTach, RepLevel.INHOSPITABLE, null, dialog.getTextPanel(), null, null, 0f, true);
641                        CoreReputationPlugin.addCurrentStanding(triTach, null, dialog.getTextPanel(), null, null, 0f);
642                } else if ("isTTCRInProgress".equals(action)) {
643                        return TriTachyonCommerceRaiding.get() != null;
644                } else if ("isTTRaidingPlayerCommerce".equals(action)) {
645                        HostileActivityEventIntel intel = HostileActivityEventIntel.get();
646                        if (intel != null) {
647                                EventFactor factor = intel.getFactorOfClass(TriTachyonHostileActivityFactor.class);
648                                if (factor instanceof TriTachyonHostileActivityFactor) {
649                                        TriTachyonHostileActivityFactor ttFactor = (TriTachyonHostileActivityFactor) factor;
650                                        return ttFactor.getProgress(intel) > 0;
651                                }
652                        }
653                } else if ("makeTriTachDeal".equals(action)) {
654                        if (TriTachyonDeal.get() == null) {
655                                new TriTachyonDeal(dialog);
656                        }
657                } else if ("breakTriTachDeal".equals(action)) {
658                        if (TriTachyonDeal.get() != null) {
659                                TriTachyonDeal.get().endAgreement(com.fs.starfarer.api.impl.campaign.intel.TriTachyonDeal.AgreementEndingType.BROKEN, dialog);
660                        }
661                } else if ("printLCDealRepReq".equals(action)) {
662                        FactionAPI luddicChurch = Global.getSector().getFaction(Factions.LUDDIC_CHURCH);
663                        CoreReputationPlugin.addRequiredStanding(luddicChurch, RepLevel.INHOSPITABLE, null, dialog.getTextPanel(), null, null, 0f, true);
664                        CoreReputationPlugin.addCurrentStanding(luddicChurch, null, dialog.getTextPanel(), null, null, 0f);
665                } else if ("breakLCDeal".equals(action)) {
666                        if (LuddicChurchImmigrationDeal.get() != null) {
667                                LuddicChurchImmigrationDeal.get().endAgreement(com.fs.starfarer.api.impl.campaign.intel.LuddicChurchImmigrationDeal.AgreementEndingType.BROKEN, dialog);
668                        }
669                } else if ("KOLTakeoverInProgress".equals(action)) {
670                        return isKOLTakeoverInProgress();
671                } else if ("makeLuddicChurchDeal".equals(action)) {
672                        if (LuddicChurchImmigrationDeal.get() == null) {
673                                new LuddicChurchImmigrationDeal(dialog);
674                        }
675                } else if ("joinLeague".equals(action)) {
676                        new PerseanLeagueMembership(dialog);
677                        
678                        avertOrEndPLBlockadeAsNecessary();
679                        HegemonyHostileActivityFactor.avertInspectionIfNotInProgress();
680                } else if ("canJoinLeague".equals(action)) {
681                        return canPlayerJoinTheLeague();        
682                } else if ("isPLExpeditionInProgress".equals(action)) {
683                        return isPLExpeditionInProgress();
684                } else if ("isPLProtectingPlayerSpace".equals(action)) {
685                        HostileActivityEventIntel intel = HostileActivityEventIntel.get();
686                        if (intel != null) {
687                                EventFactor factor = intel.getFactorOfClass(PerseanLeagueHostileActivityFactor.class);
688                                if (factor instanceof PerseanLeagueHostileActivityFactor) {
689                                        PerseanLeagueHostileActivityFactor plFactor = (PerseanLeagueHostileActivityFactor) factor;
690                                        return plFactor.getProgress(intel) > 0;
691                                }
692                        }                       
693                } else if ("canSendPLPunitiveExpedition".equals(action)) {
694                        return canSendPerseanLeaguePunitiveExpedition();
695                } else if ("updateLeagueData".equals(action)) {
696                        float duesF = Global.getSettings().getFloat("perseanLeagueFeeFraction");
697                        float hannanF = Global.getSettings().getFloat("houseHannanFeeFraction");
698                        
699                        memoryMap.get(MemKeys.LOCAL).set("$plDuesPercent", (int)Math.round(duesF * 100f) + "%", 0);
700                        memoryMap.get(MemKeys.LOCAL).set("$hannanBribePercent", (int)Math.round(hannanF * 100f) + "%", 0);
701                        return canPlayerJoinTheLeague();        
702                        
703                } else if ("canRemakeDealWithHouseHannan".equals(action)) {
704                        return GensHannanMachinations.canRemakeDealWithHouseHannan();
705                } else if ("endGHMachinations".equals(action)) {
706                        GensHannanMachinations m = GensHannanMachinations.get();
707                        if (m != null) {
708                                m.endMachinations(text);
709                        }
710                } else if ("doKOLTTakeover".equals(action)) {
711                        KnightsOfLuddTakeoverExpedition takeover = KnightsOfLuddTakeoverExpedition.get();
712                        if (takeover != null) {
713                                takeover.performTakeover(true);
714                        }
715                } else if ("updateKOLTArmadaData".equals(action)) {
716                        KnightsOfLuddTakeoverExpedition takeover = KnightsOfLuddTakeoverExpedition.get();
717                        if (takeover != null) {
718                                MemoryAPI mem = memoryMap.get(MemKeys.LOCAL);
719                                mem.set("$KOLT_target", takeover.getBlockadeParams().specificMarket.getName());
720                                return true;
721                        }
722                } else if ("updateTTMAData".equals(action)) {
723                        MemoryAPI mem = memoryMap.get(MemKeys.LOCAL);
724                        
725//                      int bribe = Global.getSettings().getInt("triTachyonMercBribe");
726//                      int bribeSmall = bribe / 2;
727//                      mem.set("$bribeSmall", Misc.getWithDGS(bribeSmall));
728//                      mem.set("$bribe", Misc.getWithDGS(bribe));
729                        
730                        TTMercenaryAttack attack = TTMercenaryAttack.get();
731                        StarSystemAPI target = TriTachyonHostileActivityFactor.getPrimaryTriTachyonSystem();
732                        boolean reversible = attack != null && !attack.isSpawning() && !attack.isFailed() &&
733                                        !attack.isSucceeded() && !attack.isAborted() && !attack.isEnding() && !attack.isEnded() &&
734                                        target != null;
735                        
736                        mem.set("$attackReversible", reversible);
737                        if (target != null) {
738                                mem.set("$triTachSystem", target.getNameWithLowercaseTypeShort());
739                        }
740                        return true;
741                        
742                } else if ("retargetTTMA".equals(action)) {
743                        TTMercenaryReversedAttack.sendReversedAttack(dialog);
744                } else if ("computeSacredProtectorsData".equals(action)) {
745                        MemoryAPI mem = memoryMap.get(MemKeys.LOCAL);
746                        int supplies = (int) Global.getSector().getPlayerFleet().getFleetPoints() * 1;
747                        mem.set("$SP_supplies", (int)supplies, 0);
748                        return true;
749                } else if ("sacredProtectorsCheckCargoPods".equals(action)) {
750                        MemoryAPI mem = memoryMap.get(MemKeys.LOCAL);
751                        int supplies = mem.getInt("$SP_supplies");
752                        return sacredProtectorsCheckCargoPods(supplies);
753                } else if ("knightsHasslingPlayerColonies".equals(action)) {
754                        HostileActivityEventIntel intel = HostileActivityEventIntel.get();
755                        if (intel != null) {
756                                HostileActivityCause2 cause = intel.getActivityCause(LuddicChurchHostileActivityFactor.class, LuddicChurchStandardActivityCause.class);
757                                if (cause instanceof LuddicChurchStandardActivityCause) {
758                                        LuddicChurchStandardActivityCause lcCause = (LuddicChurchStandardActivityCause) cause;
759                                        return lcCause.getProgress() > 0;
760                                }
761                        }
762                } else if ("printSDDealRepReq".equals(action)) {
763                        FactionAPI diktat = Global.getSector().getFaction(Factions.DERELICT);
764                        CoreReputationPlugin.addRequiredStanding(diktat, RepLevel.INHOSPITABLE, null, dialog.getTextPanel(), null, null, 0f, true);
765                        CoreReputationPlugin.addCurrentStanding(diktat, null, dialog.getTextPanel(), null, null, 0f);
766                } else if ("breakSDDeal".equals(action)) {
767                        if (SindrianDiktatFuelDeal.get() != null) {
768                                SindrianDiktatFuelDeal.get().endAgreement(com.fs.starfarer.api.impl.campaign.intel.SindrianDiktatFuelDeal.AgreementEndingType.BROKEN, dialog);
769                        }
770                } else if ("makeDiktatDeal".equals(action)) {
771                        if (SindrianDiktatFuelDeal.get() == null) {
772                                new SindrianDiktatFuelDeal(dialog);
773                        }
774                } else if ("diktatConcernedByFuelProd".equals(action)) {
775                        HostileActivityEventIntel intel = HostileActivityEventIntel.get();
776                        if (intel != null) {
777                                HostileActivityCause2 cause = intel.getActivityCause(SindrianDiktatHostileActivityFactor.class, SindrianDiktatStandardActivityCause.class);
778                                if (cause instanceof SindrianDiktatStandardActivityCause) {
779                                        SindrianDiktatStandardActivityCause lcCause = (SindrianDiktatStandardActivityCause) cause;
780                                        return lcCause.getProgress() > 0;
781                                }
782                        }
783                }
784                
785//              else if ("printLeagueRequirements".equals(action)) {
786//                      
787//              }
788                
789                return false;
790        }
791        
792        public boolean sacredProtectorsCheckCargoPods(int remove) {
793                float maxPodsDist = 1500f;
794                for (SectorEntityToken entity : other.getContainingLocation().getAllEntities()) {
795                        if (Entities.CARGO_PODS.equals(entity.getCustomEntityType())) {
796                                VisibilityLevel vLevel = entity.getVisibilityLevelTo(other);
797                                if (entity.getCustomPlugin() instanceof CargoPodsEntityPlugin) {
798                                        float dist = Misc.getDistance(other, entity);
799                                        if (dist > maxPodsDist) continue;
800                                        
801                                        if (vLevel == VisibilityLevel.COMPOSITION_DETAILS ||
802                                                        vLevel == VisibilityLevel.COMPOSITION_AND_FACTION_DETAILS) {
803                                                CargoPodsEntityPlugin plugin = (CargoPodsEntityPlugin) entity.getCustomPlugin();
804                                                if (plugin.getElapsed() <= 1f && entity.getCargo() != null) {
805                                                        float supplies = entity.getCargo().getSupplies();
806                                                        if (supplies >= remove) {
807                                                                entity.getCargo().removeSupplies(remove * 2);
808                                                                return true;
809                                                        }
810                                                }
811                                        }
812                                }
813                        }
814                }
815                return false;
816        }
817        
818        
819        public static boolean isKOLTakeoverInProgress() {
820                return KnightsOfLuddTakeoverExpedition.get() != null && 
821                                !KnightsOfLuddTakeoverExpedition.get().isSucceeded() && 
822                                !KnightsOfLuddTakeoverExpedition.get().isAborted() && 
823                                !KnightsOfLuddTakeoverExpedition.get().isFailed();
824        }
825        
826        public static boolean isPLExpeditionInProgress() {
827                return PerseanLeaguePunitiveExpedition.get() != null && 
828                                !PerseanLeaguePunitiveExpedition.get().isSucceeded() && 
829                                !PerseanLeaguePunitiveExpedition.get().isAborted() && 
830                                !PerseanLeaguePunitiveExpedition.get().isFailed();
831        }
832        
833        public static void avertOrEndKOLTakeoverAsNecessary() {
834                KnightsOfLuddTakeoverExpedition takeover = KnightsOfLuddTakeoverExpedition.get();
835                if (takeover != null) {
836                        takeover.finish(false);
837                }
838                
839                HostileActivityEventIntel intel = HostileActivityEventIntel.get();
840                if (intel != null) {
841                        HAERandomEventData data = intel.getRollDataForEvent();
842                        if (data != null && data.factor instanceof LuddicChurchHostileActivityFactor) {
843                                intel.resetHA_EVENT();
844                        }
845                }
846        }
847        
848        public static void avertOrEndDiktatAttackAsNecessary() {
849                SindrianDiktatPunitiveExpedition attack = SindrianDiktatPunitiveExpedition.get();
850                if (attack != null) {
851                        attack.finish(false);
852                }
853                
854                HostileActivityEventIntel intel = HostileActivityEventIntel.get();
855                if (intel != null) {
856                        HAERandomEventData data = intel.getRollDataForEvent();
857                        if (data != null && data.factor instanceof SindrianDiktatHostileActivityFactor) {
858                                intel.resetHA_EVENT();
859                        }
860                }
861        }
862        
863        
864        public static void avertOrEndPLBlockadeAsNecessary() {
865                PerseanLeagueBlockade blockade = PerseanLeagueBlockade.get();
866                if (blockade != null) {
867                        blockade.finish(false);
868                }
869
870                PerseanLeaguePunitiveExpedition expedition = PerseanLeaguePunitiveExpedition.get();
871                if (expedition != null) {
872                        expedition.finish(false);
873                }
874                
875                HostileActivityEventIntel intel = HostileActivityEventIntel.get();
876                if (intel != null) {
877                        HAERandomEventData data = intel.getRollDataForEvent();
878                        if (data != null && data.factor instanceof PerseanLeagueHostileActivityFactor) {
879                                intel.resetHA_EVENT();
880                        }
881                }
882        }
883        
884        public static boolean canPlayerJoinTheLeague() {
885                if (isPLExpeditionInProgress()) return false;
886                
887                if (PerseanLeagueMembership.isLeagueMember()) return false;
888                if (PerseanLeagueMembership.isLeftLeagueWhenGoodDeal()) return false;
889                
890                if (PerseanLeagueHostileActivityFactor.wasPLEverSatBombardedByPlayer()) return false;
891                if (PerseanLeagueHostileActivityFactor.getKazeron(false) == null) return false;
892                
893                if (PerseanLeagueMembership.getNumTimesLeftLeague() >= PerseanLeagueMembership.TIMES_LEFT_LEAGUE_FOR_NO_REJOIN) {
894                        return false;
895                }
896                
897                int large = 0;
898                int count = 0;
899                int medium = 0;
900                for (MarketAPI market : Misc.getPlayerMarkets(false)) {
901                        int size = market.getSize();
902                        if (size >= StandardPerseanLeagueActivityCause.LARGE_COLONY) {
903                                large++;
904                        }
905                        if (size >= StandardPerseanLeagueActivityCause.MEDIUM_COLONY) {
906                                medium++;
907                        }
908                        count++;
909                }
910                if (large > 0 || (medium > 0 && count >= StandardPerseanLeagueActivityCause.COUNT_IF_MEDIUM)) {
911                        return true;
912                }
913                return false; 
914        }
915
916        public static boolean baseInvolved(StarSystemAPI system, PirateBaseIntel base) {
917                if (system == null) return false;
918                if (base == null) return false;
919                
920                return !PirateBasePirateActivityCause2.getColoniesAffectedBy(base).isEmpty();
921        }
922        
923
924        public static class PLPunExData {
925                public HostileActivityEventIntel intel;
926                public StarSystemAPI target;
927                public MarketAPI kazeron;
928        }
929        
930        public static boolean canSendPerseanLeaguePunitiveExpedition() {
931                return computePerseanLeaguePunitiveExpeditionData() != null;
932        }
933        public static PLPunExData computePerseanLeaguePunitiveExpeditionData() {
934                if (PerseanLeagueMembership.isDefeatedBlockadeOrPunEx()) {
935                        return null;
936                }
937                if (isPLExpeditionInProgress()) {
938                        return null;
939                }
940                
941                HostileActivityEventIntel intel = HostileActivityEventIntel.get();
942                if (intel == null) return null;
943                
944                StarSystemAPI target = PerseanLeagueHostileActivityFactor.findBlockadeTarget(intel, null);
945                if (target == null) return null;
946                
947                MarketAPI kazeron = PerseanLeagueHostileActivityFactor.getKazeron(true);
948                if (kazeron == null) return null;
949                
950                PLPunExData data = new PLPunExData();
951                data.intel = intel;
952                data.target = target;
953                data.kazeron = kazeron;
954                return data;
955        }
956        
957        public static void sendPerseanLeaguePunitiveExpedition(InteractionDialogAPI dialog) {
958                
959                PLPunExData data = computePerseanLeaguePunitiveExpeditionData();
960                if (data == null) {
961                        return;
962                }
963                
964                avertOrEndPLBlockadeAsNecessary();
965                
966                GenericRaidParams params = new GenericRaidParams(new Random(), true);
967                params.factionId = data.kazeron.getFactionId();
968                params.source = data.kazeron;
969                
970                Random random = new Random();
971                
972                params.prepDays = 14f + random.nextFloat() * 14f;
973                params.payloadDays = 27f + 7f * random.nextFloat();
974                
975                params.raidParams.where = data.target;
976                
977                Set<String> disrupt = new LinkedHashSet<String>();
978                for (MarketAPI market : Misc.getMarketsInLocation(data.target, Factions.PLAYER)) {
979                        params.raidParams.allowedTargets.add(market);
980                        params.raidParams.allowNonHostileTargets = true;
981                        for (Industry ind : market.getIndustries()) {
982                                if (ind.getSpec().hasTag(Industries.TAG_UNRAIDABLE)) continue;
983                                disrupt.add(ind.getId());
984                                
985                        }
986                }
987                
988                // this is set in the custom fleet creation in PerseanLeaguePunitiveExpedition
989                //params.makeFleetsHostile = false;
990                
991                params.raidParams.disrupt.addAll(disrupt);
992                params.raidParams.raidsPerColony = Math.min(disrupt.size(), 4);
993                if (disrupt.isEmpty()) {
994                        params.raidParams.raidsPerColony = 2;
995                }
996                
997                if (params.raidParams.allowedTargets.isEmpty()) {
998                        return;
999                }
1000                
1001                params.style = FleetStyle.STANDARD;
1002                
1003                
1004                float fleetSizeMult = data.kazeron.getStats().getDynamic().getMod(Stats.COMBAT_FLEET_SIZE_MULT).computeEffective(0f);
1005                
1006                float f = data.intel.getMarketPresenceFactor(data.target);
1007                
1008                float totalDifficulty = fleetSizeMult * 50f * (0.5f + 0.5f * f);
1009                if (totalDifficulty < 30) {
1010                        return;
1011                }
1012                if (totalDifficulty > 100) {
1013                        totalDifficulty = 100;
1014                }
1015                
1016                Random r = data.intel.getRandom();
1017                
1018                // mostly maxed-out fleets, some smaller ones
1019                while (totalDifficulty > 0) {
1020                        float max = 6f;
1021                        float min = 3f;
1022                        
1023                        if (r.nextFloat() > 0.3f) {
1024                                min = (int) Math.min(totalDifficulty, 8f);
1025                                max = (int) Math.min(totalDifficulty, 10f);
1026                        }
1027                        
1028                        int diff = Math.round(StarSystemGenerator.getNormalRandom(r, min, max));
1029                        
1030                        params.fleetSizes.add(diff);
1031                        totalDifficulty -= diff;
1032                }
1033                
1034                PerseanLeaguePunitiveExpedition punex = new PerseanLeaguePunitiveExpedition(params);
1035                punex.setPreFleetDeploymentDelay(30f + random.nextFloat() * 60f);
1036                //punex.setPreFleetDeploymentDelay(1f);
1037                TextPanelAPI text = dialog == null ? null : dialog.getTextPanel();
1038                Global.getSector().getIntelManager().addIntel(punex, false, text);              
1039                
1040        }
1041        
1042        
1043        
1044}
1045
1046
1047
1048
1049