001package com.fs.starfarer.api.impl.campaign.intel.events;
002
003import java.awt.Color;
004import java.util.Random;
005
006import org.lwjgl.util.vector.Vector2f;
007
008import com.fs.starfarer.api.Global;
009import com.fs.starfarer.api.campaign.CampaignFleetAPI;
010import com.fs.starfarer.api.campaign.CargoAPI;
011import com.fs.starfarer.api.campaign.InteractionDialogAPI;
012import com.fs.starfarer.api.campaign.StarSystemAPI;
013import com.fs.starfarer.api.campaign.comm.IntelInfoPlugin.ListInfoMode;
014import com.fs.starfarer.api.campaign.econ.Industry;
015import com.fs.starfarer.api.campaign.econ.MarketAPI;
016import com.fs.starfarer.api.campaign.listeners.ColonyPlayerHostileActListener;
017import com.fs.starfarer.api.campaign.listeners.ColonySizeChangeListener;
018import com.fs.starfarer.api.impl.campaign.NPCHassler;
019import com.fs.starfarer.api.impl.campaign.econ.LuddicMajority;
020import com.fs.starfarer.api.impl.campaign.ids.Conditions;
021import com.fs.starfarer.api.impl.campaign.ids.Factions;
022import com.fs.starfarer.api.impl.campaign.ids.FleetTypes;
023import com.fs.starfarer.api.impl.campaign.ids.Industries;
024import com.fs.starfarer.api.impl.campaign.intel.events.BaseEventIntel.EventStageData;
025import com.fs.starfarer.api.impl.campaign.intel.events.HostileActivityEventIntel.HAERandomEventData;
026import com.fs.starfarer.api.impl.campaign.intel.events.HostileActivityEventIntel.Stage;
027import com.fs.starfarer.api.impl.campaign.intel.group.FGBlockadeAction.FGBlockadeParams;
028import com.fs.starfarer.api.impl.campaign.intel.group.FleetGroupIntel;
029import com.fs.starfarer.api.impl.campaign.intel.group.FleetGroupIntel.FGIEventListener;
030import com.fs.starfarer.api.impl.campaign.intel.group.GenericRaidFGI.GenericRaidParams;
031import com.fs.starfarer.api.impl.campaign.intel.group.KnightsOfLuddTakeoverExpedition;
032import com.fs.starfarer.api.impl.campaign.missions.FleetCreatorMission;
033import com.fs.starfarer.api.impl.campaign.missions.FleetCreatorMission.FleetStyle;
034import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.FleetQuality;
035import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.MarketCMD.TempData;
036import com.fs.starfarer.api.ui.LabelAPI;
037import com.fs.starfarer.api.ui.TooltipMakerAPI;
038import com.fs.starfarer.api.ui.TooltipMakerAPI.TooltipCreator;
039import com.fs.starfarer.api.util.Misc;
040import com.fs.starfarer.api.util.WeightedRandomPicker;
041
042public class LuddicChurchHostileActivityFactor extends BaseHostileActivityFactor implements
043                                                FGIEventListener, ColonyPlayerHostileActListener, ColonySizeChangeListener {
044
045        public static final String HASSLE_REASON = "sacredProtectors";
046        
047        // in $player memory
048        public static final String DEFEATED_LUDDIC_CHURCH_EXPEDITION = "$defeatedLuddicChurchExpedition";
049        public static final String MADE_IMMIGRATION_DEAL_WITH_LUDDIC_CHURCH = "$madeImmigrationDealWithLuddicChurch";
050        public static final String BROKE_LUDDIC_CHURCH_DEAL = "$brokeLuddicChurchDeal";
051        
052        public static boolean isDefeatedExpedition() {
053                //if (true) return true;
054                return Global.getSector().getPlayerMemoryWithoutUpdate().getBoolean(DEFEATED_LUDDIC_CHURCH_EXPEDITION);
055        }
056        public static void setDefeatedExpedition(boolean value) {
057                Global.getSector().getPlayerMemoryWithoutUpdate().set(DEFEATED_LUDDIC_CHURCH_EXPEDITION, value);
058        }
059        
060        public static boolean isMadeDeal() {
061                return Global.getSector().getPlayerMemoryWithoutUpdate().getBoolean(MADE_IMMIGRATION_DEAL_WITH_LUDDIC_CHURCH);
062        }
063        public static void setMadeDeal(boolean value) {
064                Global.getSector().getPlayerMemoryWithoutUpdate().set(MADE_IMMIGRATION_DEAL_WITH_LUDDIC_CHURCH, value);
065        }
066        
067        
068        public static boolean brokeDeal() {
069                return Global.getSector().getPlayerMemoryWithoutUpdate().getBoolean(BROKE_LUDDIC_CHURCH_DEAL);
070        }
071        public static void setBrokeDeal(boolean broke) {
072                Global.getSector().getPlayerMemoryWithoutUpdate().set(BROKE_LUDDIC_CHURCH_DEAL, broke);
073        }
074        
075        
076        
077        
078        
079        
080        
081        public LuddicChurchHostileActivityFactor(HostileActivityEventIntel intel) {
082                super(intel);
083                
084                Global.getSector().getListenerManager().addListener(this);
085        }
086        
087        public String getProgressStr(BaseEventIntel intel) {
088                return "";
089        }
090        
091        @Override
092        public int getProgress(BaseEventIntel intel) {
093                if (!checkFactionExists(Factions.LUDDIC_CHURCH, true)) {
094                        return 0;
095                }
096                return super.getProgress(intel);
097        }
098        
099        public String getDesc(BaseEventIntel intel) {
100                return "Luddic Church";
101        }
102        
103        public String getNameForThreatList(boolean first) {
104                return "Knights of Ludd";
105        }
106
107
108        public Color getDescColor(BaseEventIntel intel) {
109                if (getProgress(intel) <= 0) {
110                        return Misc.getGrayColor();
111                }
112                return Global.getSector().getFaction(Factions.LUDDIC_CHURCH).getBaseUIColor();
113        }
114
115        public TooltipCreator getMainRowTooltip(BaseEventIntel intel) {
116                return new BaseFactorTooltip() {
117                        public void createTooltip(TooltipMakerAPI tooltip, boolean expanded, Object tooltipParam) {
118                                float opad = 10f;
119                                tooltip.addPara("A large community of the faithful -"
120                                                + " not under their direct control, and with potential to emerge as a major cultural center - "
121                                                + "is a growing source of concern to the Church. "
122                                                + "\"Protector\" fleets operated by the Knights of Ludd can be found in your systems, "
123                                                + "ostensibly there to protect the "
124                                                + "interests of the local Luddic population.", 0f);
125                        }
126                };
127        }
128
129        public boolean shouldShow(BaseEventIntel intel) {
130                return getProgress(intel) > 0;
131        }
132
133
134        public Color getNameColor(float mag) {
135                if (mag <= 0f) {
136                        return Misc.getGrayColor();
137                }
138                return Global.getSector().getFaction(Factions.LUDDIC_CHURCH).getBaseUIColor();
139        }
140        
141        
142        @Override
143        public int getMaxNumFleets(StarSystemAPI system) {
144                return Global.getSettings().getInt("luddicChurchMaxFleets");
145        }
146        
147        
148        @Override
149        public float getSpawnInHyperProbability(StarSystemAPI system) {
150                return 0f;
151        }
152        
153        public CampaignFleetAPI createFleet(StarSystemAPI system, Random random) {
154        
155                //float f = intel.getMarketPresenceFactor(system);
156                
157                int maxSize = 0;
158                for (MarketAPI curr : Misc.getMarketsInLocation(system, Factions.PLAYER)) {
159                        maxSize = Math.max(curr.getSize(), maxSize);
160                }
161                
162                //int difficulty = 0 + (int) Math.max(1f, Math.round(f * 6f));
163                int difficulty = maxSize + 1;
164                difficulty += random.nextInt(4);
165                if (difficulty > 10) difficulty = 10;
166                
167                FleetCreatorMission m = new FleetCreatorMission(random);
168                m.beginFleet();
169                
170                Vector2f loc = system.getLocation();
171                String factionId = Factions.LUDDIC_CHURCH;
172                
173                m.createStandardFleet(difficulty, factionId, loc);
174                m.triggerSetFleetQuality(FleetQuality.HIGHER);
175                m.triggerSetFleetType(FleetTypes.SACRED_PROTECTORS);
176                m.triggerSetPatrol();
177                m.triggerSetFleetHasslePlayer(HASSLE_REASON);
178                m.triggerSetFleetFlag("$sacredProtectors");
179                
180                m.triggerFleetAllowLongPursuit();
181                m.triggerMakeLowRepImpact();
182                
183                //m.triggerMakeHostile();
184                //m.triggerMakeHostileWhileTransponderOff();
185                
186                CampaignFleetAPI fleet = m.createFleet();
187                
188                if (fleet != null) {
189                        fleet.setName("Knights of Ludd " + fleet.getName());
190                        fleet.setNoFactionInName(true);
191                        NPCHassler hassle = new NPCHassler(fleet, system);
192                        hassle.getParams().crDamageMult = 0f; 
193                        fleet.addScript(hassle);
194                }
195
196                return fleet;
197        }
198        
199        
200        public void addBulletPointForEvent(HostileActivityEventIntel intel, EventStageData stage, TooltipMakerAPI info,
201                                                                                 ListInfoMode mode, boolean isUpdate, Color tc, float initPad) {
202                Color c = Global.getSector().getFaction(Factions.LUDDIC_CHURCH).getBaseUIColor();
203                info.addPara("Impending Luddic Church takeover operation", initPad, tc, c, "Luddic Church");
204        }
205        
206        public void addBulletPointForEventReset(HostileActivityEventIntel intel, EventStageData stage, TooltipMakerAPI info,
207                        ListInfoMode mode, boolean isUpdate, Color tc, float initPad) {
208                info.addPara("Luddic Church takeover averted", tc, initPad);
209        }
210        
211        public void addStageDescriptionForEvent(HostileActivityEventIntel intel, EventStageData stage, TooltipMakerAPI info) {
212                float small = 0f;
213                float opad = 10f;
214                
215                small = 8f;
216
217                LabelAPI label = info.addPara("You've received intel that the Knights of Ludd, under the aegis of the Luddic Church, "
218                                + "are planning an operation to take over one of your colonies that has a Luddic Majority "
219                                + "population.",
220                                small, Misc.getNegativeHighlightColor(), "take over one of your colonies");
221                label.setHighlight("take over one of your colonies", "Luddic Majority");
222                label.setHighlightColors(Misc.getNegativeHighlightColor(),
223                                Global.getSector().getFaction(Factions.LUDDIC_CHURCH).getBaseUIColor());
224                
225                label = info.addPara("If the expedition is defeated, the Luddic faithful leaving the Church worlds "
226                                + "will feel more secure, resulting in increased immigration, stability, and productivity, "
227                                + "and the Luddic Church will likely abandon further efforts of this sort.", 
228                                opad);
229                label.setHighlight("increased immigration, stability, and productivity", "Luddic Church");
230                label.setHighlightColors(Misc.getPositiveHighlightColor(),
231                                Global.getSector().getFaction(Factions.LUDDIC_CHURCH).getBaseUIColor());
232                
233                Color c = Global.getSector().getFaction(Factions.LUDDIC_CHURCH).getBaseUIColor();
234                stage.beginResetReqList(info, true, "crisis", opad);
235                info.addPara("You make an agreement with the Church", 0f);
236                info.addPara("%s is tactically bombarded", 0f, c, "Hesperus");
237                stage.endResetReqList(info, false, "crisis", -1, -1);
238                
239                addBorder(info, Global.getSector().getFaction(Factions.LUDDIC_CHURCH).getBaseUIColor());
240        }
241        
242        
243        public String getEventStageIcon(HostileActivityEventIntel intel, EventStageData stage) {
244                return Global.getSector().getFaction(Factions.LUDDIC_CHURCH).getCrest();
245        }
246
247        public TooltipCreator getStageTooltipImpl(final HostileActivityEventIntel intel, final EventStageData stage) {
248                if (stage.id == Stage.HA_EVENT) {
249                        return getDefaultEventTooltip("Luddic Church expedition", intel, stage);
250                }
251                return null;
252        }
253        
254        
255        public float getEventFrequency(HostileActivityEventIntel intel, EventStageData stage) {
256                if (stage.id == Stage.HA_EVENT) {
257                        if (isDefeatedExpedition() || getHesperus(true) == null) {
258                                return 0f;
259                        }
260                        
261                        if (KnightsOfLuddTakeoverExpedition.get() != null) {
262                                return 0f;
263                        }
264                        
265                        MarketAPI target = findExpeditionTarget(intel, stage);
266                        MarketAPI source = getExpeditionSource(intel, stage, target);
267                        if (target != null && source != null) {
268                                return 20f;
269                        }
270                }
271                return 0;
272        }
273        
274
275        public void rollEvent(HostileActivityEventIntel intel, EventStageData stage) {
276                HAERandomEventData data = new HAERandomEventData(this, stage);
277                stage.rollData = data;
278                intel.sendUpdateIfPlayerHasIntel(data, false);
279        }
280        
281        public boolean fireEvent(HostileActivityEventIntel intel, EventStageData stage) {
282                MarketAPI target = findExpeditionTarget(intel, stage);
283                MarketAPI source = getExpeditionSource(intel, stage, target);
284                if (source == null || target == null) {
285                        return false;
286                }
287        
288                stage.rollData = null;
289                return startExpedition(source, target, stage, getRandomizedStageRandom(3));
290        }
291        
292        
293        public MarketAPI findExpeditionTarget(HostileActivityEventIntel intel, EventStageData stage) {
294                WeightedRandomPicker<MarketAPI> picker = new WeightedRandomPicker<MarketAPI>(getRandomizedStageRandom());
295                for (MarketAPI market : Misc.getPlayerMarkets(false)) {
296                        if (market.getStarSystem() == null) continue;
297                        if (market.hasCondition(Conditions.LUDDIC_MAJORITY)) {
298                                float size = market.getSize();
299                                float w = Math.max(size - 3f, 1f);
300                                w = w * w * w;
301                                picker.add(market, w);
302                        }
303                }
304                return picker.pick();
305        }
306        
307        public MarketAPI getExpeditionSource(HostileActivityEventIntel intel, EventStageData stage, final MarketAPI target) {
308                return getHesperus(true);
309        }
310        
311        public static MarketAPI getHesperus(boolean requireMilitaryBase) {
312                MarketAPI hesperus = Global.getSector().getEconomy().getMarket("hesperus");
313                if (hesperus == null || hesperus.hasCondition(Conditions.DECIVILIZED) ||
314                                !hesperus.getFactionId().equals(Factions.LUDDIC_CHURCH)) {
315                        return null;
316                }
317                if (requireMilitaryBase) {
318                        Industry b = hesperus.getIndustry(Industries.MILITARYBASE);
319                        if (b == null) b = hesperus.getIndustry(Industries.HIGHCOMMAND);
320                        if (b == null || b.isDisrupted() || !b.isFunctional()) {
321                                return null;
322                        }
323                }
324                return hesperus;
325        }
326        
327        
328        public boolean startExpedition(MarketAPI source, MarketAPI target, EventStageData stage, Random random) {
329
330                GenericRaidParams params = new GenericRaidParams(new Random(random.nextLong()), true);
331                params.factionId = source.getFactionId();
332                params.source = source;
333                
334                params.prepDays = 7f + random.nextFloat() * 14f;
335                params.payloadDays = 180f;
336                
337                params.makeFleetsHostile = false;
338                
339                FGBlockadeParams bParams = new FGBlockadeParams();
340                bParams.where = target.getStarSystem();
341                bParams.targetFaction = Factions.PLAYER;
342                bParams.specificMarket = target;
343                
344                params.noun = "takeover";
345                params.forcesNoun = "Luddic forces";
346                
347                params.style = FleetStyle.STANDARD;
348                
349                
350                params.fleetSizes.add(10); // first size 10 pick becomes the Armada
351                
352                // and a few smaller picket forces
353                params.fleetSizes.add(4);
354                params.fleetSizes.add(4);
355                params.fleetSizes.add(3);
356                params.fleetSizes.add(3);
357
358                
359                KnightsOfLuddTakeoverExpedition blockade = new KnightsOfLuddTakeoverExpedition(params, bParams);
360                blockade.setListener(this);
361                Global.getSector().getIntelManager().addIntel(blockade);
362                
363                return true;
364        }
365        
366        public void reportFGIAborted(FleetGroupIntel intel) {
367                setDefeatedExpedition(true);
368        }
369        
370        
371        
372        @Override
373        public void notifyFactorRemoved() {
374                Global.getSector().getListenerManager().removeListener(this);
375        }
376
377        public void notifyEventEnding() {
378                notifyFactorRemoved();
379        }
380
381        
382        public void reportRaidForValuablesFinishedBeforeCargoShown(InteractionDialogAPI dialog, MarketAPI market,
383                        TempData actionData, CargoAPI cargo) {
384                
385        }
386
387        public void reportRaidToDisruptFinished(InteractionDialogAPI dialog, MarketAPI market, TempData actionData, Industry industry) {
388                
389        }
390
391        public void reportTacticalBombardmentFinished(InteractionDialogAPI dialog, MarketAPI market, TempData actionData) {
392                MarketAPI hesperus = getHesperus(false);
393                if (market != null && market == hesperus) {
394                        EventStageData stage = intel.getDataFor(Stage.HA_EVENT);
395                        if (stage != null) {
396                                boolean thisEvent = stage.rollData instanceof HAERandomEventData && 
397                                                ((HAERandomEventData)stage.rollData).factor == this;
398                                // no points if takeover expedition is the event since it'll lead to a reset anyway
399                                if (!thisEvent) {
400                                        int points = Global.getSettings().getInt("HA_tacBombardHesperus");
401                                        if (points > 0) {
402                                                intel.addFactor(new HAHersperusTacBombardmentFactor(-points));
403                                        }
404                                }
405                        }
406
407                }
408        }
409
410        public void reportSaturationBombardmentFinished(InteractionDialogAPI dialog, MarketAPI market, TempData actionData) {
411                
412        }
413
414        @Override
415        public void advance(float amount) {
416                super.advance(amount);
417                
418//              if (!Global.getSector().getListenerManager().hasListener(this)) {
419//                      Global.getSector().getListenerManager().addListener(this);
420//              }
421                
422                EventStageData stage = intel.getDataFor(Stage.HA_EVENT);
423                if (stage != null && stage.rollData instanceof HAERandomEventData && 
424                                ((HAERandomEventData)stage.rollData).factor == this) {
425                        MarketAPI hesperus = getHesperus(true);
426                        
427                        if (hesperus == null) {
428                                intel.resetHA_EVENT();
429                        }                       
430                }
431        }
432        public void reportColonySizeChanged(MarketAPI market, int prevSize) {
433                if (!market.isPlayerOwned()) return;
434                
435                boolean matches = LuddicMajority.matchesBonusConditions(market);
436                
437                if (market.hasCondition(Conditions.LUDDIC_MAJORITY) && !matches) {
438                        market.removeCondition(Conditions.LUDDIC_MAJORITY);
439                } else if (!market.hasCondition(Conditions.LUDDIC_MAJORITY) && matches) {
440                        market.addCondition(Conditions.LUDDIC_MAJORITY);
441                }
442                
443        }
444        
445        
446        
447}
448
449
450
451