Merge branch 'master' into MagicWands

This commit is contained in:
comasqw
2024-12-12 00:59:47 +04:00
393 changed files with 220202 additions and 9814 deletions

View File

@@ -1,15 +1,7 @@
using System.Globalization;
using System.Linq;
using System.Numerics;
using Content.Server.Chat.Systems;
using Content.Server.Mind;
using Content.Server.Shuttles.Components;
using Content.Server.Shuttles.Events;
using Content.Server.Station.Systems;
using Content.Shared._CP14.Cargo;
using Content.Shared.Administration.Logs;
using Content.Shared.Database;
using Content.Shared.Roles.Jobs;
using Robust.Shared.Map;
using Robust.Shared.Random;
@@ -17,12 +9,6 @@ namespace Content.Server._CP14.Cargo;
public sealed partial class CP14CargoSystem
{
[Dependency] private readonly ISharedAdminLogManager _adminLog = default!;
[Dependency] private readonly ChatSystem _chatSystem = default!;
[Dependency] private readonly MindSystem _mind = default!;
[Dependency] private readonly SharedJobSystem _job = default!;
[Dependency] private readonly StationJobsSystem _stationJobs = default!;
private void InitializeShuttle()
{
SubscribeLocalEvent<CP14TravelingStoreShipComponent, FTLCompletedEvent>(OnFTLCompleted);
@@ -102,10 +88,6 @@ public sealed partial class CP14CargoSystem
{
station.OnStation = false;
var b = station.Balance;
PlayersPurgeJobs(ent);
SellingThings((ent.Comp.Station, station)); // +balance
TopUpBalance((ent.Comp.Station, station)); //+balance
BuyToQueue((ent.Comp.Station, station)); //-balance +buyQueue
@@ -121,44 +103,4 @@ public sealed partial class CP14CargoSystem
UpdateAllStores();
}
private void PlayersPurgeJobs(Entity<CP14TravelingStoreShipComponent> ent)
{
var childrens = Transform(ent).ChildEnumerator;
HashSet<EntityUid> toDelete = new();
while (childrens.MoveNext(out var uid))
{
if (!_mind.TryGetMind(uid, out var mindId, out var mindComp))
continue;
if (!_job.MindTryGetJob(mindId, out var jobProto))
continue;
_adminLog.Add(LogType.Action,
LogImpact.High,
$"{ToPrettyString(uid):player} was leave the round on traveling merchant ship");
_chatSystem.DispatchStationAnnouncement(ent.Comp.Station,
Loc.GetString(
"cp14-earlyleave-ship-announcement",
("character", mindComp.CharacterName ?? "Unknown"),
("entity", ent.Owner), // gender things for supporting downstreams with other languages
("job", CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Loc.GetString(jobProto.Name)))
),
Loc.GetString("cp14-ship-sender"),
playDefaultSound: false
);
_stationJobs.TryAdjustJobSlot(ent.Comp.Station, jobProto, 1, clamp: true);
toDelete.Add(uid);
}
while (toDelete.Count > 0)
{
var r = toDelete.First();
toDelete.Remove(r);
QueueDel(r);
}
}
}

View File

@@ -1,4 +1,5 @@
using Content.Server._CP14.Currency;
using Content.Server._CP14.RoundRemoveShuttle;
using Content.Server.Shuttles.Systems;
using Content.Server.Station.Events;
using Content.Server.Station.Systems;
@@ -102,6 +103,9 @@ public sealed partial class CP14CargoSystem : CP14SharedCargoSystem
var member = EnsureComp<StationMemberComponent>(shuttle);
member.Station = station;
var roundRemover = EnsureComp<CP14RoundRemoveShuttleComponent>(shuttle);
roundRemover.Station = station;
station.Comp.NextTravelTime = _timing.CurTime + TimeSpan.FromSeconds(10f);
AddRoundstartTradingPositions(station);

View File

