| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- using System.Linq;
- using Content.Server.Gateway.Components;
- using Content.Server.Parallax;
- using Content.Server.Procedural;
- using Content.Shared.CCVar;
- using Content.Shared.Dataset;
- using Content.Shared.Maps;
- using Content.Shared.Parallax.Biomes;
- using Content.Shared.Procedural;
- using Content.Shared.Salvage;
- using Robust.Shared.Configuration;
- using Robust.Shared.Map;
- using Robust.Shared.Map.Components;
- using Robust.Shared.Prototypes;
- using Robust.Shared.Random;
- using Robust.Shared.Timing;
- using Robust.Shared.Utility;
- namespace Content.Server.Gateway.Systems;
- /// <summary>
- /// Generates gateway destinations regularly and indefinitely that can be chosen from.
- /// </summary>
- public sealed class GatewayGeneratorSystem : EntitySystem
- {
- [Dependency] private readonly IConfigurationManager _cfgManager = default!;
- [Dependency] private readonly IGameTiming _timing = default!;
- [Dependency] private readonly IMapManager _mapManager = default!;
- [Dependency] private readonly IPrototypeManager _protoManager = default!;
- [Dependency] private readonly IRobustRandom _random = default!;
- [Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
- [Dependency] private readonly BiomeSystem _biome = default!;
- [Dependency] private readonly DungeonSystem _dungeon = default!;
- [Dependency] private readonly GatewaySystem _gateway = default!;
- [Dependency] private readonly MetaDataSystem _metadata = default!;
- [Dependency] private readonly SharedMapSystem _maps = default!;
- [Dependency] private readonly SharedSalvageSystem _salvage = default!;
- [Dependency] private readonly TileSystem _tile = default!;
- [ValidatePrototypeId<LocalizedDatasetPrototype>]
- private const string PlanetNames = "NamesBorer";
- // TODO:
- // Fix shader some more
- // Show these in UI
- // Use regular mobs for thingo.
- // Use salvage mission params
- // Add the funny song
- // Put salvage params in the UI
- // Re-use salvage config stuff for the RNG
- // Have it in the UI like expeditions.
- // Also add weather coz it's funny.
- // Add songs (incl. the downloaded one) to the ambient music playlist for planet probably.
- // Copy most of salvage mission spawner
- public override void Initialize()
- {
- base.Initialize();
- SubscribeLocalEvent<GatewayGeneratorComponent, MapInitEvent>(OnGeneratorMapInit);
- SubscribeLocalEvent<GatewayGeneratorComponent, ComponentShutdown>(OnGeneratorShutdown);
- SubscribeLocalEvent<GatewayGeneratorDestinationComponent, AttemptGatewayOpenEvent>(OnGeneratorAttemptOpen);
- SubscribeLocalEvent<GatewayGeneratorDestinationComponent, GatewayOpenEvent>(OnGeneratorOpen);
- }
- private void OnGeneratorShutdown(EntityUid uid, GatewayGeneratorComponent component, ComponentShutdown args)
- {
- foreach (var genUid in component.Generated)
- {
- if (Deleted(genUid))
- continue;
- QueueDel(genUid);
- }
- }
- private void OnGeneratorMapInit(EntityUid uid, GatewayGeneratorComponent generator, MapInitEvent args)
- {
- if (!_cfgManager.GetCVar(CCVars.GatewayGeneratorEnabled))
- return;
- generator.NextUnlock = TimeSpan.FromMinutes(5);
- for (var i = 0; i < 3; i++)
- {
- GenerateDestination(uid, generator);
- }
- }
- private void GenerateDestination(EntityUid uid, GatewayGeneratorComponent? generator = null)
- {
- if (!Resolve(uid, ref generator))
- return;
- var tileDef = _tileDefManager["FloorSteel"];
- const int MaxOffset = 256;
- var tiles = new List<(Vector2i Index, Tile Tile)>();
- var seed = _random.Next();
- var random = new Random(seed);
- var mapId = _mapManager.CreateMap();
- var mapUid = _mapManager.GetMapEntityId(mapId);
- var gatewayName = _salvage.GetFTLName(_protoManager.Index<LocalizedDatasetPrototype>(PlanetNames), seed);
- _metadata.SetEntityName(mapUid, gatewayName);
- var origin = new Vector2i(random.Next(-MaxOffset, MaxOffset), random.Next(-MaxOffset, MaxOffset));
- var restricted = new RestrictedRangeComponent
- {
- Origin = origin
- };
- AddComp(mapUid, restricted);
- _biome.EnsurePlanet(mapUid, _protoManager.Index<BiomeTemplatePrototype>("Continental"), seed);
- var grid = Comp<MapGridComponent>(mapUid);
- for (var x = -2; x <= 2; x++)
- {
- for (var y = -2; y <= 2; y++)
- {
- tiles.Add((new Vector2i(x, y) + origin, new Tile(tileDef.TileId, variant: _tile.PickVariant((ContentTileDefinition) tileDef, random))));
- }
- }
- // Clear area nearby as a sort of landing pad.
- _maps.SetTiles(mapUid, grid, tiles);
- _metadata.SetEntityName(mapUid, gatewayName);
- var originCoords = new EntityCoordinates(mapUid, origin);
- var genDest = AddComp<GatewayGeneratorDestinationComponent>(mapUid);
- genDest.Origin = origin;
- genDest.Seed = seed;
- genDest.Generator = uid;
- // Create the gateway.
- var gatewayUid = SpawnAtPosition(generator.Proto, originCoords);
- var gatewayComp = Comp<GatewayComponent>(gatewayUid);
- _gateway.SetDestinationName(gatewayUid, FormattedMessage.FromMarkupOrThrow($"[color=#D381C996]{gatewayName}[/color]"), gatewayComp);
- _gateway.SetEnabled(gatewayUid, true, gatewayComp);
- generator.Generated.Add(mapUid);
- }
- private void OnGeneratorAttemptOpen(Entity<GatewayGeneratorDestinationComponent> ent, ref AttemptGatewayOpenEvent args)
- {
- if (ent.Comp.Loaded || args.Cancelled)
- return;
- if (!TryComp(ent.Comp.Generator, out GatewayGeneratorComponent? generatorComp))
- return;
- if (generatorComp.NextUnlock + _metadata.GetPauseTime(ent.Owner) <= _timing.CurTime)
- return;
- args.Cancelled = true;
- }
- private void OnGeneratorOpen(Entity<GatewayGeneratorDestinationComponent> ent, ref GatewayOpenEvent args)
- {
- if (ent.Comp.Loaded)
- return;
- if (TryComp(ent.Comp.Generator, out GatewayGeneratorComponent? generatorComp))
- {
- generatorComp.NextUnlock = _timing.CurTime + generatorComp.UnlockCooldown;
- _gateway.UpdateAllGateways();
- // Generate another destination to keep them going.
- GenerateDestination(ent.Comp.Generator);
- }
- if (!TryComp(args.MapUid, out MapGridComponent? grid))
- return;
- ent.Comp.Locked = false;
- ent.Comp.Loaded = true;
- // Do dungeon
- var seed = ent.Comp.Seed;
- var origin = ent.Comp.Origin;
- var random = new Random(seed);
- var dungeonDistance = random.Next(3, 6);
- var dungeonRotation = _dungeon.GetDungeonRotation(seed);
- var dungeonPosition = (origin + dungeonRotation.RotateVec(new Vector2i(0, dungeonDistance))).Floored();
- _dungeon.GenerateDungeon(_protoManager.Index<DungeonConfigPrototype>("Experiment"), args.MapUid, grid, dungeonPosition, seed);
- // TODO: Dungeon mobs + loot.
- // Do markers on the map.
- if (TryComp(ent.Owner, out BiomeComponent? biomeComp) && generatorComp != null)
- {
- // - Loot
- var lootLayers = generatorComp.LootLayers.ToList();
- for (var i = 0; i < generatorComp.LootLayerCount; i++)
- {
- var layerIdx = random.Next(lootLayers.Count);
- var layer = lootLayers[layerIdx];
- lootLayers.RemoveSwap(layerIdx);
- _biome.AddMarkerLayer(ent.Owner, biomeComp, layer.Id);
- }
- // - Mobs
- var mobLayers = generatorComp.MobLayers.ToList();
- for (var i = 0; i < generatorComp.MobLayerCount; i++)
- {
- var layerIdx = random.Next(mobLayers.Count);
- var layer = mobLayers[layerIdx];
- mobLayers.RemoveSwap(layerIdx);
- _biome.AddMarkerLayer(ent.Owner, biomeComp, layer.Id);
- }
- }
- }
- }
|