removes beforeserialization hook (#12319)

This commit is contained in:
Paul Ritter
2022-11-03 02:41:12 +01:00
committed by GitHub
parent 6eca66a637
commit c5e5729bd4
14 changed files with 199 additions and 229 deletions

View File

@@ -1,42 +1,31 @@
using System; using System.Linq;
using System.Collections.Generic;
using Content.Shared.Gravity; using Content.Shared.Gravity;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Client.Gravity namespace Content.Client.Gravity
{ {
[UsedImplicitly] [UsedImplicitly]
public sealed class GravityGeneratorVisualizer : AppearanceVisualizer, ISerializationHooks public sealed class GravityGeneratorVisualizer : AppearanceVisualizer
{ {
[DataField("spritemap")] [DataField("spritemap")]
private Dictionary<string, string> _rawSpriteMap = new(); private Dictionary<string, string> _rawSpriteMap
private Dictionary<GravityGeneratorStatus, string> _spriteMap = new();
void ISerializationHooks.BeforeSerialization()
{ {
_rawSpriteMap = new Dictionary<string, string>(); get => _spriteMap.ToDictionary(x => x.Value.ToString().ToLower(), x => x.Value);
foreach (var (status, sprite) in _spriteMap) set
{
_rawSpriteMap.Add(status.ToString().ToLower(), sprite);
}
}
void ISerializationHooks.AfterDeserialization()
{ {
// Get Sprites for each status // Get Sprites for each status
foreach (var status in (GravityGeneratorStatus[]) Enum.GetValues(typeof(GravityGeneratorStatus))) foreach (var status in (GravityGeneratorStatus[]) Enum.GetValues(typeof(GravityGeneratorStatus)))
{ {
if (_rawSpriteMap.TryGetValue(status.ToString().ToLower(), out var sprite)) if (value.TryGetValue(status.ToString().ToLower(), out var sprite))
{ {
_spriteMap[status] = sprite; _spriteMap[status] = sprite;
} }
} }
} }
}
private Dictionary<GravityGeneratorStatus, string> _spriteMap = new();
[Obsolete("Subscribe to your component being initialised instead.")] [Obsolete("Subscribe to your component being initialised instead.")]
public override void InitializeEntity(EntityUid entity) public override void InitializeEntity(EntityUid entity)

View File

@@ -1,8 +1,5 @@
using System;
using Content.Shared.Research.Components; using Content.Shared.Research.Components;
using Content.Shared.Research.Prototypes; using Content.Shared.Research.Prototypes;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
namespace Content.Client.Research namespace Content.Client.Research
@@ -21,14 +18,14 @@ namespace Content.Client.Research
if (curState is not TechnologyDatabaseState state) return; if (curState is not TechnologyDatabaseState state) return;
Technologies.Clear(); TechnologyIds.Clear();
var protoManager = IoCManager.Resolve<IPrototypeManager>(); var protoManager = IoCManager.Resolve<IPrototypeManager>();
foreach (var techID in state.Technologies) foreach (var techID in state.Technologies)
{ {
if (!protoManager.TryIndex(techID, out TechnologyPrototype? technology)) continue; if (!protoManager.HasIndex<TechnologyPrototype>(techID)) continue;
Technologies.Add(technology); TechnologyIds.Add(techID);
} }
OnDatabaseUpdated?.Invoke(); OnDatabaseUpdated?.Invoke();

View File

@@ -53,7 +53,7 @@ namespace Content.Client.Research.UI
public bool IsTechnologyUnlocked(TechnologyPrototype technology) public bool IsTechnologyUnlocked(TechnologyPrototype technology)
{ {
return _technologyDatabase?.IsTechnologyUnlocked(technology) ?? false; return _technologyDatabase?.IsTechnologyUnlocked(technology.ID) ?? false;
} }
public bool CanUnlockTechnology(TechnologyPrototype technology) public bool CanUnlockTechnology(TechnologyPrototype technology)

View File

@@ -1,7 +1,7 @@
using Content.Server.Atmos.EntitySystems; using Content.Server.Atmos.EntitySystems;
using Content.Server.Atmos.Piping.Components; using Content.Server.Atmos.Piping.Components;
using Content.Server.Atmos.Serialization;
using Content.Server.NodeContainer.NodeGroups; using Content.Server.NodeContainer.NodeGroups;
using Robust.Shared.Serialization;
namespace Content.Server.Atmos.Components namespace Content.Server.Atmos.Components
{ {
@@ -10,7 +10,7 @@ namespace Content.Server.Atmos.Components
/// </summary> /// </summary>
[RegisterComponent, Serializable, [RegisterComponent, Serializable,
Access(typeof(AtmosphereSystem), typeof(GasTileOverlaySystem), typeof(AtmosDebugOverlaySystem))] Access(typeof(AtmosphereSystem), typeof(GasTileOverlaySystem), typeof(AtmosDebugOverlaySystem))]
public sealed class GridAtmosphereComponent : Component, ISerializationHooks public sealed class GridAtmosphereComponent : Component
{ {
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public bool Simulated { get; set; } = true; public bool Simulated { get; set; } = true;
@@ -24,13 +24,8 @@ namespace Content.Server.Atmos.Components
[ViewVariables] [ViewVariables]
public int UpdateCounter { get; set; } = 1; // DO NOT SET TO ZERO BY DEFAULT! It will break roundstart atmos... public int UpdateCounter { get; set; } = 1; // DO NOT SET TO ZERO BY DEFAULT! It will break roundstart atmos...
[DataField("uniqueMixes")]
public List<GasMixture>? UniqueMixes;
[DataField("tiles")]
public Dictionary<Vector2i, int>? TilesUniqueMixes;
[ViewVariables] [ViewVariables]
[IncludeDataField(customTypeSerializer:typeof(TileAtmosCollectionSerializer))]
public readonly Dictionary<Vector2i, TileAtmosphere> Tiles = new(1000); public readonly Dictionary<Vector2i, TileAtmosphere> Tiles = new(1000);
[ViewVariables] [ViewVariables]
@@ -95,34 +90,5 @@ namespace Content.Server.Atmos.Components
[ViewVariables] [ViewVariables]
public AtmosphereProcessingState State { get; set; } = AtmosphereProcessingState.Revalidate; public AtmosphereProcessingState State { get; set; } = AtmosphereProcessingState.Revalidate;
void ISerializationHooks.BeforeSerialization()
{
var uniqueMixes = new List<GasMixture>();
var uniqueMixHash = new Dictionary<GasMixture, int>();
var tiles = new Dictionary<Vector2i, int>();
foreach (var (indices, tile) in Tiles)
{
if (tile.Air == null) continue;
if (uniqueMixHash.TryGetValue(tile.Air, out var index))
{
tiles[indices] = index;
continue;
}
uniqueMixes.Add(tile.Air);
var newIndex = uniqueMixes.Count - 1;
uniqueMixHash[tile.Air] = newIndex;
tiles[indices] = newIndex;
}
if (uniqueMixes.Count == 0) uniqueMixes = null;
if (tiles.Count == 0) tiles = null;
UniqueMixes = uniqueMixes;
TilesUniqueMixes = tiles;
}
} }
} }

View File

@@ -2,7 +2,6 @@ using System.Linq;
using Content.Server.Atmos.Components; using Content.Server.Atmos.Components;
using Content.Server.Atmos.Reactions; using Content.Server.Atmos.Reactions;
using Content.Shared.Atmos; using Content.Shared.Atmos;
using Content.Shared.Maps;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Utility; using Robust.Shared.Utility;
@@ -44,29 +43,13 @@ public sealed partial class AtmosphereSystem
{ {
base.Initialize(); base.Initialize();
gridAtmosphere.Tiles.Clear();
if (!TryComp(uid, out IMapGridComponent? mapGrid)) if (!TryComp(uid, out IMapGridComponent? mapGrid))
return; return;
if (gridAtmosphere.TilesUniqueMixes != null) foreach (var (indices, tile) in gridAtmosphere.Tiles)
{ {
foreach (var (indices, mix) in gridAtmosphere.TilesUniqueMixes)
{
try
{
gridAtmosphere.Tiles.Add(indices, new TileAtmosphere(mapGrid.Owner, indices,
gridAtmosphere.UniqueMixes![mix].Clone()));
}
catch (ArgumentOutOfRangeException)
{
Logger.Error(
$"Error during atmos serialization! Tile at {indices} points to an unique mix ({mix}) out of range!");
throw;
}
gridAtmosphere.InvalidatedCoords.Add(indices); gridAtmosphere.InvalidatedCoords.Add(indices);
} tile.GridIndex = uid;
} }
GridRepopulateTiles(mapGrid.Grid, gridAtmosphere); GridRepopulateTiles(mapGrid.Grid, gridAtmosphere);
@@ -334,7 +317,7 @@ public sealed partial class AtmosphereSystem
{ {
adjacent = new TileAtmosphere(tile.GridIndex, otherIndices, adjacent = new TileAtmosphere(tile.GridIndex, otherIndices,
GetTileMixture(null, mapUid, otherIndices), GetTileMixture(null, mapUid, otherIndices),
space:IsTileSpace(null, mapUid, otherIndices, mapGridComp)); space: IsTileSpace(null, mapUid, otherIndices, mapGridComp));
} }
var oppositeDirection = direction.GetOpposite(); var oppositeDirection = direction.GetOpposite();
@@ -531,7 +514,7 @@ public sealed partial class AtmosphereSystem
{ {
if (!gridAtmosphere.Tiles.ContainsKey(tile.GridIndices)) if (!gridAtmosphere.Tiles.ContainsKey(tile.GridIndices))
gridAtmosphere.Tiles[tile.GridIndices] = new TileAtmosphere(tile.GridUid, tile.GridIndices, gridAtmosphere.Tiles[tile.GridIndices] = new TileAtmosphere(tile.GridUid, tile.GridIndices,
new GasMixture(volume) {Temperature = Atmospherics.T20C}); new GasMixture(volume) { Temperature = Atmospherics.T20C });
gridAtmosphere.InvalidatedCoords.Add(tile.GridIndices); gridAtmosphere.InvalidatedCoords.Add(tile.GridIndices);
} }

View File

@@ -3,7 +3,6 @@ using Content.Server.Atmos.Piping.Components;
using Content.Server.NodeContainer.NodeGroups; using Content.Server.NodeContainer.NodeGroups;
using Content.Shared.Atmos; using Content.Shared.Atmos;
using Content.Shared.Maps; using Content.Shared.Maps;
using Robust.Shared.Map;
using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Components;
using Robust.Shared.Timing; using Robust.Shared.Timing;
@@ -59,7 +58,8 @@ namespace Content.Server.Atmos.EntitySystems
{ {
if (!atmosphere.Tiles.TryGetValue(indices, out var tile)) if (!atmosphere.Tiles.TryGetValue(indices, out var tile))
{ {
tile = new TileAtmosphere(mapGrid.GridEntityId, indices, new GasMixture(volume){Temperature = Atmospherics.T20C}); tile = new TileAtmosphere(mapGrid.GridEntityId, indices,
new GasMixture(volume) { Temperature = Atmospherics.T20C });
atmosphere.Tiles[indices] = tile; atmosphere.Tiles[indices] = tile;
} }

View File

@@ -0,0 +1,89 @@
using Robust.Shared.Serialization.Manager;
using Robust.Shared.Serialization.Markdown;
using Robust.Shared.Serialization.Markdown.Mapping;
using Robust.Shared.Serialization.Markdown.Validation;
using Robust.Shared.Serialization.TypeSerializers.Interfaces;
namespace Content.Server.Atmos.Serialization;
public sealed class TileAtmosCollectionSerializer : ITypeSerializer<Dictionary<Vector2i, TileAtmosphere>, MappingDataNode>
{
public ValidationNode Validate(ISerializationManager serializationManager, MappingDataNode node,
IDependencyCollection dependencies, ISerializationContext? context = null)
{
return serializationManager.ValidateNode<TileAtmosData>(node, context);
}
public Dictionary<Vector2i, TileAtmosphere> Read(ISerializationManager serializationManager, MappingDataNode node, IDependencyCollection dependencies,
bool skipHook, ISerializationContext? context = null, Dictionary<Vector2i, TileAtmosphere>? value = default)
{
var data = serializationManager.Read<TileAtmosData>(node, context, skipHook);
var tiles = new Dictionary<Vector2i, TileAtmosphere>();
if (data.TilesUniqueMixes != null)
{
foreach (var (indices, mix) in data.TilesUniqueMixes)
{
try
{
tiles.Add(indices, new TileAtmosphere(EntityUid.Invalid, indices,
data.UniqueMixes![mix].Clone()));
}
catch (ArgumentOutOfRangeException)
{
Logger.Error(
$"Error during atmos serialization! Tile at {indices} points to an unique mix ({mix}) out of range!");
}
}
}
return tiles;
}
public DataNode Write(ISerializationManager serializationManager, Dictionary<Vector2i, TileAtmosphere> value, IDependencyCollection dependencies,
bool alwaysWrite = false, ISerializationContext? context = null)
{
var uniqueMixes = new List<GasMixture>();
var uniqueMixHash = new Dictionary<GasMixture, int>();
var tiles = new Dictionary<Vector2i, int>();
foreach (var (indices, tile) in value)
{
if (tile.Air == null) continue;
if (uniqueMixHash.TryGetValue(tile.Air, out var index))
{
tiles[indices] = index;
continue;
}
uniqueMixes.Add(tile.Air);
var newIndex = uniqueMixes.Count - 1;
uniqueMixHash[tile.Air] = newIndex;
tiles[indices] = newIndex;
}
if (uniqueMixes.Count == 0) uniqueMixes = null;
if (tiles.Count == 0) tiles = null;
return serializationManager.WriteValue(new TileAtmosData
{
UniqueMixes = uniqueMixes,
TilesUniqueMixes = tiles
}, alwaysWrite, context);
}
public Dictionary<Vector2i, TileAtmosphere> Copy(ISerializationManager serializationManager, Dictionary<Vector2i, TileAtmosphere> source, Dictionary<Vector2i, TileAtmosphere> target, bool skipHook,
ISerializationContext? context = null)
{
serializationManager.Copy(source, ref target, context, skipHook);
return target;
}
[DataDefinition]
private struct TileAtmosData
{
[DataField("uniqueMixes")] public List<GasMixture>? UniqueMixes;
[DataField("tiles")] public Dictionary<Vector2i, int>? TilesUniqueMixes;
}
}

View File

@@ -68,7 +68,8 @@ namespace Content.Server.Atmos
public AtmosDirection LastPressureDirection; public AtmosDirection LastPressureDirection;
[ViewVariables] [ViewVariables]
public EntityUid GridIndex { get; } [Access(typeof(AtmosphereSystem))]
public EntityUid GridIndex { get; set; }
[ViewVariables] [ViewVariables]
public TileRef? Tile => GridIndices.GetTileRef(GridIndex); public TileRef? Tile => GridIndices.GetTileRef(GridIndex);

View File

@@ -1,21 +1,21 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using Content.Server.Lathe.Components;
using Content.Shared.Lathe;
using Content.Shared.Materials;
using Content.Shared.Research.Prototypes;
using Content.Server.Research.Components;
using Content.Server.Research;
using Content.Shared.Research.Components;
using Robust.Server.GameObjects;
using Robust.Shared.Prototypes;
using JetBrains.Annotations;
using System.Linq; using System.Linq;
using Content.Server.Construction; using Content.Server.Construction;
using Content.Server.Lathe.Components;
using Content.Server.Materials; using Content.Server.Materials;
using Content.Server.Power.Components; using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems; using Content.Server.Power.EntitySystems;
using Content.Server.Research;
using Content.Server.Research.Components;
using Content.Server.UserInterface; using Content.Server.UserInterface;
using Content.Shared.Lathe;
using Content.Shared.Materials;
using Content.Shared.Research.Components;
using Content.Shared.Research.Prototypes;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Robust.Server.Player; using Robust.Server.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing; using Robust.Shared.Timing;
namespace Content.Server.Lathe namespace Content.Server.Lathe
@@ -202,8 +202,9 @@ namespace Content.Server.Lathe
return; return;
//gets all of the techs that are unlocked and also in the DynamicRecipes list //gets all of the techs that are unlocked and also in the DynamicRecipes list
var allTechs = (from tech in component.Technologies var allTechs = (from technology in from tech in component.TechnologyIds
from recipe in tech.UnlockedRecipes select _proto.Index<TechnologyPrototype>(tech)
from recipe in technology.UnlockedRecipes
where latheComponent.DynamicRecipes.Contains(recipe) where latheComponent.DynamicRecipes.Contains(recipe)
select recipe).ToList(); select recipe).ToList();

View File

@@ -1,6 +1,6 @@
using Content.Server.Power.EntitySystems; using Content.Server.Power.EntitySystems;
using Content.Server.Station.Systems;
using Content.Server.Research.Components; using Content.Server.Research.Components;
using Content.Server.Station.Systems;
using Content.Shared.Research.Prototypes; using Content.Shared.Research.Prototypes;
namespace Content.Server.Research; namespace Content.Server.Research;
@@ -70,7 +70,7 @@ public sealed partial class ResearchSystem
TechnologyDatabaseComponent? databaseComponent = null) TechnologyDatabaseComponent? databaseComponent = null)
{ {
if (!Resolve(component.Owner, ref databaseComponent, false)) return false; if (!Resolve(component.Owner, ref databaseComponent, false)) return false;
return databaseComponent.IsTechnologyUnlocked(prototype); return databaseComponent.IsTechnologyUnlocked(prototype.ID);
} }
public bool CanUnlockTechnology(ResearchServerComponent component, TechnologyPrototype technology, TechnologyDatabaseComponent? databaseComponent = null) public bool CanUnlockTechnology(ResearchServerComponent component, TechnologyPrototype technology, TechnologyDatabaseComponent? databaseComponent = null)

View File

@@ -14,7 +14,7 @@ public sealed partial class ResearchSystem
private void OnTechnologyGetState(EntityUid uid, TechnologyDatabaseComponent component, ref ComponentGetState args) private void OnTechnologyGetState(EntityUid uid, TechnologyDatabaseComponent component, ref ComponentGetState args)
{ {
args.State = new TechnologyDatabaseState(component.Technologies); args.State = new TechnologyDatabaseState(component.TechnologyIds);
} }
/// <summary> /// <summary>
@@ -26,7 +26,7 @@ public sealed partial class ResearchSystem
/// <param name="twoway">Whether the other database should be synced against this one too or not.</param> /// <param name="twoway">Whether the other database should be synced against this one too or not.</param>
public void Sync(TechnologyDatabaseComponent component, TechnologyDatabaseComponent otherDatabase, bool twoway = true) public void Sync(TechnologyDatabaseComponent component, TechnologyDatabaseComponent otherDatabase, bool twoway = true)
{ {
foreach (var tech in otherDatabase.Technologies) foreach (var tech in otherDatabase.TechnologyIds)
{ {
if (!component.IsTechnologyUnlocked(tech)) AddTechnology(component, tech); if (!component.IsTechnologyUnlocked(tech)) AddTechnology(component, tech);
} }
@@ -62,7 +62,7 @@ public sealed partial class ResearchSystem
{ {
if (!component.CanUnlockTechnology(technology)) return false; if (!component.CanUnlockTechnology(technology)) return false;
AddTechnology(component, technology); AddTechnology(component, technology.ID);
Dirty(component); Dirty(component);
return true; return true;
} }
@@ -71,8 +71,8 @@ public sealed partial class ResearchSystem
/// Adds a technology to the database without checking if it could be unlocked. /// Adds a technology to the database without checking if it could be unlocked.
/// </summary> /// </summary>
/// <param name="technology"></param> /// <param name="technology"></param>
public void AddTechnology(TechnologyDatabaseComponent component, TechnologyPrototype technology) public void AddTechnology(TechnologyDatabaseComponent component, string technology)
{ {
component.Technologies.Add(technology); component.TechnologyIds.Add(technology);
} }
} }

View File

@@ -1,5 +1,4 @@
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared.Alert namespace Content.Shared.Alert
{ {
@@ -8,44 +7,36 @@ namespace Content.Shared.Alert
/// </summary> /// </summary>
[Prototype("alertOrder")] [Prototype("alertOrder")]
[DataDefinition] [DataDefinition]
public sealed class AlertOrderPrototype : IPrototype, IComparer<AlertPrototype>, ISerializationHooks public sealed class AlertOrderPrototype : IPrototype, IComparer<AlertPrototype>
{ {
[ViewVariables] [ViewVariables]
[IdDataFieldAttribute] [IdDataFieldAttribute]
public string ID { get; } = default!; public string ID { get; } = default!;
[DataField("order")] private readonly List<(string type, string alert)> _order = new(); [DataField("order")]
private List<(string type, string alert)> Order
private readonly Dictionary<AlertType, int> _typeToIdx = new();
private readonly Dictionary<AlertCategory, int> _categoryToIdx = new();
void ISerializationHooks.BeforeSerialization()
{ {
_order.Clear(); get
{
var orderArray = new KeyValuePair<string, string>[_typeToIdx.Count + _categoryToIdx.Count]; var res = new List<(string, string)>(_typeToIdx.Count + _categoryToIdx.Count);
foreach (var (type, id) in _typeToIdx) foreach (var (type, id) in _typeToIdx)
{ {
orderArray[id] = new KeyValuePair<string, string>("alertType", type.ToString()); res.Insert(id, ("alertType", type.ToString()));
} }
foreach (var (category, id) in _categoryToIdx) foreach (var (category, id) in _categoryToIdx)
{ {
orderArray[id] = new KeyValuePair<string, string>("category", category.ToString()); res.Insert(id, ("category", category.ToString()));
} }
foreach (var (type, alert) in orderArray) return res;
{
_order.Add((type, alert));
} }
} set
void ISerializationHooks.AfterDeserialization()
{ {
var i = 0; var i = 0;
foreach (var (type, alert) in _order) foreach (var (type, alert) in value)
{ {
switch (type) switch (type)
{ {
@@ -60,6 +51,10 @@ namespace Content.Shared.Alert
} }
} }
} }
}
private readonly Dictionary<AlertType, int> _typeToIdx = new();
private readonly Dictionary<AlertCategory, int> _categoryToIdx = new();
private int GetOrderIndex(AlertPrototype alert) private int GetOrderIndex(AlertPrototype alert)
{ {

View File

@@ -1,8 +1,8 @@
using Content.Shared.Damage; using Content.Shared.Damage;
using Content.Shared.Tools; using Content.Shared.Tools;
using JetBrains.Annotations;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
@@ -146,26 +146,27 @@ public sealed class DoorComponent : Component, ISerializationHooks
/// Time until next state change. Because apparently <see cref="IGameTiming.CurTime"/> might not get saved/restored. /// Time until next state change. Because apparently <see cref="IGameTiming.CurTime"/> might not get saved/restored.
/// </summary> /// </summary>
[DataField("SecondsUntilStateChange")] [DataField("SecondsUntilStateChange")]
private float? _secondsUntilStateChange; private float? SecondsUntilStateChange
{
void ISerializationHooks.BeforeSerialization() [UsedImplicitly]
get
{ {
if (NextStateChange == null) if (NextStateChange == null)
{ {
_secondsUntilStateChange = null; return null;
return;
};
var curTime = IoCManager.Resolve<IGameTiming>().CurTime;
_secondsUntilStateChange = (float) (NextStateChange.Value - curTime).TotalSeconds;
} }
void ISerializationHooks.AfterDeserialization() var curTime = IoCManager.Resolve<IGameTiming>().CurTime;
return (float) (NextStateChange.Value - curTime).TotalSeconds;
}
set
{ {
if (_secondsUntilStateChange == null || _secondsUntilStateChange.Value > 0) if (value == null || value.Value > 0)
return; return;
NextStateChange = IoCManager.Resolve<IGameTiming>().CurTime + TimeSpan.FromSeconds(_secondsUntilStateChange.Value); NextStateChange = IoCManager.Resolve<IGameTiming>().CurTime + TimeSpan.FromSeconds(value.Value);
}
} }
#endregion #endregion

View File

@@ -1,77 +1,25 @@
using System.Collections;
using Content.Shared.Research.Prototypes; using Content.Shared.Research.Prototypes;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
namespace Content.Shared.Research.Components namespace Content.Shared.Research.Components
{ {
[NetworkedComponent()] [NetworkedComponent()]
public abstract class SharedTechnologyDatabaseComponent : Component, IEnumerable<TechnologyPrototype>, ISerializationHooks public abstract class SharedTechnologyDatabaseComponent : Component
{ {
[DataField("technologies")] private List<string> _technologyIds = new(); [DataField("technologies", customTypeSerializer: typeof(PrototypeIdListSerializer<TechnologyPrototype>))]
public readonly List<string> TechnologyIds = new();
public List<TechnologyPrototype> Technologies = new();
void ISerializationHooks.BeforeSerialization()
{
var techIds = new List<string>();
foreach (var tech in Technologies)
{
techIds.Add(tech.ID);
}
_technologyIds = techIds;
}
void ISerializationHooks.AfterDeserialization()
{
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
foreach (var id in _technologyIds)
{
if (prototypeManager.TryIndex(id, out TechnologyPrototype? tech))
{
Technologies.Add(tech);
}
}
}
public IEnumerator<TechnologyPrototype> GetEnumerator()
{
return Technologies.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <summary>
/// Returns a list with the IDs of all unlocked technologies.
/// </summary>
/// <returns>A list of technology IDs</returns>
public List<string> GetTechnologyIdList()
{
List<string> techIds = new List<string>();
foreach (var tech in Technologies)
{
techIds.Add(tech.ID);
}
return techIds;
}
/// <summary> /// <summary>
/// Returns whether a technology is unlocked on this database or not. /// Returns whether a technology is unlocked on this database or not.
/// </summary> /// </summary>
/// <param name="technology">The technology to be checked</param> /// <param name="technology">The technology to be checked</param>
/// <returns>Whether it is unlocked or not</returns> /// <returns>Whether it is unlocked or not</returns>
public bool IsTechnologyUnlocked(TechnologyPrototype technology) public bool IsTechnologyUnlocked(string technologyId)
{ {
return Technologies.Contains(technology); return TechnologyIds.Contains(technologyId);
} }
/// <summary> /// <summary>
@@ -82,7 +30,7 @@ namespace Content.Shared.Research.Components
/// <returns>Whether it could be unlocked or not</returns> /// <returns>Whether it could be unlocked or not</returns>
public bool CanUnlockTechnology(TechnologyPrototype technology) public bool CanUnlockTechnology(TechnologyPrototype technology)
{ {
if (technology == null || IsTechnologyUnlocked(technology)) return false; if (IsTechnologyUnlocked(technology.ID)) return false;
var protoMan = IoCManager.Resolve<IPrototypeManager>(); var protoMan = IoCManager.Resolve<IPrototypeManager>();
foreach (var technologyId in technology.RequiredTechnologies) foreach (var technologyId in technology.RequiredTechnologies)
{ {
@@ -90,7 +38,7 @@ namespace Content.Shared.Research.Components
if (requiredTechnology == null) if (requiredTechnology == null)
return false; return false;
if (!IsTechnologyUnlocked(requiredTechnology)) if (!IsTechnologyUnlocked(requiredTechnology.ID))
return false; return false;
} }
return true; return true;