@@ -1,5 +1,4 @@
using Content.Server.Administration;
using Content.Shared._CP14.DayCycle;
using Content.Shared.Administration;
using Robust.Shared.Console;
using CP14DayCycleComponent = Content.Shared._CP14.DayCycle.Components.CP14DayCycleComponent;

View File

@@ -108,9 +108,9 @@ public sealed class CP14SpawnRandomDemiplaneJob : Job<bool>
}
//Setup gravity
var gravity = _entManager.EnsureComponent<GravityComponent>(DemiplaneMapUid);
var gravity = _entManager.EnsureComponent<GravityComponent>(grid);
gravity.Enabled = true;
_entManager.Dirty(DemiplaneMapUid, gravity, metadata);
_entManager.Dirty(grid, gravity, metadata);
// Setup default atmos
var moles = new float[Atmospherics.AdjustedNumberOfGases];

View File

@@ -0,0 +1,17 @@
namespace Content.Server._CP14.MapDamage;
/// <summary>
/// can take damage from being directly on the map (not on the grid)
/// </summary>
[RegisterComponent, AutoGenerateComponentPause]
public sealed partial class CP14DamageableByMapComponent : Component
{
[DataField, AutoPausedField]
public TimeSpan NextDamageTime = TimeSpan.Zero;
[DataField]
public bool Enabled = false;
[DataField]
public Entity<CP14MapDamageComponent>? CurrentMap;
}

View File

@@ -0,0 +1,24 @@
using Content.Shared.Damage;
using Content.Shared.FixedPoint;
namespace Content.Server._CP14.MapDamage;
/// <summary>
/// The map deals damage to entities that are on it (not on the grid)
/// </summary>
[RegisterComponent]
public sealed partial class CP14MapDamageComponent : Component
{
//Damage every second
[DataField]
public DamageSpecifier Damage = new()
{
DamageDict = new Dictionary<string, FixedPoint2>()
{
{"Asphyxiation", 10}
}
};
[DataField]
public float StaminaDamage = 7f;
}

View File

@@ -0,0 +1,82 @@
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
using Robust.Shared.Timing;
namespace Content.Server._CP14.MapDamage;
public sealed partial class CP14MapDamageSystem : EntitySystem
{
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly DamageableSystem _damageable = default!;
[Dependency] private readonly StaminaSystem _stamina = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CP14DamageableByMapComponent, EntParentChangedMessage>(OnParentChanged);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = EntityQueryEnumerator<CP14DamageableByMapComponent, DamageableComponent, MobStateComponent>();
while (query.MoveNext(out var uid, out var damage, out var damageable, out var mobState))
{
if (!damage.Enabled)
continue;
if (damage.NextDamageTime > _timing.CurTime)
continue;
damage.NextDamageTime = _timing.CurTime + TimeSpan.FromSeconds(2f);
if (damage.CurrentMap is null)
continue;
if (!_mobState.IsAlive(uid, mobState))
continue;
_damageable.TryChangeDamage(uid, damage.CurrentMap.Value.Comp.Damage, damageable: damageable);
_stamina.TakeStaminaDamage(uid, damage.CurrentMap.Value.Comp.StaminaDamage);
}
}
private void OnParentChanged(Entity<CP14DamageableByMapComponent> ent, ref EntParentChangedMessage args)
{
DisableDamage(ent);
if (args.OldParent == null || TerminatingOrDeleted(ent))
return;
var newParent = _transform.GetParentUid(ent);
if (!TryComp<CP14MapDamageComponent>(newParent, out var mapDamage))
return;
EnableDamage(ent, (newParent, mapDamage));
}
private void DisableDamage(Entity<CP14DamageableByMapComponent> ent)
{
if (!ent.Comp.Enabled)
return;
ent.Comp.Enabled = false;
ent.Comp.CurrentMap = null;
Dirty(ent);
}
private void EnableDamage(Entity<CP14DamageableByMapComponent> ent, Entity<CP14MapDamageComponent> map)
{
if (ent.Comp.Enabled)
return;
ent.Comp.Enabled = true;
ent.Comp.CurrentMap = map;
Dirty(ent);
}
}

