001package com.fs.starfarer.api.impl.campaign.world;
002
003import java.awt.Color;
004
005import org.lwjgl.util.vector.Vector2f;
006
007import com.fs.starfarer.api.Global;
008import com.fs.starfarer.api.campaign.CampaignFleetAPI;
009import com.fs.starfarer.api.campaign.CargoAPI;
010import com.fs.starfarer.api.campaign.CustomCampaignEntityAPI;
011import com.fs.starfarer.api.campaign.InteractionDialogAPI;
012import com.fs.starfarer.api.campaign.LocationAPI;
013import com.fs.starfarer.api.campaign.NascentGravityWellAPI;
014import com.fs.starfarer.api.campaign.PlanetAPI;
015import com.fs.starfarer.api.campaign.SectorAPI;
016import com.fs.starfarer.api.campaign.SectorEntityToken;
017import com.fs.starfarer.api.campaign.StarSystemAPI;
018import com.fs.starfarer.api.characters.FullName;
019import com.fs.starfarer.api.characters.FullName.Gender;
020import com.fs.starfarer.api.characters.PersonAPI;
021import com.fs.starfarer.api.combat.BattleCreationContext;
022import com.fs.starfarer.api.fleet.FleetMemberAPI;
023import com.fs.starfarer.api.impl.MusicPlayerPluginImpl;
024import com.fs.starfarer.api.impl.campaign.CoreLifecyclePluginImpl;
025import com.fs.starfarer.api.impl.campaign.DerelictShipEntityPlugin;
026import com.fs.starfarer.api.impl.campaign.DerelictShipEntityPlugin.DerelictShipData;
027import com.fs.starfarer.api.impl.campaign.FleetEncounterContext;
028import com.fs.starfarer.api.impl.campaign.FleetInteractionDialogPluginImpl.BaseFIDDelegate;
029import com.fs.starfarer.api.impl.campaign.FleetInteractionDialogPluginImpl.FIDConfig;
030import com.fs.starfarer.api.impl.campaign.FleetInteractionDialogPluginImpl.FIDConfigGen;
031import com.fs.starfarer.api.impl.campaign.RuleBasedInteractionDialogPluginImpl;
032import com.fs.starfarer.api.impl.campaign.WarningBeaconEntityPlugin;
033import com.fs.starfarer.api.impl.campaign.fleets.FleetFactoryV3;
034import com.fs.starfarer.api.impl.campaign.ids.Conditions;
035import com.fs.starfarer.api.impl.campaign.ids.Entities;
036import com.fs.starfarer.api.impl.campaign.ids.Factions;
037import com.fs.starfarer.api.impl.campaign.ids.FleetTypes;
038import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
039import com.fs.starfarer.api.impl.campaign.ids.Personalities;
040import com.fs.starfarer.api.impl.campaign.ids.Pings;
041import com.fs.starfarer.api.impl.campaign.ids.Ranks;
042import com.fs.starfarer.api.impl.campaign.ids.Skills;
043import com.fs.starfarer.api.impl.campaign.ids.Tags;
044import com.fs.starfarer.api.impl.campaign.ids.Terrain;
045import com.fs.starfarer.api.impl.campaign.procgen.NebulaEditor;
046import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator.StarSystemType;
047import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseThemeGenerator;
048import com.fs.starfarer.api.impl.campaign.procgen.themes.RemnantSeededFleetManager.RemnantFleetInteractionConfigGen;
049import com.fs.starfarer.api.impl.campaign.procgen.themes.SalvageSpecialAssigner.ShipRecoverySpecialCreator;
050import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.ShipRecoverySpecial.PerShipData;
051import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.ShipRecoverySpecial.ShipCondition;
052import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.ShipRecoverySpecial.ShipRecoverySpecialData;
053import com.fs.starfarer.api.impl.campaign.terrain.HyperspaceTerrainPlugin;
054import com.fs.starfarer.api.impl.campaign.terrain.MagneticFieldTerrainPlugin.MagneticFieldParams;
055import com.fs.starfarer.api.loading.VariantSource;
056import com.fs.starfarer.api.util.Misc;
057
058public class TTBlackSite {
059
060        public static String HAMATSU_ID = "hamatsu";
061        
062        public static String NASCENT_WELL_KEY = "$ttBlackSite_well";
063        public static String DEFEATED_ZIGGURAT_KEY = "$defeatedZiggurat";
064        
065        public static class ZigFIDConfig implements FIDConfigGen {
066                public FIDConfig createConfig() {
067                        FIDConfig config = new FIDConfig();
068                        
069//                      config.alwaysAttackVsAttack = true;
070//                      config.leaveAlwaysAvailable = true;
071//                      config.showFleetAttitude = false;
072                        config.showTransponderStatus = false;
073                        config.showEngageText = false;
074                        config.alwaysPursue = true;
075                        config.dismissOnLeave = false;
076                        //config.lootCredits = false;
077                        config.withSalvage = false;
078                        //config.showVictoryText = false;
079                        config.printXPToDialog = true;
080                        
081                        config.noSalvageLeaveOptionText = "Continue";
082//                      config.postLootLeaveOptionText = "Continue";
083//                      config.postLootLeaveHasShortcut = false;
084                        
085                        config.delegate = new BaseFIDDelegate() {
086                                public void postPlayerSalvageGeneration(InteractionDialogAPI dialog, FleetEncounterContext context, CargoAPI salvage) {
087                                        new RemnantFleetInteractionConfigGen().createConfig().delegate.
088                                                                postPlayerSalvageGeneration(dialog, context, salvage);
089                                }
090                                public void notifyLeave(InteractionDialogAPI dialog) {
091                                        
092                                        SectorEntityToken other = dialog.getInteractionTarget();
093                                        if (!(other instanceof CampaignFleetAPI)) {
094                                                dialog.dismiss();
095                                                return;
096                                        }
097                                        CampaignFleetAPI fleet = (CampaignFleetAPI) other;
098                                        
099                                        if (!fleet.isEmpty()) {
100                                                dialog.dismiss();
101                                                return;
102                                        }
103                                        
104                                        Global.getSector().getMemoryWithoutUpdate().set(DEFEATED_ZIGGURAT_KEY, true);
105                                        
106                                        PerShipData ship = new PerShipData("ziggurat_Hull", ShipCondition.WRECKED, 0f);
107                                        ship.shipName = "TTS Xenorphica";
108                                        DerelictShipData params = new DerelictShipData(ship, false);
109                                        CustomCampaignEntityAPI entity = (CustomCampaignEntityAPI) BaseThemeGenerator.addSalvageEntity(
110                                                                                                fleet.getContainingLocation(),
111                                                                                                Entities.WRECK, Factions.NEUTRAL, params);
112                                        Misc.makeImportant(entity, "ziggurat");
113                                        entity.getMemoryWithoutUpdate().set("$ziggurat", true);
114                                        
115                                        entity.getLocation().x = fleet.getLocation().x + (50f - (float) Math.random() * 100f);
116                                        entity.getLocation().y = fleet.getLocation().y + (50f - (float) Math.random() * 100f);
117                        
118                                        ShipRecoverySpecialData data = new ShipRecoverySpecialData(null);
119                                        data.notNowOptionExits = true;
120                                        data.noDescriptionText = true;
121                                        DerelictShipEntityPlugin dsep = (DerelictShipEntityPlugin) entity.getCustomPlugin();
122                                        PerShipData copy = (PerShipData) dsep.getData().ship.clone();
123                                        copy.variant = Global.getSettings().getVariant(copy.variantId).clone();
124                                        copy.variantId = null;
125                                        copy.variant.addTag(Tags.SHIP_CAN_NOT_SCUTTLE);
126                                        copy.variant.addTag(Tags.SHIP_UNIQUE_SIGNATURE);
127                                        data.addShip(copy);
128                                        
129                                        Misc.setSalvageSpecial(entity, data);
130                                        
131                                        dialog.setInteractionTarget(entity);
132                                        RuleBasedInteractionDialogPluginImpl plugin = new RuleBasedInteractionDialogPluginImpl("AfterZigguratDefeat");
133                                        dialog.setPlugin(plugin);
134                                        plugin.init(dialog);
135                                }
136                                
137                                public void battleContextCreated(InteractionDialogAPI dialog, BattleCreationContext bcc) {
138                                        bcc.aiRetreatAllowed = false;
139                                        bcc.objectivesAllowed = false;
140                                        bcc.fightToTheLast = true;
141                                        bcc.enemyDeployAll = true;
142                                }
143                        };
144                        return config;
145                }
146        }
147        
148        
149        public void generate(SectorAPI sector) {
150                StarSystemAPI system = sector.createStarSystem("Unknown Location");
151                //system.setType(StarSystemType.NEBULA);
152                system.setName("Unknown Location"); // to get rid of "Star System" at the end of the name
153                system.setType(StarSystemType.DEEP_SPACE);
154                system.addTag(Tags.THEME_UNSAFE);
155                system.addTag(Tags.THEME_HIDDEN);
156                system.addTag(Tags.THEME_SPECIAL);
157                LocationAPI hyper = Global.getSector().getHyperspace();
158                
159                system.getMemoryWithoutUpdate().set(MusicPlayerPluginImpl.MUSIC_SET_MEM_KEY, "music_campaign_alpha_site");
160                
161                system.setBackgroundTextureFilename("graphics/backgrounds/background4.jpg");
162                //system.getLocation().set(2500, 3000);
163                system.getLocation().set(4000, 2500);
164                
165                HyperspaceTerrainPlugin hyperTerrain = (HyperspaceTerrainPlugin) Misc.getHyperspaceTerrain().getPlugin();
166                NebulaEditor editor = new NebulaEditor(hyperTerrain);
167                editor.clearArc(system.getLocation().x, system.getLocation().y, 0, 200, 0, 360f);
168//              editor.regenNoise();
169//              editor.noisePrune(0.8f);
170//              editor.regenNoise();
171
172                SectorEntityToken center = system.initNonStarCenter();
173                
174                system.setLightColor(new Color(225,170,255,255)); // light color in entire system, affects all entities
175                center.addTag(Tags.AMBIENT_LS);
176                
177                String type = "barren";
178                type = "irradiated";
179                PlanetAPI rock = system.addPlanet("site_alpha", center, "Alpha Site", type, 0, 150, 1200, 40);
180                //rock.setCustomDescriptionId("???");
181                rock.getMemoryWithoutUpdate().set("$ttBlackSite", true);
182                
183                rock.getMarket().addCondition(Conditions.NO_ATMOSPHERE);
184                rock.getMarket().addCondition(Conditions.COLD);
185                rock.getMarket().addCondition(Conditions.DARK);
186                rock.getMarket().addCondition(Conditions.IRRADIATED);
187                rock.getMarket().addCondition(Conditions.RUINS_SCATTERED);
188                
189                rock.getMarket().getMemoryWithoutUpdate().set("$ruinsExplored", true);
190                //If this is done, shows up in intel planet list; doesn't matter either way
191                //Misc.setFullySurveyed(rock.getMarket(), null, false);
192                
193                CoreLifecyclePluginImpl.addRuinsJunk(rock);
194                
195                rock.setOrbit(null);
196                rock.setLocation(1200, 300);
197                
198                SectorEntityToken field = system.addTerrain(Terrain.MAGNETIC_FIELD,
199                                                new MagneticFieldParams(150f, // terrain effect band width 
200                                                500, // terrain effect middle radius
201                                                rock, // entity that it's around
202                                                350f, // visual band start
203                                                650f, // visual band end
204                                                new Color(60, 60, 150, 90), // base color
205                                                1f, // probability to spawn aurora sequence, checked once/day when no aurora in progress
206                                                new Color(130, 60, 150, 130),
207                                                new Color(150, 30, 120, 150), 
208                                                new Color(200, 50, 130, 190),
209                                                new Color(250, 70, 150, 240),
210                                                new Color(200, 80, 130, 255),
211                                                new Color(75, 0, 160, 255), 
212                                                new Color(127, 0, 255, 255)
213                                                ));
214                field.setCircularOrbit(rock, 0, 0, 75);
215                
216                CustomCampaignEntityAPI beacon = system.addCustomEntity(null, null, Entities.WARNING_BEACON, Factions.NEUTRAL);
217                beacon.setCircularOrbitPointingDown(rock, 0, 2500, 60);
218                
219                beacon.getMemoryWithoutUpdate().set("$ttBlackSite", true);
220                beacon.getMemoryWithoutUpdate().set(WarningBeaconEntityPlugin.PING_ID_KEY, Pings.WARNING_BEACON3);
221                beacon.getMemoryWithoutUpdate().set(WarningBeaconEntityPlugin.PING_FREQ_KEY, 1.5f);
222                beacon.getMemoryWithoutUpdate().set(WarningBeaconEntityPlugin.PING_COLOR_KEY, new Color(250,125,0,255));
223                beacon.getMemoryWithoutUpdate().set(WarningBeaconEntityPlugin.GLOW_COLOR_KEY, new Color(250,55,0,255));
224                
225                
226                SectorEntityToken cache = BaseThemeGenerator.addSalvageEntity(system, Entities.ALPHA_SITE_WEAPONS_CACHE, Factions.NEUTRAL);
227                cache.getMemoryWithoutUpdate().set("$ttWeaponsCache", true);
228                cache.getLocation().set(11111, 11111);
229                
230//              JumpPointAPI jumpPoint = Global.getFactory().createJumpPoint("rock_jump_point", "Unstable Jump-point");
231//              OrbitAPI orbit = Global.getFactory().createCircularOrbit(rock, 0, 2500, 90);
232//              jumpPoint.setOrbit(orbit);
233//              //jumpPoint.setRelatedPlanet(magec2);
234//              jumpPoint.setStandardWormholeToHyperspaceVisual();
235//              system.addEntity(jumpPoint);
236                
237                system.generateAnchorIfNeeded();
238                
239                NascentGravityWellAPI well = Global.getSector().createNascentGravityWell(beacon, 50f);
240                well.addTag(Tags.NO_ENTITY_TOOLTIP);
241                well.setColorOverride(new Color(125, 50, 255));
242                hyper.addEntity(well);
243                well.autoUpdateHyperLocationBasedOnInSystemEntityAtRadius(beacon, 0);
244                
245                addFleet(rock);
246                
247                SectorEntityToken hamatsu = addDerelict(system, beacon, 
248                                                        "venture_Outdated", "ISS Hamatsu", HAMATSU_ID, ShipCondition.BATTERED, 200, true);
249                hamatsu.getMemoryWithoutUpdate().set("$hamatsu", true);
250                
251                Global.getSector().getMemoryWithoutUpdate().set(NASCENT_WELL_KEY, well);
252        }
253        
254        public static NascentGravityWellAPI getWell() {
255                return (NascentGravityWellAPI) Global.getSector().getMemoryWithoutUpdate().get(NASCENT_WELL_KEY);
256        }
257        
258        
259        public static void addFleet(SectorEntityToken rock) {
260                CampaignFleetAPI fleet = FleetFactoryV3.createEmptyFleet(Factions.NEUTRAL, FleetTypes.PATROL_LARGE, null);
261                fleet.setName("Unidentified Vessel");
262                fleet.setNoFactionInName(true);
263                fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_MAKE_HOSTILE, true);
264                fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_MAKE_AGGRESSIVE, true);
265                fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_NO_REP_IMPACT, true);
266                fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_LOW_REP_IMPACT, true);
267                //fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_PATROL_FLEET, true); // so it keeps transponder on
268                fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_NO_SHIP_RECOVERY, true);
269                fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_MAKE_ALWAYS_PURSUE, true);
270                fleet.getMemoryWithoutUpdate().set("$ziggurat", true);
271                
272                fleet.getMemoryWithoutUpdate().set(MusicPlayerPluginImpl.KEEP_PLAYING_LOCATION_MUSIC_DURING_ENCOUNTER_MEM_KEY, true);
273                
274                
275                fleet.getFleetData().addFleetMember("ziggurat_Experimental");
276                fleet.getFleetData().ensureHasFlagship();
277                
278                fleet.clearAbilities();
279//              fleet.addAbility(Abilities.TRANSPONDER);
280//              fleet.getAbility(Abilities.TRANSPONDER).activate();
281                
282                // so it never shows as "Unidentified Fleet" but isn't easier to spot due to using the actual transponder ability
283                fleet.setTransponderOn(true);
284                
285                PersonAPI person = createZigguratCaptain();
286                fleet.setCommander(person);
287                
288                FleetMemberAPI flagship = fleet.getFlagship();
289                flagship.setCaptain(person);
290                flagship.updateStats();
291                flagship.getRepairTracker().setCR(flagship.getRepairTracker().getMaxCR());
292                flagship.setShipName("TTS Xenorphica");
293                
294                // to "perm" the variant so it gets saved and not recreated from the "ziggurat_Experimental" id
295                flagship.setVariant(flagship.getVariant().clone(), false, false);
296                flagship.getVariant().setSource(VariantSource.REFIT);
297                flagship.getVariant().addTag(Tags.SHIP_LIMITED_TOOLTIP);
298
299                
300                Vector2f loc = new Vector2f(rock.getLocation().x + 300 * ((float) Math.random() - 0.5f),
301                                                                        rock.getLocation().y + 300 * ((float) Math.random() - 0.5f));
302                fleet.setLocation(loc.x, loc.y);
303                rock.getContainingLocation().addEntity(fleet);
304                
305                fleet.getMemoryWithoutUpdate().set(MemFlags.FLEET_INTERACTION_DIALOG_CONFIG_OVERRIDE_GEN, 
306                                   new ZigFIDConfig());
307                
308                fleet.addScript(new ZigLeashAssignmentAI(fleet, rock));
309                
310        }
311        
312        
313        public static PersonAPI createZigguratCaptain() {
314                PersonAPI person = Global.getFactory().createPerson();
315                person.setName(new FullName("Motes", "", Gender.ANY));
316                person.setFaction(Factions.NEUTRAL);
317                person.setPortraitSprite(Global.getSettings().getSpriteName("characters", "ziggurat_captain"));
318                person.setPersonality(Personalities.RECKLESS);
319                person.setRankId(Ranks.SPACE_CAPTAIN);
320                person.setPostId(null);
321                
322                person.getStats().setSkipRefresh(true);
323                
324                person.getStats().setLevel(10);
325                person.getStats().setSkillLevel(Skills.HELMSMANSHIP, 2);
326                person.getStats().setSkillLevel(Skills.TARGET_ANALYSIS, 2);
327                person.getStats().setSkillLevel(Skills.IMPACT_MITIGATION, 2);
328                person.getStats().setSkillLevel(Skills.GUNNERY_IMPLANTS, 2);
329                person.getStats().setSkillLevel(Skills.ENERGY_WEAPON_MASTERY, 2);
330                person.getStats().setSkillLevel(Skills.COMBAT_ENDURANCE, 2);
331                //person.getStats().setSkillLevel(Skills.RELIABILITY_ENGINEERING, 2);
332                //person.getStats().setSkillLevel(Skills.RANGED_SPECIALIZATION, 2);
333                person.getStats().setSkillLevel(Skills.POLARIZED_ARMOR, 2);
334                person.getStats().setSkillLevel(Skills.MISSILE_SPECIALIZATION, 2);
335                //person.getStats().setSkillLevel(Skills.PHASE_MASTERY, 2);
336                person.getStats().setSkillLevel(Skills.FIELD_MODULATION, 2);
337                person.getStats().setSkillLevel(Skills.DAMAGE_CONTROL, 2);
338                
339                person.getStats().setSkillLevel(Skills.NAVIGATION, 1);
340                
341                person.getStats().setSkipRefresh(false);
342                
343                return person;
344        }
345        
346        public static SectorEntityToken addDerelict(StarSystemAPI system, SectorEntityToken focus, 
347                                                           String variantId, String name, String id, 
348                                                           ShipCondition condition, float orbitRadius, boolean recoverable) {
349                DerelictShipData params = new DerelictShipData(new PerShipData(variantId, condition, 0f), false);
350                if (name != null) {
351                        params.ship.shipName = name;
352                        params.ship.nameAlwaysKnown = true;
353                        params.ship.fleetMemberId = id;
354                }
355                SectorEntityToken ship = BaseThemeGenerator.addSalvageEntity(system, Entities.WRECK, Factions.NEUTRAL, params);
356                ship.setDiscoverable(true);
357
358                float orbitDays = orbitRadius / (10f + (float) Math.random() * 5f);
359                ship.setCircularOrbit(focus, (float) Math.random() * 360f, orbitRadius, orbitDays);
360
361                if (recoverable) {
362                        ShipRecoverySpecialCreator creator = new ShipRecoverySpecialCreator(null, 0, 0, false, null, null);
363                        Misc.setSalvageSpecial(ship, creator.createSpecial(ship, null));
364                }
365                return ship;
366        }
367        
368}
369
370
371
372
373
374
375
376
377
378
379
380
381