001package com.fs.starfarer.api.impl.campaign.intel.events;
002
003import java.util.List;
004import java.util.Random;
005
006import java.awt.Color;
007
008import org.lwjgl.util.vector.Vector2f;
009
010import com.fs.starfarer.api.Global;
011import com.fs.starfarer.api.campaign.CampaignFleetAPI;
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.impl.campaign.ids.Conditions;
017import com.fs.starfarer.api.impl.campaign.ids.Factions;
018import com.fs.starfarer.api.impl.campaign.ids.FleetTypes;
019import com.fs.starfarer.api.impl.campaign.ids.Industries;
020import com.fs.starfarer.api.impl.campaign.ids.Stats;
021import com.fs.starfarer.api.impl.campaign.intel.events.BaseEventIntel.EventStageData;
022import com.fs.starfarer.api.impl.campaign.intel.events.HostileActivityEventIntel.HAERandomEventData;
023import com.fs.starfarer.api.impl.campaign.intel.events.HostileActivityEventIntel.Stage;
024import com.fs.starfarer.api.impl.campaign.intel.events.TriTachyonStandardActivityCause.CompetitorData;
025import com.fs.starfarer.api.impl.campaign.intel.group.FGRaidAction.FGRaidType;
026import com.fs.starfarer.api.impl.campaign.intel.group.FleetGroupIntel;
027import com.fs.starfarer.api.impl.campaign.intel.group.FleetGroupIntel.FGIEventListener;
028import com.fs.starfarer.api.impl.campaign.intel.group.GenericRaidFGI.GenericRaidParams;
029import com.fs.starfarer.api.impl.campaign.intel.group.SindrianDiktatPunitiveExpedition;
030import com.fs.starfarer.api.impl.campaign.missions.FleetCreatorMission;
031import com.fs.starfarer.api.impl.campaign.missions.FleetCreatorMission.FleetStyle;
032import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.MarketCMD.BombardType;
033import com.fs.starfarer.api.ui.LabelAPI;
034import com.fs.starfarer.api.ui.TooltipMakerAPI;
035import com.fs.starfarer.api.ui.TooltipMakerAPI.TooltipCreator;
036import com.fs.starfarer.api.util.CountingMap;
037import com.fs.starfarer.api.util.Misc;
038
039public class SindrianDiktatHostileActivityFactor extends BaseHostileActivityFactor 
040                                                        implements FGIEventListener {
041
042        public static String DEFEATED_DIKTAT_ATTACK = "$defeatedDiktatAttack";
043        public static String MADE_DIKTAT_DEAL = "$makeDiktatDeal";
044        public static String BROKE_DIKTAT_DEAL = "$brokeDiktatDeal";
045        
046        public static String RAIDER_FLEET = "$diktatRaider";
047        
048        public static boolean isMadeDeal() {
049                return Global.getSector().getPlayerMemoryWithoutUpdate().getBoolean(MADE_DIKTAT_DEAL);
050        }
051        public static void setMadeDeal(boolean value) {
052                Global.getSector().getPlayerMemoryWithoutUpdate().set(MADE_DIKTAT_DEAL, value);
053        }
054        
055        public static boolean brokeDeal() {
056                return Global.getSector().getPlayerMemoryWithoutUpdate().getBoolean(BROKE_DIKTAT_DEAL);
057        }
058        public static void setBrokeDeal(boolean broke) {
059                Global.getSector().getPlayerMemoryWithoutUpdate().set(BROKE_DIKTAT_DEAL, broke);
060        }
061        
062        public static boolean isPlayerDefeatedDiktatAttack() {
063                return Global.getSector().getPlayerMemoryWithoutUpdate().getBoolean(DEFEATED_DIKTAT_ATTACK);
064        }
065        public static void setPlayerDefeatedDiktatAttack() {
066                Global.getSector().getPlayerMemoryWithoutUpdate().set(DEFEATED_DIKTAT_ATTACK, true);
067        }
068        
069        public SindrianDiktatHostileActivityFactor(HostileActivityEventIntel intel) {
070                super(intel);
071                
072                //Global.getSector().getListenerManager().addListener(this);
073        }
074        
075        public String getProgressStr(BaseEventIntel intel) {
076                return "";
077        }
078        
079        public String getDesc(BaseEventIntel intel) {
080                return "Sindrian Diktat";
081        }
082        
083        public String getNameForThreatList(boolean first) {
084                return "Sindrian Diktat";
085        }
086
087
088        public Color getDescColor(BaseEventIntel intel) {
089                if (getProgress(intel) <= 0) {
090                        return Misc.getGrayColor();
091                }
092                return Global.getSector().getFaction(Factions.DIKTAT).getBaseUIColor();
093        }
094
095        public TooltipCreator getMainRowTooltip(BaseEventIntel intel) {
096                return new BaseFactorTooltip() {
097                        public void createTooltip(TooltipMakerAPI tooltip, boolean expanded, Object tooltipParam) {
098                                float opad = 10f;
099                                tooltip.addPara("You've attracted the attention of the Sindrian Diktat.", 0f);
100                                
101                                tooltip.addPara("Sindrian raider fleets have been sighted in your space, "
102                                                + "attacking trade fleets regardless of their factional allegiance.", opad);
103                        }
104                };
105        }
106
107        public boolean shouldShow(BaseEventIntel intel) {
108                return getProgress(intel) > 0;
109        }
110
111        @Override
112        public int getProgress(BaseEventIntel intel) {
113                if (!checkFactionExists(Factions.DIKTAT, true)) {
114                        return 0;
115                }
116                return super.getProgress(intel);
117        }
118        
119        public Color getNameColor(float mag) {
120                if (mag <= 0f) {
121                        return Misc.getGrayColor();
122                }
123                return Global.getSector().getFaction(Factions.DIKTAT).getBaseUIColor();
124        }
125        
126        
127        @Override
128        public int getMaxNumFleets(StarSystemAPI system) {
129                return Global.getSettings().getInt("diktatMaxFleets");
130        }
131        
132        public CampaignFleetAPI createFleet(StarSystemAPI system, Random random) {
133        
134                float f = intel.getMarketPresenceFactor(system);
135                
136                int difficulty = 4 + (int) Math.round(f * 4f);
137                
138                FleetCreatorMission m = new FleetCreatorMission(random);
139                m.beginFleet();
140                
141                Vector2f loc = system.getLocation();
142                String factionId = Factions.DIKTAT;
143                
144                m.createQualityFleet(difficulty, factionId, loc);
145                
146                m.triggerSetFleetType(FleetTypes.RAIDER);
147                
148                m.triggerSetPirateFleet();
149                m.triggerMakeHostile();
150                m.triggerMakeNonHostileToFaction(Factions.DIKTAT);
151                m.triggerMakeNonHostileToFaction(Factions.PIRATES);
152                m.triggerMakeLowRepImpact();
153                m.triggerFleetAllowLongPursuit();
154                m.triggerMakeHostileToAllTradeFleets();
155                m.triggerMakeEveryoneJoinBattleAgainst();
156                
157                m.triggerSetFleetFlag(RAIDER_FLEET);
158                
159                m.triggerFleetMakeFaster(true, 0, true);
160                
161                //m.triggerSetFleetMaxShipSize(3);
162                
163                
164                CampaignFleetAPI fleet = m.createFleet();
165
166                return fleet;
167        }
168        
169
170        
171        
172        public void addBulletPointForEvent(HostileActivityEventIntel intel, EventStageData stage, TooltipMakerAPI info,
173                                                                                 ListInfoMode mode, boolean isUpdate, Color tc, float initPad) {
174                Color c = Global.getSector().getFaction(Factions.DIKTAT).getBaseUIColor();
175                info.addPara("Impending Sindrian Diktat attack", initPad, tc, c, "Sindrian Diktat");
176        }
177        
178        public void addBulletPointForEventReset(HostileActivityEventIntel intel, EventStageData stage, TooltipMakerAPI info,
179                        ListInfoMode mode, boolean isUpdate, Color tc, float initPad) {
180                info.addPara("Sindrian Diktat attack averted", tc, initPad);
181        }
182        
183        public void addStageDescriptionForEvent(HostileActivityEventIntel intel, EventStageData stage, TooltipMakerAPI info) {
184                float small = 0f;
185                float opad = 10f;
186                
187                small = 8f;
188
189                Color c = Global.getSector().getFaction(Factions.DIKTAT).getBaseUIColor();
190                
191                Color h = Misc.getHighlightColor();
192                info.addPara("You've received intel that the Sindrian Diktat is planning an attack to "
193                                + "saturation-bombard your fuel production facilities.",
194                                small, Misc.getNegativeHighlightColor(), "saturation-bombard");
195
196//              LabelAPI label = info.addPara("If the attack is defeated, your standing with the Hegemony "
197//                              + "and the independents will increase substantially, and the Diktat will likely abandon "
198//                              + "further efforts against you. In addition, your ability to export fuel will be improved.", 
199//                              opad);
200//              label.setHighlight("Hegemony", "independents", "increase substantially", "Diktat",
201//                              "ability to export fuel will be improved");
202//              label.setHighlightColors(Global.getSector().getFaction(Factions.HEGEMONY).getBaseUIColor(),
203//                              Global.getSector().getFaction(Factions.INDEPENDENT).getBaseUIColor(),
204//                              Misc.getPositiveHighlightColor(),
205//                              Global.getSector().getFaction(Factions.DIKTAT).getBaseUIColor(),
206//                              Misc.getPositiveHighlightColor());
207                
208                LabelAPI label = info.addPara("If the attack is defeated the Diktat will likely abandon "
209                                + "further efforts against you, and your ability to export fuel will be improved.", 
210                                opad);
211                label.setHighlight("Diktat",
212                                "export fuel", "improved");
213                label.setHighlightColors(
214                                Global.getSector().getFaction(Factions.DIKTAT).getBaseUIColor(),
215                                Misc.getPositiveHighlightColor(),
216                                Misc.getPositiveHighlightColor());
217                
218                c = Global.getSector().getFaction(Factions.DIKTAT).getBaseUIColor();
219                stage.beginResetReqList(info, true, "crisis", opad);
220                info.addPara("You go to %s and make an agreement with the Diktat", 0f, c, "Sindria");
221                info.addPara("%s is tactically bombarded", 0f, c, "Sindria");
222                info.addPara("Fuel production on %s is significantly disrupted", 0f, c, "Sindria");
223                stage.endResetReqList(info, false, "crisis", -1, -1);
224                
225                addBorder(info, Global.getSector().getFaction(Factions.DIKTAT).getBaseUIColor());
226        }
227        
228        
229        public String getEventStageIcon(HostileActivityEventIntel intel, EventStageData stage) {
230                return Global.getSector().getFaction(Factions.DIKTAT).getCrest();
231        }
232
233        public TooltipCreator getStageTooltipImpl(final HostileActivityEventIntel intel, final EventStageData stage) {
234                if (stage.id == Stage.HA_EVENT) {
235                        return getDefaultEventTooltip("Sindrian Diktat attack", intel, stage);
236                }
237                return null;
238        }
239        
240        public static Industry getSindrianFuelProd() {
241                MarketAPI sindria = getSindria(false);
242                if (sindria == null) return null;
243                
244                Industry prod = sindria.getIndustry(Industries.FUELPROD);
245                return prod;
246        }
247        
248        public static MarketAPI getSindria(boolean requireMilitaryBase) {
249                MarketAPI sindria = Global.getSector().getEconomy().getMarket("sindria");
250                if (sindria == null || sindria.hasCondition(Conditions.DECIVILIZED) ||
251                                !sindria.getFactionId().equals(Factions.DIKTAT)) {
252                        return null;
253                }
254                if (requireMilitaryBase) {
255                        Industry b = sindria.getIndustry(Industries.MILITARYBASE);
256                        if (b == null) b = sindria.getIndustry(Industries.HIGHCOMMAND);
257                        if (b == null || b.isDisrupted() || !b.isFunctional()) {
258                                return null;
259                        }
260                }
261                return sindria;
262        }
263        
264        
265        public float getEventFrequency(HostileActivityEventIntel intel, EventStageData stage) {
266                if (stage.id == Stage.HA_EVENT) {
267                        
268                        if (isPlayerDefeatedDiktatAttack() || getSindria(true) == null) {
269                                return 0f;
270                        }
271                        
272                        if (isMadeDeal()) return 0f;
273                        
274                        if (SindrianDiktatPunitiveExpedition.get() != null) {
275                                return 0f;
276                        }
277                        
278                        MarketAPI target = findExpeditionTarget(intel, stage);
279                        MarketAPI source = getSindria(true);
280                        if (target != null && source != null) {
281                                return 10f;
282                        }
283                }
284                return 0;
285        }
286        
287
288        public void rollEvent(HostileActivityEventIntel intel, EventStageData stage) {
289                HAERandomEventData data = new HAERandomEventData(this, stage);
290                stage.rollData = data;
291                intel.sendUpdateIfPlayerHasIntel(data, false);
292        }
293        
294        public boolean fireEvent(HostileActivityEventIntel intel, EventStageData stage) {
295                MarketAPI target = findExpeditionTarget(intel, stage);
296                MarketAPI source = getSindria(true);
297                
298                if (source == null || target == null) {
299                        return false;
300                }
301        
302                stage.rollData = null;
303                return startAttack(source, target, target.getStarSystem(), stage, getRandomizedStageRandom(3));
304        }
305        
306        
307        public static MarketAPI findExpeditionTarget(HostileActivityEventIntel intel, EventStageData stage) {
308                List<CompetitorData> data = SindrianDiktatStandardActivityCause.computePlayerCompetitionData();
309                CountingMap<MarketAPI> counts = new CountingMap<MarketAPI>();
310                
311                for (CompetitorData curr : data) {
312                        for (MarketAPI market : curr.competitorProducers) {
313                                StarSystemAPI system = market.getStarSystem();
314                                if (system == null) continue;
315                                int weight = market.getCommodityData(curr.commodityId).getMaxSupply();
316                                counts.add(market, weight);
317                        }
318                }
319                
320                return counts.getLargest();
321        }
322        
323        
324        public void reportFGIAborted(FleetGroupIntel intel) {
325                setPlayerDefeatedDiktatAttack();
326                
327                DiktatFuelBonusScript.grantBonus();
328        }
329
330        
331        @Override
332        public void notifyFactorRemoved() {
333                //Global.getSector().getListenerManager().removeListener(this);
334        }
335
336        public void notifyEventEnding() {
337                notifyFactorRemoved();
338        }
339
340
341        @Override
342        public void advance(float amount) {
343                super.advance(amount);
344                
345//              float days = Misc.getDays(amount);
346                
347//              if (!Global.getSector().getListenerManager().hasListener(this)) {
348//                      Global.getSector().getListenerManager().addListener(this);
349//              }
350                
351//              String key = "$wdfwefwe";
352//              if (!Global.getSector().getMemoryWithoutUpdate().getBoolean(key)) {
353//                      MarketAPI target = findExpeditionTarget(intel, null);
354//                      MarketAPI source = getSindria(true);
355//                      startAttack(source, target, target.getStarSystem(), null, new Random());
356//                      Global.getSector().getMemoryWithoutUpdate().set(key, true);
357//              }
358                
359                EventStageData stage = intel.getDataFor(Stage.HA_EVENT);
360                if (stage != null && stage.rollData instanceof HAERandomEventData && 
361                                ((HAERandomEventData)stage.rollData).factor == this) {
362                        
363                        Industry prod = getSindrianFuelProd();
364                        boolean prodOk = prod != null && prod.getSpecialItem() != null && !prod.isDisrupted();
365                        if (getSindria(true) == null || !prodOk) {
366                                intel.resetHA_EVENT();
367                        }
368                }
369
370        }
371        
372
373        
374        public boolean startAttack(MarketAPI source, MarketAPI target, StarSystemAPI system, EventStageData stage, Random random) {
375                GenericRaidParams params = new GenericRaidParams(new Random(random.nextLong()), true);
376                
377                params.makeFleetsHostile = false; // will be made hostile when they arrive, not before
378                
379                params.factionId = source.getFactionId();
380                params.source = source;
381                
382                params.prepDays = 14f + random.nextFloat() * 14f;
383                params.payloadDays = 27f + 7f * random.nextFloat();
384                
385                params.raidParams.where = system;
386                params.raidParams.type = FGRaidType.SEQUENTIAL;
387                params.raidParams.tryToCaptureObjectives = false;
388                params.raidParams.allowedTargets.add(target);
389                params.raidParams.allowNonHostileTargets = true;
390                params.raidParams.setBombardment(BombardType.SATURATION);
391                
392                params.style = FleetStyle.STANDARD;
393                
394                
395                // standard Askonia fleet size multiplier with no shortages/issues is a bit over 230%
396                float fleetSizeMult = source.getStats().getDynamic().getMod(Stats.COMBAT_FLEET_SIZE_MULT).computeEffective(0f);
397                
398                float f = intel.getMarketPresenceFactor(system);
399                
400                float totalDifficulty = fleetSizeMult * 15f * (0.6f + 0.4f * f);
401                
402                if (totalDifficulty < 15) {
403                        return false;
404                }
405                if (totalDifficulty > 100) {
406                        totalDifficulty = 100;
407                }
408                
409                totalDifficulty -= 10;
410                
411                params.fleetSizes.add(10);
412                
413                while (totalDifficulty > 0) {
414                        int min = 6;
415                        int max = 10;
416                        
417                        //int diff = Math.round(StarSystemGenerator.getNormalRandom(random, min, max));
418                        int diff = min + random.nextInt(max - min + 1);
419                        
420                        params.fleetSizes.add(diff);
421                        totalDifficulty -= diff;
422                }
423                
424                
425                SindrianDiktatPunitiveExpedition punex = new SindrianDiktatPunitiveExpedition(params);
426                punex.setListener(this);
427                Global.getSector().getIntelManager().addIntel(punex);
428                
429//              GenericRaidFGI raid = new GenericRaidFGI(params);
430//              raid.setListener(this);
431//              Global.getSector().getIntelManager().addIntel(raid);
432                
433                return true;
434        }
435        
436}
437
438
439
440