private static void InitializeMapAndAddBorderWalls(EncounterState state, int width, int height) { // Initialize the map with empty tiles state.MapWidth = width; state.MapHeight = height; state._encounterTiles = new EncounterTile[width, height]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { state._encounterTiles[x, y] = new EncounterTile(); } } // Create border walls to prevent objects running off the map for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { if (x == 0 || x == width - 1 || y == 0 || y == height - 1) { state.PlaceEntity(EntityBuilder.CreateEdgeBlockerEntity(), new EncounterPosition(x, y)); } } } }
private static void PopulateZone(EncounterZone zone, int dungeonLevel, Random seededRand, EncounterState state, bool safe = false) { // Add satellites int numSatellites = LevelData.GetNumberOfSatellites(dungeonLevel); for (int i = 0; i < numSatellites; i++) { var unblockedPosition = zone.RandomEmptyPosition(seededRand, state); var satellite = EntityBuilder.CreateSatelliteEntity(); state.PlaceEntity(satellite, unblockedPosition); } EncounterDef encounterDef; if (safe) { encounterDef = LevelData.GetEncounterDefById(EncounterDefId.EMPTY_ENCOUNTER); } else { encounterDef = LevelData.ChooseEncounter(dungeonLevel, seededRand); } zone.ReadoutEncounterName = encounterDef.Name; if (encounterDef.EntityDefIds.Count > 0) { string activationGroupId = Guid.NewGuid().ToString(); foreach (string entityDefId in encounterDef.EntityDefIds) { var unblockedPosition = zone.RandomEmptyPosition(seededRand, state); var newEntity = EntityBuilder.CreateEnemyByEntityDefId(entityDefId, activationGroupId, state.CurrentTick); state.PlaceEntity(newEntity, unblockedPosition); } } var chosenItemDefs = LevelData.ChooseItemDefs(dungeonLevel, seededRand); foreach (string chosenItemDefId in chosenItemDefs) { var unblockedPosition = zone.RandomEmptyPosition(seededRand, state); var newEntity = EntityBuilder.CreateItemByEntityDefId(chosenItemDefId); state.PlaceEntity(newEntity, unblockedPosition); zone.AddItemToReadout(newEntity); } }
public static void PopulateStateForLevel(Entity player, int dungeonLevel, EncounterState state, Random seededRand, int width = 300, int height = 300, int maxZoneGenAttempts = 100) { InitializeMapAndAddBorderWalls(state, width, height); // Place each empty zone onto the map int zoneGenAttemps = 0; List <EncounterZone> zones = new List <EncounterZone>(); while (zoneGenAttemps < maxZoneGenAttempts && zones.Count < LevelData.GetNumberOfZones(dungeonLevel)) { int zoneWidth = seededRand.Next(ZONE_MIN_SIZE, ZONE_MAX_SIZE + 1); int zoneHeight = seededRand.Next(ZONE_MIN_SIZE, ZONE_MAX_SIZE + 1); int zoneX = seededRand.Next(1, state.MapWidth - zoneWidth); int zoneY = seededRand.Next(1, state.MapHeight - zoneHeight); var newZone = new EncounterZone(Guid.NewGuid().ToString(), new EncounterPosition(zoneX, zoneY), zoneWidth, zoneHeight, "Zone " + zones.Count.ToString()); bool overlaps = zones.Any(existing => existing.Intersects(newZone)); if (!overlaps) { zones.Add(newZone); } } state._zones = zones; // Add the player to the map var playerZoneIdx = seededRand.Next(0, zones.Count); state.PlaceEntity(player, zones[playerZoneIdx].Center); /* * var nextToPlayer = new EncounterPosition(zones[playerZoneIdx].Center.X + 2, zones[playerZoneIdx].Center.Y + 1); * state.PlaceEntity(EntityBuilder.CreateItemByEntityDefId(EntityDefId.ITEM_RED_PAINT), nextToPlayer); * nextToPlayer = new EncounterPosition(zones[playerZoneIdx].Center.X + 1, zones[playerZoneIdx].Center.Y + 1); * state.PlaceEntity(EntityBuilder.CreateItemByEntityDefId(EntityDefId.ITEM_EMP), nextToPlayer); * for (int i = 0; i < 26; i++) { * nextToPlayer = new EncounterPosition(zones[playerZoneIdx].Center.X + i, zones[playerZoneIdx].Center.Y + 3); * state.PlaceEntity(EntityBuilder.CreateItemByEntityDefId(EntityDefId.ITEM_EXTRA_BATTERY), nextToPlayer); * } */ var nextToPlayer = new EncounterPosition(zones[playerZoneIdx].Center.X + 2, zones[playerZoneIdx].Center.Y + 2); //string[] defs = new string[] { EntityDefId.SCOUT, EntityDefId.FIGHTER, EntityDefId.GUNSHIP, EntityDefId.FRIGATE, EntityDefId.DESTROYER, EntityDefId.CRUISER, EntityDefId.CARRIER, EntityDefId.DIPLOMAT }; string[] defs = new string[] { EntityDefId.ITEM_DUCT_TAPE, EntityDefId.ITEM_EMP, EntityDefId.ITEM_EXTRA_BATTERY, EntityDefId.ITEM_RED_PAINT }; for (int x = 0; x < defs.Length; x++) { for (int y = 0; y < 3; y++) { var pos = new EncounterPosition(nextToPlayer.X + x, nextToPlayer.Y + y); //state.PlaceEntity(EntityBuilder.CreateEnemyByEntityDefId(defs[x], "12345", 0), pos, ignoreCollision: true); state.PlaceEntity(EntityBuilder.CreateItemByEntityDefId(defs[x]), pos, ignoreCollision: true); } } // Add all the various zone features to the map // TODO: Draw this from LevelData instead of literally special-casing level 10 here if (dungeonLevel != 10) { // Generate the stairs (maybe we should refer interally as something more themetically appropriate?) // You can get stairs in your starting zone, but you probably shouldn't take them... // var stairsZone = zones[playerZoneIdx]; // For testing var stairsZone = zones[seededRand.Next(0, zones.Count)]; var stairsPosition = stairsZone.RandomEmptyPosition(seededRand, state); var stairs = EntityBuilder.CreateStairsEntity(); state.PlaceEntity(stairs, stairsPosition); stairsZone.AddFeatureToReadout(stairs); // Generate intel // var intelZone = zones[playerZoneIdx]; // For testing var intelZone = zones[seededRand.Next(0, zones.Count)]; var intelPosition = intelZone.RandomEmptyPosition(seededRand, state); var intel = EntityBuilder.CreateIntelEntity(dungeonLevel + 1); state.PlaceEntity(intel, intelPosition); intelZone.AddFeatureToReadout(intel); } // Populate each zone with an encounter foreach (EncounterZone zone in zones) { if (zone == zones[playerZoneIdx]) { PopulateZone(zone, dungeonLevel, seededRand, state, safe: true); } else { PopulateZone(zone, dungeonLevel, seededRand, state); } } }