View File

@@ -1,16 +0,0 @@
using Robust.Shared.Map;
namespace Content.Server._CP14.PortalAutoLink;
/// <summary>
/// allows you to automatically link entities to each other, through key matching searches
/// </summary>
[RegisterComponent, Access(typeof(CP14AutoLinkSystem))]
public sealed partial class CP14AutoLinkComponent : Component
{
/// <summary>
/// a key that is used to search for another autolinked entity installed in the worlds
/// </summary>
[DataField]
public string? AutoLinkKey = "Hello";
}

View File

@@ -1,44 +0,0 @@
using Content.Shared.Interaction;
using Content.Shared.Teleportation.Systems;
namespace Content.Server._CP14.PortalAutoLink;
public sealed partial class CP14AutoLinkSystem : EntitySystem
{
[Dependency] private readonly LinkedEntitySystem _link = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CP14AutoLinkComponent, MapInitEvent>(OnMapInit);
}
private void OnMapInit(Entity<CP14AutoLinkComponent> autolink, ref MapInitEvent args)
{
TryAutoLink(autolink, out var otherLink);
}
public bool TryAutoLink(Entity<CP14AutoLinkComponent> autolink, out EntityUid? linkedEnt)
{
linkedEnt = null;
var query = EntityQueryEnumerator<CP14AutoLinkComponent>();
while (query.MoveNext(out var uid, out var otherAutolink))
{
if (autolink.Comp == otherAutolink)
continue;
if (autolink.Comp.AutoLinkKey == otherAutolink.AutoLinkKey)
{
if (_link.TryLink(autolink, uid, false))
{
RemComp<CP14AutoLinkComponent>(uid);
RemComp<CP14AutoLinkComponent>(autolink);
return true;
}
}
}
return false;
}
}

View File

@@ -0,0 +1,8 @@
namespace Content.Server._CP14.RoundRemoveShuttle;
[RegisterComponent]
public sealed partial class CP14RoundRemoveShuttleComponent : Component
{
[DataField]
public EntityUid Station;
}

View File

@@ -0,0 +1,95 @@
using System.Globalization;
using System.Linq;
using Content.Server.Chat.Systems;
using Content.Server.Mind;
using Content.Server.Shuttles.Events;
using Content.Server.Station.Systems;
using Content.Shared.Administration.Logs;
using Content.Shared.Database;
using Content.Shared.IdentityManagement.Components;
using Content.Shared.Mind.Components;
using Content.Shared.Mobs.Systems;
using Content.Shared.Roles;
using Content.Shared.Roles.Jobs;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.RoundRemoveShuttle;
public sealed partial class CP14RoundRemoveShuttleSystem : EntitySystem
{
[Dependency] private readonly ISharedAdminLogManager _adminLog = default!;
[Dependency] private readonly ChatSystem _chatSystem = default!;
[Dependency] private readonly MindSystem _mind = default!;
[Dependency] private readonly StationJobsSystem _stationJobs = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CP14RoundRemoveShuttleComponent, FTLCompletedEvent>(OnFTLComplete);
}
private void OnFTLComplete(Entity<CP14RoundRemoveShuttleComponent> ent, ref FTLCompletedEvent args)
{
var childrens = Transform(ent).ChildEnumerator;
HashSet<EntityUid> toDelete = new();
while (childrens.MoveNext(out var uid))
{
if (!_mind.TryGetMind(uid, out _, out var mindComp))
continue;
//Trying return all jobs roles
var userId = mindComp.UserId;
ProtoId<JobPrototype>? playerJob = null;
string? jobName = null;
if (userId is not null)
{
RestoreJobs(ent.Comp.Station, userId.Value, out playerJob);
if (_proto.TryIndex(playerJob, out var indexedJob))
{
jobName = Loc.GetString(indexedJob.Name);
}
}
_adminLog.Add(LogType.Action,
LogImpact.High,
$"{ToPrettyString(uid):player} was leave the round on traveling merchant ship");
_chatSystem.DispatchStationAnnouncement(ent.Comp.Station,
Loc.GetString(
_mobState.IsDead(uid) ? "cp14-earlyleave-ship-announcement-dead" : "cp14-earlyleave-ship-announcement",
("character", mindComp.CharacterName ?? "Unknown"),
("job", CultureInfo.CurrentCulture.TextInfo.ToTitleCase(jobName ?? "Unknown"))
),
Loc.GetString("cp14-ship-sender"),
playDefaultSound: false
);
toDelete.Add(uid);
}
while (toDelete.Count > 0)
{
var r = toDelete.First();
toDelete.Remove(r);
QueueDel(r);
}
}
private void RestoreJobs(EntityUid station, NetUserId userId, out ProtoId<JobPrototype>? outJob)
{
outJob = null;
if (!_stationJobs.TryGetPlayerJobs(station, userId, out var jobs))
return;
foreach (var job in jobs)
{
_stationJobs.TryAdjustJobSlot(station, job, 1, clamp: true);
outJob = job;
}
_stationJobs.TryRemovePlayerJobs(station, userId);
}
}

