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