001package com.fs.starfarer.api.impl.campaign.world; 002 003import java.util.LinkedHashMap; 004import java.util.Random; 005 006import org.lwjgl.util.vector.Vector2f; 007 008import com.fs.starfarer.api.Global; 009import com.fs.starfarer.api.campaign.CustomCampaignEntityAPI; 010import com.fs.starfarer.api.campaign.PlanetAPI; 011import com.fs.starfarer.api.campaign.SectorAPI; 012import com.fs.starfarer.api.campaign.SectorEntityToken; 013import com.fs.starfarer.api.campaign.StarSystemAPI; 014import com.fs.starfarer.api.impl.campaign.DerelictShipEntityPlugin; 015import com.fs.starfarer.api.impl.campaign.DerelictShipEntityPlugin.DerelictShipData; 016import com.fs.starfarer.api.impl.campaign.enc.AbyssalRogueStellarObjectEPEC; 017import com.fs.starfarer.api.impl.campaign.ids.Conditions; 018import com.fs.starfarer.api.impl.campaign.ids.Entities; 019import com.fs.starfarer.api.impl.campaign.ids.Factions; 020import com.fs.starfarer.api.impl.campaign.ids.Planets; 021import com.fs.starfarer.api.impl.campaign.ids.Tags; 022import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator; 023import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator.StarSystemType; 024import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseThemeGenerator; 025import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseThemeGenerator.AddedEntity; 026import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseThemeGenerator.EntityLocation; 027import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseThemeGenerator.LocationType; 028import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.ShipRecoverySpecial.PerShipData; 029import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.ShipRecoverySpecial.ShipCondition; 030import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.ShipRecoverySpecial.ShipRecoverySpecialData; 031import com.fs.starfarer.api.util.Misc; 032import com.fs.starfarer.api.util.WeightedRandomPicker; 033 034public class NamelessRock { 035 036 public static String ONESLAUGHT_SENSOR_ARRAY = "$oneslaughtSensorArray"; 037 public static String NAMELESS_ROCK_LOCATION_ID = "nameless_rock_location"; 038 039 public void generate(SectorAPI sector) { 040 StarSystemAPI system = sector.createStarSystem("Deep Space"); 041 //system.setType(StarSystemType.NEBULA); 042 system.setName("Deep Space"); // to get rid of "Star System" at the end of the name 043 system.setOptionalUniqueId(NAMELESS_ROCK_LOCATION_ID); 044 045 system.setType(StarSystemType.DEEP_SPACE); 046 system.addTag(Tags.THEME_HIDDEN); 047 system.addTag(Tags.THEME_SPECIAL); 048 system.addTag(Tags.SYSTEM_ABYSSAL); 049 050 051 system.setBackgroundTextureFilename("graphics/backgrounds/background5.jpg"); 052 053 Random random = StarSystemGenerator.random; 054 055 float w = Global.getSettings().getFloat("sectorWidth"); 056 float h = Global.getSettings().getFloat("sectorHeight"); 057 058 Vector2f systemLoc = new Vector2f(); 059 float outsideMapPad = 2500f; 060 float outsideMapRand = 2500f; 061 float r = random.nextFloat(); 062 // avoid the actual lower-left corner somewhat, since the gate hauler is there, too, but 063 if (r < 0.5f) { // left 064 systemLoc.x = -w/2f - outsideMapPad - outsideMapRand * random.nextFloat(); 065 //systemLoc.y = -h/2f - outsideMapPad + (h + outsideMapPad * 2f) * random.nextFloat(); 066 systemLoc.y = -h/2f + (h + outsideMapPad * 1f) * random.nextFloat(); 067 } else { //if (r < 0.75f) { // bottom 068 systemLoc.x = -w/2f + (w + outsideMapPad * 1f) * random.nextFloat(); 069 systemLoc.y = -h/2f - outsideMapPad - outsideMapRand * random.nextFloat(); 070 } 071// else if (r < 0.5f) { // right 072// systemLoc.x = w/2f + outsideMapPad + outsideMapRand * random.nextFloat(); 073// systemLoc.y = -h/2f - outsideMapPad + (h + outsideMapPad * 2f) * random.nextFloat(); 074// } else { // top 075// systemLoc.x = -w/2f - outsideMapPad + (w + outsideMapPad * 2f) * random.nextFloat(); 076// systemLoc.y = h/2f + outsideMapPad + outsideMapRand * random.nextFloat(); 077// } 078 system.getLocation().set(systemLoc.x, systemLoc.y); 079 080// Vector2f systemLoc = new Vector2f(3000f, 21000f); 081// systemLoc = Misc.getPointWithinRadius(systemLoc, 1000f, random); 082// system.getLocation().set(-w/2f + systemLoc.x, -h/2f + systemLoc.y); 083 084 SectorEntityToken center = system.initNonStarCenter(); 085 086 system.setLightColor(GateHaulerLocation.ABYSS_AMBIENT_LIGHT_COLOR); // light color in entire system, affects all entities 087 center.addTag(Tags.AMBIENT_LS); 088 089 //String name = Misc.genEntityCatalogId(2700, 11, 7, CatalogEntryType.PLANET); 090 String name = "Nameless Rock"; 091 092 PlanetAPI rock = system.addPlanet("nameless_rock", null, name, Planets.BARREN, 0, 150, 0, 0); 093 rock.setDescriptionIdOverride("barren_deep_space"); 094 095 //rock.setCustomDescriptionId("???"); 096 rock.getMemoryWithoutUpdate().set("$namelessRock", true); 097 098 rock.getMarket().addCondition(Conditions.NO_ATMOSPHERE); 099 rock.getMarket().addCondition(Conditions.VERY_COLD); 100 rock.getMarket().addCondition(Conditions.DARK); 101 rock.getMarket().addCondition(Conditions.ORE_RICH); 102 rock.getMarket().addCondition(Conditions.RARE_ORE_MODERATE); 103 104 rock.setOrbit(null); 105 rock.setLocation(0, 0); 106 107 addOnslaughtMkI(rock); 108 109 system.autogenerateHyperspaceJumpPoints(false, false); 110 111 AbyssalRogueStellarObjectEPEC.setAbyssalDetectedRanges(system); 112 113 createSensorArrayInClosestSystem(system); 114 } 115 116 117 protected void addOnslaughtMkI(PlanetAPI rock) { 118 PerShipData ship = new PerShipData("onslaught_mk1_Ancient", ShipCondition.WRECKED, 0f); 119 ship.shipName = "Serial #2F38CB017"; 120 DerelictShipData params = new DerelictShipData(ship, false); 121 CustomCampaignEntityAPI entity = (CustomCampaignEntityAPI) BaseThemeGenerator.addSalvageEntity( 122 rock.getContainingLocation(), 123 Entities.WRECK, Factions.NEUTRAL, params); 124 //Misc.makeImportant(entity, "onslaughtMkI"); 125 entity.getMemoryWithoutUpdate().set("$onslaughtMkI", true); 126 entity.setSensorProfile(1f); 127 entity.setDiscoverable(true); 128 129 Random random = StarSystemGenerator.random; 130 float orbitRadius = rock.getRadius() + 200f; 131 float orbitDays = orbitRadius / (10f + random.nextFloat() * 5f); 132 entity.setCircularOrbit(rock, random.nextFloat() * 360f, orbitRadius, orbitDays); 133 134 ShipRecoverySpecialData data = new ShipRecoverySpecialData(null); 135 data.notNowOptionExits = true; 136 data.noDescriptionText = true; 137 DerelictShipEntityPlugin dsep = (DerelictShipEntityPlugin) entity.getCustomPlugin(); 138 PerShipData copy = (PerShipData) dsep.getData().ship.clone(); 139 copy.variant = Global.getSettings().getVariant(copy.variantId).clone(); 140 copy.variantId = null; 141 copy.variant.addTag(Tags.SHIP_CAN_NOT_SCUTTLE); 142 copy.variant.addTag(Tags.SHIP_UNIQUE_SIGNATURE); 143 copy.nameAlwaysKnown = true; 144 //copy.addDmods = false; 145 copy.pruneWeapons = false; 146 147 // makes it unpilotable by the the player with Neural Link, don't want that 148// AICoreOfficerPlugin plugin = Misc.getAICoreOfficerPlugin(Commodities.GAMMA_CORE); 149// if (plugin != null) { 150// copy.captain = plugin.createPerson(Commodities.GAMMA_CORE, Factions.PLAYER, null); 151// copy.captain.getStats().setSkillLevel(Skills.POLARIZED_ARMOR, 2); 152// copy.captain.getStats().setLevel(copy.captain.getStats().getLevel() + 1); 153// Misc.setUnremovable(copy.captain, true); 154// Misc.setKeepOnShipRecovery(copy.captain, true); 155// } 156 157 data.addShip(copy); 158 159 Misc.setSalvageSpecial(entity, data); 160 } 161 162 protected void createSensorArrayInClosestSystem(StarSystemAPI rockSystem) { 163 float minDist = Float.MAX_VALUE; 164 StarSystemAPI closest = null; 165 for (StarSystemAPI curr : Global.getSector().getStarSystems()) { 166 if (curr == rockSystem) continue; 167 if (Misc.getAbyssalDepth(curr.getLocation()) > 0f) continue; 168 if (curr.getType() == StarSystemType.DEEP_SPACE) continue; 169 float dist = Misc.getDistance(curr.getLocation(), rockSystem.getLocation()); 170 if (dist < minDist) { 171 closest = curr; 172 minDist = dist; 173 } 174 } 175 176 if (closest == null) return; 177 178 179 SectorEntityToken sensor = null; 180 for (SectorEntityToken curr: closest.getEntitiesWithTag(Tags.SENSOR_ARRAY)) { 181 if (curr.hasTag(Tags.MAKESHIFT)) continue; 182 sensor = curr; 183 break; 184 } 185 186 if (sensor == null) { 187 LinkedHashMap<LocationType, Float> weights = new LinkedHashMap<LocationType, Float>(); 188 weights.put(LocationType.STAR_ORBIT, 10f); 189 weights.put(LocationType.OUTER_SYSTEM, 10f); 190 WeightedRandomPicker<EntityLocation> locs = BaseThemeGenerator.getLocations(null, closest, null, 100f, weights); 191 EntityLocation loc = locs.pick(); 192 AddedEntity added = BaseThemeGenerator.addNonSalvageEntity(closest, 193 loc, Entities.SENSOR_ARRAY, Factions.NEUTRAL); 194 if (added != null) { 195 sensor = added.entity; 196 } 197 } 198 199 // really shouldn't be possible as BaseThemeGenerator.getLocations() is supposed to 200 // always find something if STAR_ORBIT/OUTER_SYSTEM are supplied in the weights 201 if (sensor == null) return; 202 203 sensor.getMemoryWithoutUpdate().set(ONESLAUGHT_SENSOR_ARRAY, true); 204 Global.getSector().getPersistentData().put(ONESLAUGHT_SENSOR_ARRAY, sensor); 205 206 // to get it: 207 //SectorEntityToken sensor = (SectorEntityToken) Global.getSector().getPersistentData().get(ONESLAUGHT_SENSOR_ARRAY); 208 } 209} 210 211 212 213 214 215 216 217 218 219 220 221 222