View File

@@ -0,0 +1,94 @@
using System.Linq;
using Content.Server._CP14.ZLevels.Components;
using Content.Server.Administration;
using Content.Shared.Administration;
using Robust.Shared.Console;
using Robust.Shared.Map;
namespace Content.Server._CP14.ZLevels.Commands;
[AdminCommand(AdminFlags.VarEdit)]
public sealed class CP14CombineMapsIntoZLevelsCommand : LocalizedCommands
{
[Dependency] private readonly IEntityManager _entities = default!;
[Dependency] private readonly IMapManager _map = default!;
private const string Name = "cp14-combineMapsIntoZLevels";
public override string Command => Name;
public override string Description => "Connects a number of maps into a common network of z-levels. Does not work if one of the maps is already in the z-level network";
public override string Help => $"{Name} <MapId 1> <MapId 2> ... <MapId X> (from ground to sky)";
public override void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length == 1)
{
shell.WriteError("Not enough maps to form a network of levels");
return;
}
List<MapId> maps = new();
foreach (var arg in args)
{
if (!int.TryParse(arg, out var mapIdInt))
{
shell.WriteError($"Cannot parse `{arg}` into mapId");
return;
}
var mapId = new MapId(mapIdInt);
if (mapId == MapId.Nullspace)
{
shell.WriteError($"Cannot parse NullSpace");
return;
}
if (!_map.MapExists(mapId))
{
shell.WriteError($"Map {mapId} dont exist");
return;
}
//if (!_mapSystem.TryGetMap(mapId, out var mapUid))
//{
// shell.WriteError($"Map {mapId} dont exist");
// return;
//}
if (maps.Contains(mapId))
{
shell.WriteError($"Duplication maps: {mapId}");
return;
}
maps.Add(mapId);
}
//Check maps already in zLevel links
var query = _entities.EntityQueryEnumerator<CP14StationZLevelsComponent>();
while (query.MoveNext(out var uid, out var zLevelComp))
{
foreach (var findMap in maps)
{
if (zLevelComp.LevelEntities.ContainsKey(findMap))
{
shell.WriteError($"{findMap} already in z-level network! Z-Network Entity: {uid}");
return;
}
}
}
//Ok, all check passed, we create new z-level network
var zLevelEnt = _entities.Spawn();
_entities.EnsureComponent<CP14StationZLevelsComponent>(zLevelEnt, out var newZLevelComp);
var count = 0;
foreach (var map in maps)
{
newZLevelComp.LevelEntities.Add(map, count);
count++;
}
shell.WriteLine($"Successfully created z-level network! Z-Network entity: {zLevelEnt}");
}
}

View File

