001package com.fs.starfarer.api.impl.campaign;
002
003import java.util.HashSet;
004import java.util.Set;
005
006import java.awt.Color;
007
008import org.json.JSONObject;
009
010import com.fs.starfarer.api.Global;
011import com.fs.starfarer.api.PluginPick;
012import com.fs.starfarer.api.campaign.AICoreAdminPlugin;
013import com.fs.starfarer.api.campaign.AICoreOfficerPlugin;
014import com.fs.starfarer.api.campaign.BaseCampaignPlugin;
015import com.fs.starfarer.api.campaign.BattleAPI;
016import com.fs.starfarer.api.campaign.BattleAutoresolverPlugin;
017import com.fs.starfarer.api.campaign.BattleCreationPlugin;
018import com.fs.starfarer.api.campaign.CampaignFleetAPI;
019import com.fs.starfarer.api.campaign.CampaignTerrainAPI;
020import com.fs.starfarer.api.campaign.CampaignTerrainPlugin;
021import com.fs.starfarer.api.campaign.CargoStackAPI;
022import com.fs.starfarer.api.campaign.CustomEntitySpecAPI;
023import com.fs.starfarer.api.campaign.FactionAPI;
024import com.fs.starfarer.api.campaign.FleetInflater;
025import com.fs.starfarer.api.campaign.FleetStubAPI;
026import com.fs.starfarer.api.campaign.FleetStubConverterPlugin;
027import com.fs.starfarer.api.campaign.InteractionDialogPlugin;
028import com.fs.starfarer.api.campaign.JumpPointAPI;
029import com.fs.starfarer.api.campaign.PersonImportance;
030import com.fs.starfarer.api.campaign.PlanetAPI;
031import com.fs.starfarer.api.campaign.RepLevel;
032import com.fs.starfarer.api.campaign.ReputationActionResponsePlugin;
033import com.fs.starfarer.api.campaign.SectorEntityToken;
034import com.fs.starfarer.api.campaign.SubmarketPlugin;
035import com.fs.starfarer.api.campaign.ai.AbilityAIPlugin;
036import com.fs.starfarer.api.campaign.ai.CampaignFleetAIAPI;
037import com.fs.starfarer.api.campaign.ai.CampaignFleetAIAPI.EncounterOption;
038import com.fs.starfarer.api.campaign.ai.ModularFleetAIAPI;
039import com.fs.starfarer.api.campaign.econ.ImmigrationPlugin;
040import com.fs.starfarer.api.campaign.econ.Industry;
041import com.fs.starfarer.api.campaign.econ.MarketAPI;
042import com.fs.starfarer.api.campaign.econ.MarketAPI.SurveyLevel;
043import com.fs.starfarer.api.campaign.econ.MarketConditionAPI;
044import com.fs.starfarer.api.campaign.econ.MonthlyReport;
045import com.fs.starfarer.api.campaign.econ.SubmarketAPI;
046import com.fs.starfarer.api.campaign.rules.MemoryAPI;
047import com.fs.starfarer.api.characters.AbilityPlugin;
048import com.fs.starfarer.api.characters.ImportantPeopleAPI;
049import com.fs.starfarer.api.characters.ImportantPeopleAPI.PersonDataAPI;
050import com.fs.starfarer.api.characters.PersonAPI;
051import com.fs.starfarer.api.combat.ShipAPI.HullSize;
052import com.fs.starfarer.api.fleet.FleetMemberAPI;
053import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActionEnvelope;
054import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActions;
055import com.fs.starfarer.api.impl.campaign.fleets.DefaultFleetInflater;
056import com.fs.starfarer.api.impl.campaign.fleets.DefaultFleetInflaterParams;
057import com.fs.starfarer.api.impl.campaign.ids.Commodities;
058import com.fs.starfarer.api.impl.campaign.ids.Factions;
059import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
060import com.fs.starfarer.api.impl.campaign.ids.Strings;
061import com.fs.starfarer.api.impl.campaign.ids.Tags;
062import com.fs.starfarer.api.impl.campaign.intel.bases.PirateBaseManager;
063import com.fs.starfarer.api.impl.campaign.intel.contacts.ContactIntel;
064import com.fs.starfarer.api.impl.campaign.population.CoreImmigrationPluginImpl;
065import com.fs.starfarer.api.impl.campaign.shared.PlayerTradeDataForSubmarket;
066import com.fs.starfarer.api.impl.campaign.shared.SharedData;
067import com.fs.starfarer.api.impl.campaign.tutorial.CampaignTutorialScript;
068import com.fs.starfarer.api.impl.campaign.tutorial.TutorialMissionIntel;
069import com.fs.starfarer.api.impl.campaign.tutorial.TutorialRespawnDialogPluginImpl;
070import com.fs.starfarer.api.impl.combat.BattleCreationPluginImpl;
071import com.fs.starfarer.api.plugins.AutofitPlugin;
072import com.fs.starfarer.api.plugins.impl.CoreAutofitPlugin;
073import com.fs.starfarer.api.util.Misc;
074
075public class CoreCampaignPluginImpl extends BaseCampaignPlugin {
076
077        public String getId() {
078                return "coreCampaignPluginImpl";
079        }
080        
081        public boolean isTransient() {
082                return false;
083        }
084
085        public PluginPick<InteractionDialogPlugin> pickInteractionDialogPlugin(SectorEntityToken interactionTarget) {
086                if (interactionTarget.hasTag(Tags.OBJECTIVE) || interactionTarget.getMarket() != null) {
087                        return new PluginPick<InteractionDialogPlugin>(new RuleBasedInteractionDialogPluginImpl(), PickPriority.CORE_GENERAL);
088                }
089                
090                if (interactionTarget.hasTag(Tags.GATE)) {
091                        return new PluginPick<InteractionDialogPlugin>(new RuleBasedInteractionDialogPluginImpl(), PickPriority.CORE_GENERAL);
092                }
093                
094                if (interactionTarget.hasTag(Tags.STATION)) {
095                        return new PluginPick<InteractionDialogPlugin>(new RuleBasedInteractionDialogPluginImpl(), PickPriority.CORE_GENERAL);
096                }
097                
098                if (interactionTarget.hasTag(Tags.HAS_INTERACTION_DIALOG)) {
099                        return new PluginPick<InteractionDialogPlugin>(new RuleBasedInteractionDialogPluginImpl(), PickPriority.CORE_GENERAL);
100                }
101                
102//              if ((interactionTarget instanceof OrbitalStationAPI ||
103//                              interactionTarget.hasTag("station")) ||
104//                              interactionTarget.getMarket() != null) {
105                if (interactionTarget.getMarket() != null) {
106                        return new PluginPick<InteractionDialogPlugin>(new OrbitalStationInteractionDialogPluginImpl(), PickPriority.CORE_GENERAL);
107                }
108                
109                if (interactionTarget instanceof CampaignFleetAPI) {
110                        return new PluginPick<InteractionDialogPlugin>(new FleetInteractionDialogPluginImpl(), PickPriority.CORE_GENERAL);
111                }
112                if (interactionTarget instanceof JumpPointAPI) {
113                        return new PluginPick<InteractionDialogPlugin>(new JumpPointInteractionDialogPluginImpl(), PickPriority.CORE_GENERAL);
114                }
115                if (interactionTarget instanceof PlanetAPI) {
116                        return new PluginPick<InteractionDialogPlugin>(new PlanetInteractionDialogPluginImpl(), PickPriority.CORE_GENERAL);
117                }
118                return null;
119        }
120        
121        public PluginPick<InteractionDialogPlugin> pickInteractionDialogPlugin(Object param, SectorEntityToken interactionTarget) {
122                return null;
123        }
124        
125
126        @Override
127        public PluginPick<AbilityAIPlugin> pickAbilityAI(AbilityPlugin ability, ModularFleetAIAPI ai) {
128                if (ability == null) return null;
129                String id = ability.getId();
130                if (id == null) return null;
131                
132                if (ability.getSpec().getAIPluginClass() != null) {
133                        return new PluginPick<AbilityAIPlugin>(ability.getSpec().getNewAIPluginInstance(ability), PickPriority.CORE_GENERAL);
134                } else {
135                        return null;
136                }
137                
138//              if (id.equals(Abilities.GO_DARK)) {
139//                      return new PluginPick<AbilityAIPlugin>(new GoDarkAbilityAI(ability, ai), PickPriority.CORE_GENERAL);
140//              } else if (id.equals(Abilities.EMERGENCY_BURN)) {
141//                      return new PluginPick<AbilityAIPlugin>(new EmergencyBurnAbilityAI(ability, ai), PickPriority.CORE_GENERAL);
142//              } else if (id.equals(Abilities.SENSOR_BURST)) {
143//                      return new PluginPick<AbilityAIPlugin>(new SensorBurstAbilityAI(ability, ai), PickPriority.CORE_GENERAL);
144//              } else if (id.equals(Abilities.TRANSPONDER)) {
145//                      return new PluginPick<AbilityAIPlugin>(new TransponderAbilityAI(ability, ai), PickPriority.CORE_GENERAL);
146//              }
147//              return null;
148        }
149
150        
151        
152        
153        public PluginPick<BattleCreationPlugin> pickBattleCreationPlugin(SectorEntityToken opponent) {
154                if (opponent instanceof CampaignFleetAPI) {
155                        return new PluginPick<BattleCreationPlugin>(new BattleCreationPluginImpl(), PickPriority.CORE_GENERAL);
156                }
157                return null;
158        }
159        
160        
161        public PluginPick<BattleAutoresolverPlugin> pickBattleAutoresolverPlugin(BattleAPI battle) {
162                return new PluginPick<BattleAutoresolverPlugin>(
163                                                new BattleAutoresolverPluginImpl(battle),
164                                                PickPriority.CORE_GENERAL
165                                   );
166        }
167        
168
169        @Override
170        public PluginPick<ReputationActionResponsePlugin> pickReputationActionResponsePlugin(Object action, String factionId) {
171                if (action instanceof RepActions || action instanceof RepActionEnvelope) {
172                        return new PluginPick<ReputationActionResponsePlugin>(
173                                                        new CoreReputationPlugin(),
174                                                        PickPriority.CORE_GENERAL
175                                           );
176                }
177                return null;
178        }
179        
180        @Override
181        public PluginPick<ReputationActionResponsePlugin> pickReputationActionResponsePlugin(Object action, PersonAPI person) {
182                if (action instanceof RepActions || action instanceof RepActionEnvelope) {
183                        return new PluginPick<ReputationActionResponsePlugin>(
184                                                        new CoreReputationPlugin(),
185                                                        PickPriority.CORE_GENERAL
186                                           );
187                }
188                return null;
189        }
190
191        
192        @Override
193        public void updateEntityFacts(SectorEntityToken entity, MemoryAPI memory) {
194                for (String tag : entity.getTags()) {
195                        memory.set("$tag:" + tag, true, 0);
196                }
197                
198                memory.set("$abyssalDepth", Misc.getAbyssalDepth(entity), 0);
199                memory.set("$abyssalDepthUncapped", Misc.getAbyssalDepth(entity, true), 0);
200                
201                String onOrAt = "on";
202                if (entity.hasTag(Tags.STATION)) {
203                        onOrAt = "at";
204                }
205                memory.set("$onOrAt", onOrAt, 0);
206                
207                if (entity.getStarSystem() != null && 
208                                entity.getStarSystem().hasTag(Tags.SYSTEM_CUT_OFF_FROM_HYPER)) {
209                        memory.set("$systemCutOffFromHyper", true, 0);
210                }
211                
212                if (entity.getContainingLocation() != null) {
213                        memory.set("$locationId", entity.getContainingLocation().getId(), 0f);
214                }
215                
216                CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet();
217                
218                memory.set("$id", entity.getId(), 0);
219                
220                memory.set("$transponderOn", entity.isTransponderOn(), 0);
221                
222//              if (entity.getMarket() != null) {
223//                      memory.set("$market", entity.getMarket().getName(), 0);
224//              }
225                
226                memory.set("$name", entity.getName(), 0);
227                memory.set("$fullName", entity.getFullName(), 0);
228                
229                memory.set("$inHyperspace", entity.isInHyperspace(), 0);
230                
231                
232                if (entity.getCustomEntityType() != null) {
233                        memory.set("$customType", entity.getCustomEntityType(), 0);
234                        
235                        if (entity.getCustomEntitySpec() != null) {
236                                CustomEntitySpecAPI spec = entity.getCustomEntitySpec();
237                                memory.set("$nameInText", spec.getNameInText(), 0);
238                                memory.set("$shortName", spec.getShortName(), 0);
239                                memory.set("$isOrAre", spec.getIsOrAre(), 0);
240                                memory.set("$aOrAn", spec.getAOrAn(), 0);
241                        }
242                }
243                
244                if (entity instanceof CampaignTerrainAPI) {
245                        CampaignTerrainAPI terrain = (CampaignTerrainAPI) entity;
246                        CampaignTerrainPlugin plugin = terrain.getPlugin();
247                        memory.set("$terrainId", plugin.getSpec().getId(), 0);
248                }
249                
250                
251                if (entity instanceof CampaignFleetAPI) {
252                        CampaignFleetAPI fleet = (CampaignFleetAPI) entity;
253                        if (fleet.getAI() instanceof CampaignFleetAIAPI) {
254                                CampaignFleetAIAPI ai = (CampaignFleetAIAPI) fleet.getAI();
255                                EncounterOption option = ai.pickEncounterOption(null, playerFleet, true);
256                                BattleAPI b = fleet.getBattle();
257                                if (b != null && b.isPlayerInvolved()) {
258                                        b.genCombined();
259                                        option = b.getCombinedFor(fleet).getAI().pickEncounterOption(null, b.getCombinedFor(Global.getSector().getPlayerFleet()), true);
260                                }
261                                
262                                switch (option) {
263                                case DISENGAGE:
264                                        memory.set("$relativeStrength", -1, 0);
265                                        break;
266                                case ENGAGE:
267                                        memory.set("$relativeStrength", 1, 0);
268                                        break;
269                                case HOLD:
270                                        memory.set("$relativeStrength", 0, 0);
271                                        break;
272                                case HOLD_VS_STRONGER:
273                                        memory.set("$weakerThanPlayerButHolding", true, 0);
274                                        memory.set("$relativeStrength", -1, 0);
275                                        break;
276                                }
277                                
278                                memory.set("$isHostile", ai.isHostileTo(playerFleet), 0);
279                                
280                                memory.set("$fleetPoints", fleet.getFleetPoints(), 0);
281                        }
282                        
283                        memory.set("$isStation", fleet.isStationMode(), 0); 
284                        
285                        memory.set("$supplies", fleet.getCargo().getSupplies(), 0);
286                        memory.set("$fuel", fleet.getCargo().getFuel(), 0);
287                        
288                        memory.set("$knowsWhoPlayerIs", fleet.knowsWhoPlayerIs(), 0);
289                        
290                        if (!playerFleet.isTransponderOn() && !memory.contains(MemFlags.MEMORY_KEY_SAW_PLAYER_WITH_TRANSPONDER_OFF)) {
291                                memory.set(MemFlags.MEMORY_KEY_SAW_PLAYER_WITH_TRANSPONDER_OFF, true, 0);
292                        }
293                        
294                        if (!Misc.isPermaKnowsWhoPlayerIs(fleet) && playerFleet.isTransponderOn()) {
295                                memory.set(MemFlags.MEMORY_KEY_SAW_PLAYER_WITH_TRANSPONDER_ON, true, 7f + (float) Math.random() * 7f);
296                        }
297                }
298                
299                if (entity.getFaction() != null && !memory.contains("$isHostile")) {
300                        float rel = entity.getFaction().getRelationship(Factions.PLAYER);
301                        RepLevel level = RepLevel.getLevelFor(rel);
302                        if (level.isAtWorst(RepLevel.INHOSPITABLE)) {
303                                memory.set("$isHostile", false, 0);
304                        } else {
305                                memory.set("$isHostile", true, 0);
306                        }
307                }
308                
309                
310                MarketAPI market = entity.getMarket();
311                if (market != null) {
312//                      for (MarketConditionAPI mc : market.getConditions()) {
313//                              memory.set("$mc:" + mc.getId(), true, 0);
314//                      }
315                        if (!market.isPlanetConditionMarketOnly()) {
316                                memory.set("$hasMarket", true, 0);
317                        }
318                        
319                        if (Misc.getStationFleet(market) != null) {
320                                memory.set("$hasStation", true, 0);
321                        }
322                        
323                        memory.set("$marketSize", market.getSize(), 0);
324                        memory.set("$stability", (int) market.getStabilityValue(), 0);
325                }
326                
327                if (entity instanceof PlanetAPI) {
328                        PlanetAPI planet = (PlanetAPI) entity;
329                        memory.set("$planetType", planet.getTypeId(), 0);
330                }
331        }
332        
333        public void updateMarketFacts(MarketAPI market, MemoryAPI memory) {
334                if (market != null) {
335                        for (String tag : market.getTags()) {
336                                memory.set("$tag:" + tag, true, 0);
337                        }
338                        for (MarketConditionAPI mc : market.getConditions()) {
339                                memory.set("$mc:" + mc.getId(), true, 0);
340                        }
341                        for (Industry ind : market.getIndustries()) {
342                                memory.set("$ind:" + ind.getId(), true, 0);
343                        }
344                        
345                        memory.set("$id", market.getId(), 0);
346                        memory.set("$size", market.getSize(), 0);
347                        memory.set("$stability", (int) market.getStabilityValue(), 0);
348                        
349                        memory.set("$isSurveyed", market.getSurveyLevel() == SurveyLevel.FULL, 0);
350                        memory.set("$surveyLevel", market.getSurveyLevel().name(), 0);
351                        memory.set("$isPlanetConditionMarketOnly", market.isPlanetConditionMarketOnly(), 0);
352                        
353                        float daysExisted = market.getDaysInExistence();
354                        memory.set("$daysExisted", daysExisted, 0);
355                        
356                        memory.set("$isHidden", market.isHidden(), 0);
357                        
358                        memory.set("$isPlayerOwned", market.isPlayerOwned(), 0);
359                        
360                        boolean hasRuins = false;
361                        if (Misc.hasRuins(market)) {
362                                memory.set("$hasRuins", true, 0);
363                                hasRuins = true;
364                        }
365                        
366                        //boolean ruinsExlored = memory.getBoolean("$ruinsExplored");
367                        
368                        memory.set("$hasUnexploredRuins", Misc.hasUnexploredRuins(market), 0);
369                        
370                        
371                        float suspicionLevel = computeSmugglingSuspicionLevel(market);
372                        memory.set(MemFlags.MEMORY_MARKET_SMUGGLING_SUSPICION_LEVEL, suspicionLevel, 0);
373                }
374        }
375        
376//      public static boolean hasUnexploredRuins(MarketAPI market) {
377//              return market != null && market.isPlanetConditionMarketOnly() &&
378//                      hasRuins(market) && !market.getMemoryWithoutUpdate().getBoolean("$ruinsExplored");
379//      }
380//      public static boolean hasRuins(MarketAPI market) {
381//              return market != null && 
382//                         (market.hasCondition(Conditions.RUINS_SCATTERED) || 
383//                         market.hasCondition(Conditions.RUINS_WIDESPREAD) ||
384//                         market.hasCondition(Conditions.RUINS_EXTENSIVE) ||
385//                         market.hasCondition(Conditions.RUINS_VAST));
386//      }
387        
388        
389        public static final float computeSmugglingSuspicionLevel(MarketAPI market) {
390                float smugglingTotal = 0f;
391                float tradeTotal = 0f;
392                for (SubmarketAPI submarket : market.getSubmarketsCopy()) {
393                        SubmarketPlugin plugin = submarket.getPlugin();
394                        if (!plugin.isParticipatesInEconomy()) continue;
395                        
396                        PlayerTradeDataForSubmarket tradeData =  SharedData.getData().getPlayerActivityTracker().getPlayerTradeData(submarket);
397                        if (submarket.getFaction().isHostileTo(market.getFaction()) || submarket.getPlugin().isBlackMarket()) {
398                                smugglingTotal += tradeData.getTotalPlayerTradeValue();
399                        } else {
400                                tradeTotal += tradeData.getTotalPlayerTradeValue();
401                        }
402                }
403                
404                float suspicionLevel = 0f;
405                
406                if (smugglingTotal + tradeTotal > 0) {
407                        suspicionLevel = smugglingTotal / (smugglingTotal + tradeTotal);
408                        
409                        //float playerImpactMult = Global.getSettings().getFloat("economyPlayerTradeImpactMult");
410                        //float threshold = 30000f * playerImpactMult * market.getSize();
411                        float threshold = 10000f * market.getSize();
412                        suspicionLevel *= Math.min(1f, (smugglingTotal + tradeTotal) / threshold);
413                }
414                
415                float extra = market.getMemoryWithoutUpdate().getFloat(MemFlags.MARKET_EXTRA_SUSPICION);
416                suspicionLevel += extra;
417                suspicionLevel = Math.min(1f, suspicionLevel);
418                
419                return suspicionLevel;
420        }
421        
422        public void updatePersonFacts(PersonAPI person, MemoryAPI memory) {
423                memory.set("$id", person.getId(), 0);
424                
425                for (String tag : person.getTags()) {
426                        memory.set("$tag:" + tag, true, 0);
427                }
428                
429                //int rel = (int)Math.round(person.getRelToPlayer().getRel() * 100f);
430                float rel = person.getRelToPlayer().getRel();
431                memory.set("$relValue", rel, 0);
432                memory.set("$rel", rel, 0); // inconsistent with $faction, oops.
433                memory.set("$relName", person.getRelToPlayer().getLevel().name(), 0);
434                
435                if (Misc.isMercenary(person)) {
436                        memory.set("$mercContractDur", (int)Global.getSettings().getFloat("officerMercContractDur"), 0);
437                        memory.set("$mercContractDurStr", "" + (int)Global.getSettings().getFloat("officerMercContractDur"), 0);
438                }
439                
440                memory.set("$isPerson", true, 0);
441                memory.set("$name", person.getName().getFullName(), 0);
442                memory.set("$personName", person.getName().getFullName(), 0);
443                memory.set("$isContact", ContactIntel.playerHasContact(person, false), 0);
444                
445                memory.set("$rankId", person.getRankId(), 0);
446                memory.set("$postId", person.getPostId(), 0);
447                
448                if (person.isAICore()) {
449                        memory.set("$aiCoreId", person.getAICoreId(), 0);
450                        memory.set("$isAICore", true, 0);
451                }
452                
453                memory.set("$rankAOrAn", person.getRankArticle(), 0);
454                memory.set("$postAOrAn", person.getPostArticle(), 0);
455
456                if (person.getRank() != null) {
457                        memory.set("$rank", person.getRank().toLowerCase(), 0);
458                        memory.set("$Rank", Misc.ucFirst(person.getRank()), 0);
459                }
460                if (person.getPost() != null) {
461                        memory.set("$post", person.getPost().toLowerCase(), 0);
462                        memory.set("$Post", Misc.ucFirst(person.getPost()), 0);
463                }
464                memory.set("$importance", person.getImportance().name(), 0);
465                memory.set("$importanceAtLeastHigh", person.getImportance().ordinal() >= PersonImportance.HIGH.ordinal(), 0);
466                memory.set("$importanceAtMostLow", person.getImportance().ordinal() <= PersonImportance.LOW.ordinal(), 0);
467                
468                memory.set("$level", person.getStats().getLevel(), 0);
469                
470                memory.set("$personality", person.getPersonalityAPI().getId(), 0);
471                
472                ImportantPeopleAPI ip = Global.getSector().getImportantPeople();
473                PersonDataAPI data = ip.getData(person);
474                if (data != null) {
475                        if (data.getLocation().getMarket() != null) {
476                                MarketAPI market = data.getLocation().getMarket();
477                                memory.set("$hostileToMarket", person.getFaction().isHostileTo(market.getFaction()), 0);
478                        }
479                }
480        }
481
482        @Override
483        public void updateFactionFacts(FactionAPI faction, MemoryAPI memory) {
484                memory.set("$id", faction.getId(), 0);
485                
486                float rel = faction.getRelationship(Factions.PLAYER);
487                RepLevel level = RepLevel.getLevelFor(rel);
488                if (level.isAtWorst(RepLevel.FAVORABLE)) {
489                        memory.set("$friendlyToPlayer", true, 0);
490                } else if (level.isAtBest(RepLevel.HOSTILE)) {
491                        memory.set("$hostileToPlayer", true, 0);
492                } else {
493                        memory.set("$neutralToPlayer", true, 0);
494                }
495                
496                if (level.isAtWorst(RepLevel.INHOSPITABLE)) {
497                        memory.set("$isHostile", false, 0);
498                } else {
499                        memory.set("$isHostile", true, 0);
500                }
501                
502                if (JSONObject.getNames(faction.getCustom()) != null) {
503                        for (String key : JSONObject.getNames(faction.getCustom())) {
504                                String val = faction.getCustom().optString(key);
505                                memory.set("$c:" + key, val, 0);
506                        }
507                }
508                Color c = faction.getColor();
509                memory.set("$color", c.getRed() + "," + c.getGreen() + "," + c.getBlue() + "," + c.getAlpha(), 0);
510                
511                c = faction.getBaseUIColor();
512                memory.set("$baseColor", c.getRed() + "," + c.getGreen() + "," + c.getBlue() + "," + c.getAlpha(), 0);
513                
514                c = faction.getBrightUIColor();
515                memory.set("$brightColor", c.getRed() + "," + c.getGreen() + "," + c.getBlue() + "," + c.getAlpha(), 0);
516                
517                c = faction.getDarkUIColor();
518                memory.set("$darkColor", c.getRed() + "," + c.getGreen() + "," + c.getBlue() + "," + c.getAlpha(), 0);
519                
520                c = faction.getGridUIColor();
521                memory.set("$gridColor", c.getRed() + "," + c.getGreen() + "," + c.getBlue() + "," + c.getAlpha(), 0);
522                
523                
524                memory.set("$isNeutralFaction", faction.isNeutralFaction(), 0);
525                
526                memory.set("$relValue", rel, 0);
527                memory.set("$rel", level.name(), 0);
528                memory.set("$relName", level.name(), 0);
529                //memory.set("$relAdjective", level.getDisplayName().toLowerCase(), 0);
530        }
531
532        @Override
533        public void updateGlobalFacts(MemoryAPI memory) {
534                if (Global.getSettings().isDevMode()) {
535                        memory.set("$isDevMode", true, 0);
536                }
537                if (TutorialMissionIntel.isTutorialInProgress()) {
538                        memory.set("$isInTutorial", true, 0);   
539                }
540                
541                if (!memory.getBoolean(GateEntityPlugin.PLAYER_CAN_USE_GATES)) {
542                        memory.set(GateEntityPlugin.PLAYER_CAN_USE_GATES, GateEntityPlugin.canUseGates(), 0);
543                }
544                
545                memory.set("$daysSinceStart", PirateBaseManager.getInstance().getUnadjustedDaysSinceStart(), 0);        
546        }
547
548        @Override
549        public void updatePlayerFacts(MemoryAPI memory) {
550                CampaignFleetAPI fleet = Global.getSector().getPlayerFleet();
551
552                if (fleet != null) {
553                        memory.set("$abyssalDepth", Misc.getAbyssalDepth(fleet), 0);
554                        memory.set("$abyssalDepthUncapped", Misc.getAbyssalDepth(fleet, true), 0);
555                }
556                
557                PersonAPI person = Global.getSector().getPlayerPerson();
558                memory.set("$firstName", person.getName().getFirst(), 0);
559                memory.set("$lastName", person.getName().getLast(), 0);
560                memory.set("$name", person.getName().getFullName(), 0);
561                
562                memory.set("$factionName", Global.getSector().getFaction(Factions.PLAYER).getDisplayNameOverride(), 0);
563                memory.set("$theFactionName", Global.getSector().getFaction(Factions.PLAYER).getDisplayNameWithArticleOverride(), 0);
564                
565                
566                if (Misc.getCommissionFactionId() != null) {
567                        memory.set("$commissionFactionId", Misc.getCommissionFactionId(), 0);
568                }
569                
570                
571                if (fleet.getContainingLocation() != null) {
572                        memory.set("$locationId", fleet.getContainingLocation().getId(), 0);
573                        
574                        for (String tag : fleet.getContainingLocation().getTags()) {
575                                memory.set("$locTag:" + tag, true, 0);  
576                        }
577                }
578                
579                
580                
581                
582                memory.set("$fleetId", fleet.getId(), 0);
583                
584                memory.set("$transponderOn", fleet.isTransponderOn(), 0);
585                
586                memory.set("$supplies", (int)fleet.getCargo().getSupplies(), 0);
587                memory.set("$fuel", (int)fleet.getCargo().getFuel(), 0);
588                memory.set("$machinery", (int)fleet.getCargo().getCommodityQuantity(Commodities.HEAVY_MACHINERY), 0);
589                
590                
591                memory.set("$marines", (int)fleet.getCargo().getMarines(), 0);
592                
593                memory.set("$crew", (int)fleet.getCargo().getCrew(), 0);
594                
595                memory.set("$crewRoom", (int)(fleet.getCargo().getMaxPersonnel() - fleet.getCargo().getTotalPersonnel()), 0);
596                memory.set("$fuelRoom", (int)fleet.getCargo().getMaxFuel() - (int)fleet.getCargo().getFuel(), 0);
597                memory.set("$cargoRoom", (int)fleet.getCargo().getMaxCapacity() - (int)fleet.getCargo().getSpaceUsed(), 0);
598                
599                memory.set("$crewRoomStr", Misc.getWithDGS((int)(fleet.getCargo().getMaxPersonnel() - fleet.getCargo().getTotalPersonnel())), 0);
600                memory.set("$fuelRoomStr", Misc.getWithDGS((int)fleet.getCargo().getMaxFuel() - (int)fleet.getCargo().getFuel()), 0);
601                memory.set("$cargoRoomStr", Misc.getWithDGS((int)fleet.getCargo().getMaxCapacity() - (int)fleet.getCargo().getSpaceUsed()), 0);
602                
603                memory.set("$credits", (int)fleet.getCargo().getCredits().get(), 0);
604                memory.set("$creditsStr", Misc.getWithDGS((int)fleet.getCargo().getCredits().get()), 0);
605                memory.set("$creditsStrC", Misc.getWithDGS((int)fleet.getCargo().getCredits().get()) + Strings.C, 0);
606                
607//              for (CommoditySpecAPI spec : Global.getSettings().getAllCommoditySpecs()) {
608//                      if (spec.isMeta()) continue;
609//              }
610                Set<String> seen = new HashSet<String>();
611                for (CargoStackAPI stack : fleet.getCargo().getStacksCopy()) {
612                        String id = stack.getCommodityId();
613                        if (id == null) continue;
614                        if (seen.contains(id)) continue;
615                        seen.add(id);
616                        
617                        int quantity = (int) fleet.getCargo().getCommodityQuantity(id);
618                        String key = "$" + id;
619                        
620                        if (!memory.contains(key)) {
621                                memory.set(key, quantity, 0);
622                        }
623                }
624                
625                
626                MonthlyReport report = SharedData.getData().getPreviousReport();
627                boolean debt = report.getDebt() > 0;
628                boolean longDebt = report.getDebt() > 0 && report.getPreviousDebt() > 0;
629                memory.set("$inDebt", debt, 0);
630                memory.set("$inLongDebt", longDebt, 0);
631                
632                int fleetSizeCount = fleet.getFleetSizeCount();
633                int maxSize = 0;
634                int maxCombatSize = 0;
635                for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
636                        HullSize size = member.getHullSpec().getHullSize();
637                        int val = 1;
638                        switch (size) {
639                        case CAPITAL_SHIP:
640                                val = 4;
641                                break;
642                        case CRUISER:
643                                val = 3;
644                                break;
645                        case DESTROYER:
646                                val = 2;
647                                break;
648                        case FIGHTER:
649                        case FRIGATE:
650                        case DEFAULT:
651                                val = 1;
652                                break;
653                        }
654                        if (val > maxSize) {
655                                maxSize = val;;
656                        }
657                        if (val > maxCombatSize && !member.isCivilian()) {
658                                maxCombatSize = val;
659                        }
660                }
661                
662                memory.set("$maxHullSize", maxSize, 0);
663                memory.set("$maxCombatHullSize", maxCombatSize, 0);
664                
665                memory.set("$fleetSizeCount", fleetSizeCount, 0);
666                memory.set("$numShips", fleet.getFleetData().getMembersListCopy().size(), 0);
667                memory.set("$fleetPoints", fleet.getFleetPoints(), 0);
668                
669                memory.set("$numColonies", Misc.getPlayerMarkets(true).size(), 0);
670                
671                if (fleet.getFlagship() != null) {
672                        memory.set("$flagshipName", fleet.getFlagship().getShipName(), 0);
673                }
674                
675                for (String id : fleet.getAbilities().keySet()) {
676                        memory.set("$ability:" + id, true, 0);
677                }
678        }
679
680        @Override
681        public PluginPick<FleetStubConverterPlugin> pickStubConverter(CampaignFleetAPI fleet) {
682                return new PluginPick<FleetStubConverterPlugin>(new FleetStubConverterPluginImpl(), PickPriority.CORE_GENERAL);
683        }
684
685        @Override
686        public PluginPick<FleetStubConverterPlugin> pickStubConverter(FleetStubAPI stub) {
687//              if (stub != null && stub.getParams() instanceof FleetParams) {
688//                      return new PluginPick<FleetStubConverterPlugin>(new FleetStubConverterPluginImpl(), PickPriority.CORE_GENERAL);
689//              }
690                return null;
691        }
692        
693        
694        public PluginPick<AutofitPlugin> pickAutofitPlugin(FleetMemberAPI member) {
695                PersonAPI commander = null;
696                if (member != null) {
697                        commander = member.getFleetCommanderForStats();
698                        if (commander == null) commander = member.getFleetCommander();
699                }
700                return new PluginPick<AutofitPlugin>(new CoreAutofitPlugin(commander), PickPriority.CORE_GENERAL);
701        }
702        
703
704        public PluginPick<InteractionDialogPlugin> pickRespawnPlugin() {
705                
706                if (Global.getSector().getMemoryWithoutUpdate().getBoolean(CampaignTutorialScript.USE_TUTORIAL_RESPAWN)) {
707                        return new PluginPick<InteractionDialogPlugin>(new TutorialRespawnDialogPluginImpl(), PickPriority.MOD_SPECIFIC);
708                }
709                //return new PluginPick<InteractionDialogPlugin>(new StandardRespawnDialogPluginImpl(), PickPriority.CORE_GENERAL);
710                return null;
711        }
712        
713        
714        @Override
715        public PluginPick<ImmigrationPlugin> pickImmigrationPlugin(MarketAPI market) {
716                return new PluginPick<ImmigrationPlugin>(new CoreImmigrationPluginImpl(market), PickPriority.CORE_GENERAL);
717        }
718        
719        public PluginPick<AICoreAdminPlugin> pickAICoreAdminPlugin(String commodityId) {
720                if (Commodities.ALPHA_CORE.equals(commodityId)) {
721                        return new PluginPick<AICoreAdminPlugin>(new AICoreAdminPluginImpl(), PickPriority.CORE_GENERAL);
722                }
723                return null;
724        }
725        
726        public PluginPick<AICoreOfficerPlugin> pickAICoreOfficerPlugin(String commodityId) {
727                if (Commodities.OMEGA_CORE.equals(commodityId) ||
728                                Commodities.ALPHA_CORE.equals(commodityId) ||
729                                Commodities.BETA_CORE.equals(commodityId) ||
730                                Commodities.GAMMA_CORE.equals(commodityId)) {
731                        return new PluginPick<AICoreOfficerPlugin>(new AICoreOfficerPluginImpl(), PickPriority.CORE_GENERAL);
732                }
733                return null;
734        }
735        
736        public PluginPick<FleetInflater> pickFleetInflater(CampaignFleetAPI fleet, Object params) {
737                if (params instanceof DefaultFleetInflaterParams) {
738                        DefaultFleetInflaterParams p = (DefaultFleetInflaterParams) params;
739                        return new PluginPick<FleetInflater>(new DefaultFleetInflater(p), PickPriority.CORE_GENERAL);
740                }
741                return null;
742        }
743        
744}
745
746
747
748
749
750
751
752