@@ -1,13 +1,14 @@
using Content.Server._CP14.StationDungeonMap.EntitySystems;
using Content.Server._CP14.ZLevels.Commands;
using Content.Server._CP14.ZLevels.EntitySystems;
using Robust.Shared.Map;
using Robust.Shared.Utility;
namespace Content.Server._CP14.StationDungeonMap.Components;
namespace Content.Server._CP14.ZLevels.Components;
/// <summary>
/// Initializes the z-level system by creating a series of linked maps
/// </summary>
[RegisterComponent, Access(typeof(CP14StationZLevelsSystem))]
[RegisterComponent, Access(typeof(CP14StationZLevelsSystem), typeof(CP14CombineMapsIntoZLevelsCommand))]
public sealed partial class CP14StationZLevelsComponent : Component
{
[DataField(required: true)]

View File

@@ -1,7 +1,7 @@
using Content.Server._CP14.StationDungeonMap.EntitySystems;
using Content.Server._CP14.ZLevels.EntitySystems;
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.StationDungeonMap.Components;
namespace Content.Server._CP14.ZLevels.Components;
/// <summary>
/// automatically creates a linked portal at a different relative z-level, and then the component is removed

View File

@@ -0,0 +1,51 @@
using System.Numerics;
using Content.Shared._CP14.ZLevel;
using Content.Shared.Ghost;
using Robust.Shared.Map;
namespace Content.Server._CP14.ZLevels.EntitySystems;
public sealed partial class CP14StationZLevelsSystem
{
private void InitActions()
{
SubscribeLocalEvent<GhostComponent, CP14ZLevelActionUp>(OnZLevelUp);
SubscribeLocalEvent<GhostComponent, CP14ZLevelActionDown>(OnZLevelDown);
}
private void OnZLevelDown(Entity<GhostComponent> ent, ref CP14ZLevelActionDown args)
{
if (args.Handled)
return;
ZLevelMove(ent, -1);
args.Handled = true;
}
private void OnZLevelUp(Entity<GhostComponent> ent, ref CP14ZLevelActionUp args)
{
if (args.Handled)
return;
ZLevelMove(ent, 1);
args.Handled = true;
}
private void ZLevelMove(EntityUid ent, int offset)
{
var xform = Transform(ent);
var map = xform.MapUid;
if (map is null)
return;
var targetMap = GetMapOffset(map.Value, offset);
if (targetMap is null)
return;
_transform.SetMapCoordinates(ent, new MapCoordinates(_transform.GetWorldPosition(ent), targetMap.Value));
}
}

View File

@@ -0,0 +1,51 @@
using Content.Server._CP14.ZLevels.Components;
using Content.Server.GameTicking.Events;
using Content.Shared.Teleportation.Systems;
using Robust.Shared.Map;
namespace Content.Server._CP14.ZLevels.EntitySystems;
public sealed partial class CP14StationZLevelsSystem
{
[Dependency] private readonly LinkedEntitySystem _linkedEntity = default!;
private void InitializePortals()
{
SubscribeLocalEvent<RoundStartingEvent>(OnRoundStart);
SubscribeLocalEvent<CP14ZLevelAutoPortalComponent, MapInitEvent>(OnPortalMapInit);
}
private void OnRoundStart(RoundStartingEvent ev)
{
var query = EntityQueryEnumerator<CP14ZLevelAutoPortalComponent>();
while (query.MoveNext(out var uid, out var portal))
{
InitPortal((uid, portal));
}
}
private void OnPortalMapInit(Entity<CP14ZLevelAutoPortalComponent> autoPortal, ref MapInitEvent args)
{
InitPortal(autoPortal);
}
private void InitPortal(Entity<CP14ZLevelAutoPortalComponent> autoPortal)
{
var mapId = Transform(autoPortal).MapUid;
if (mapId is null)
return;
var offsetMap = GetMapOffset(mapId.Value, autoPortal.Comp.ZLevelOffset);
if (offsetMap is null)
return;
var currentWorldPos = _transform.GetWorldPosition(autoPortal);
var targetMapPos = new MapCoordinates(currentWorldPos, offsetMap.Value);
var otherSidePortal = Spawn(autoPortal.Comp.OtherSideProto, targetMapPos);
_transform.SetWorldRotation(otherSidePortal, _transform.GetWorldRotation(autoPortal));
if (_linkedEntity.TryLink(autoPortal, otherSidePortal, true))
RemComp<CP14ZLevelAutoPortalComponent>(autoPortal);
}
}

View File

@@ -1,17 +1,14 @@
using Content.Server._CP14.StationDungeonMap.Components;
using Content.Server.GameTicking.Events;
using Content.Server._CP14.ZLevels.Components;
using Content.Server.Station.Components;
using Content.Server.Station.Events;
using Content.Server.Station.Systems;
using Content.Shared.Maps;
using Content.Shared.Station.Components;
using Content.Shared.Teleportation.Systems;
using Robust.Server.GameObjects;
using Robust.Server.Maps;
using Robust.Shared.Map;
using Robust.Shared.Random;
namespace Content.Server._CP14.StationDungeonMap.EntitySystems;
namespace Content.Server._CP14.ZLevels.EntitySystems;
public sealed partial class CP14StationZLevelsSystem : EntitySystem
{
@@ -20,29 +17,18 @@ public sealed partial class CP14StationZLevelsSystem : EntitySystem
[Dependency] private readonly MapLoaderSystem _mapLoader = default!;
[Dependency] private readonly TransformSystem _transform = default!;
[Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly TileSystem _tile = default!;
[Dependency] private readonly SharedMapSystem _maps = default!;
[Dependency] private readonly LinkedEntitySystem _linkedEntity = default!;
public override void Initialize()
{
base.Initialize();
InitializePortals();
InitActions();
SubscribeLocalEvent<CP14ZLevelAutoPortalComponent, MapInitEvent>(OnPortalMapInit);
SubscribeLocalEvent<RoundStartingEvent>(OnRoundStart);
SubscribeLocalEvent<CP14StationZLevelsComponent, StationPostInitEvent>(OnStationPostInit);
}
private void OnRoundStart(RoundStartingEvent ev)
{
var query = EntityQueryEnumerator<CP14ZLevelAutoPortalComponent>();
while (query.MoveNext(out var uid, out var portal))
{
InitPortal((uid, portal));
}
}
private void OnStationPostInit(Entity<CP14StationZLevelsComponent> ent, ref StationPostInitEvent args)
{
if (ent.Comp.Initialized)
@@ -98,35 +84,10 @@ public sealed partial class CP14StationZLevelsSystem : EntitySystem
}
}
private void OnPortalMapInit(Entity<CP14ZLevelAutoPortalComponent> autoPortal, ref MapInitEvent args)
{
InitPortal(autoPortal);
}
private void InitPortal(Entity<CP14ZLevelAutoPortalComponent> autoPortal)
{
var mapId = Transform(autoPortal).MapUid;
if (mapId is null)
return;
var offsetMap = GetMapOffset(mapId.Value, autoPortal.Comp.ZLevelOffset);
if (offsetMap is null)
return;
var currentWorldPos = _transform.GetWorldPosition(autoPortal);
var targetMapPos = new MapCoordinates(currentWorldPos, offsetMap.Value);
var otherSidePortal = Spawn(autoPortal.Comp.OtherSideProto, targetMapPos);
if (_linkedEntity.TryLink(autoPortal, otherSidePortal, true))
RemComp<CP14ZLevelAutoPortalComponent>(autoPortal);
}
public MapId? GetMapOffset(EntityUid mapUid, int offset)
{
var query = EntityQueryEnumerator<CP14StationZLevelsComponent, StationDataComponent>();
while (query.MoveNext(out var uid, out var zLevel, out _))
var query = EntityQueryEnumerator<CP14StationZLevelsComponent>();
while (query.MoveNext(out var uid, out var zLevel))
{
if (!zLevel.LevelEntities.TryGetValue(Transform(mapUid).MapID, out var currentLevel))
continue;