Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Appearance Weakrefs #1815

Merged
merged 95 commits into from
Jan 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
0cd7159
well it compiles...
amylizzle May 28, 2024
8dd14ad
plus one for you
amylizzle May 28, 2024
b985a60
work you fucker
amylizzle May 29, 2024
f2bf4b1
close, but no cigar
amylizzle May 29, 2024
a3d195d
gotcha
amylizzle May 29, 2024
68c058e
linter and cleanup
amylizzle May 29, 2024
24651fb
fine, be like that
amylizzle May 29, 2024
f32412a
break everything
amylizzle May 29, 2024
8487c93
I am confused and bewlidered
amylizzle May 29, 2024
f40b43b
Merge branch 'master' into appearanceRefCounts
amylizzle May 29, 2024
8839dfd
Merge branch 'master' into appearanceRefCounts
amylizzle Jun 3, 2024
b9fcfc9
lint
amylizzle Jun 7, 2024
189d3ef
more lint
amylizzle Jun 7, 2024
b96cf5e
Merge branch 'master' into appearanceRefCounts
amylizzle Jun 7, 2024
1b03b2d
gross
amylizzle Jun 10, 2024
1fb5f03
move a couple broken tests
amylizzle Jun 10, 2024
b2bb950
lint
amylizzle Jun 10, 2024
93df5d4
more lint
amylizzle Jun 10, 2024
6d8e331
Merge remote-tracking branch 'upstream/master' into appearanceRefCounts
amylizzle Jun 14, 2024
6e1a02d
Update OpenDreamRuntime/Rendering/ServerAppearanceSystem.cs
amylizzle Jun 14, 2024
79826de
Merge branch 'master' into appearanceRefCounts
amylizzle Jul 9, 2024
a5e76dd
area appearance, but memory churn
amylizzle Jul 9, 2024
0216403
Merge branch 'master' into appearanceRefCounts
amylizzle Oct 6, 2024
be94ae0
immutable start
amylizzle Oct 6, 2024
45a66c6
nobody keeps iconappearances anymore, only ids
amylizzle Oct 6, 2024
ab2ecfc
moreeee
amylizzle Oct 7, 2024
faa731d
faster area appearance editing
amylizzle Oct 7, 2024
d414565
bits
amylizzle Oct 7, 2024
294e84b
most of lists
amylizzle Oct 7, 2024
e6ea8e3
server compiles
amylizzle Oct 7, 2024
8b32fec
that is surprisingly not that broken
amylizzle Oct 7, 2024
2f9a7e6
fix order of ops on sprite creation
amylizzle Oct 7, 2024
cd5268b
fix turfs
amylizzle Oct 7, 2024
9eb2e54
fix one test
amylizzle Oct 7, 2024
d84c875
oops
amylizzle Oct 7, 2024
85ffe1c
weakrefs motherfucker
amylizzle Oct 11, 2024
ca1f6b7
bugs
amylizzle Oct 11, 2024
bd3f0e1
fixed it
amylizzle Oct 12, 2024
1561128
tracking down weird bugs
amylizzle Oct 12, 2024
5a991da
half done turf & area anims
amylizzle Oct 12, 2024
fc84fe9
Merge branch 'master' into appearanceRefCounts
amylizzle Oct 12, 2024
e2cd921
/mutable_appearance
amylizzle Oct 13, 2024
ed74230
fix colormatrix hashes
amylizzle Oct 13, 2024
babc6fe
enormous amount of linting
amylizzle Oct 13, 2024
b2d76af
missed one
amylizzle Oct 13, 2024
9db67b0
missed another
amylizzle Oct 13, 2024
2674ef7
gross
amylizzle Oct 13, 2024
774880a
move tests to integrated test
amylizzle Oct 13, 2024
04bee7d
don't love this
amylizzle Oct 13, 2024
9cc8285
Merge branch 'master' into appearanceRefCounts
amylizzle Oct 13, 2024
0485fe2
you know what? this PR should be larger
amylizzle Oct 13, 2024
897b62d
fun adventures in abusing networking
amylizzle Oct 14, 2024
b1f59e1
idk why this is necessary
amylizzle Oct 14, 2024
fea8e19
Merge branch 'master' into appearanceRefCounts
amylizzle Oct 14, 2024
16ca9de
overlays are confusing
amylizzle Oct 16, 2024
4391316
Overlays are immutable
amylizzle Oct 16, 2024
f5e4c14
shoulda just done it this way the first time
amylizzle Oct 16, 2024
db99b72
housekeeping
amylizzle Oct 18, 2024
bf40bba
fix a couple runtimes on paradise
amylizzle Oct 18, 2024
f4d793d
add turf anim test
amylizzle Oct 19, 2024
7d98138
need to make animated turfs have their own id somehow
amylizzle Oct 19, 2024
80da1ea
turf animations can go in another PR
amylizzle Oct 20, 2024
aa3a990
fixed it!
amylizzle Oct 21, 2024
4bc02c7
Merge branch 'master' into appearanceRefCounts
amylizzle Oct 22, 2024
e367a0f
reduce churn
amylizzle Oct 28, 2024
ea79f29
oh that should be locked
amylizzle Oct 28, 2024
104fa56
Merge branch 'master' into appearanceRefCounts
amylizzle Oct 29, 2024
02d4001
try caching mutables on the client?
amylizzle Oct 29, 2024
47a644c
just use immutables instead of doing shitloads of copying
amylizzle Oct 29, 2024
100150e
fix dir inheritence
amylizzle Oct 30, 2024
3d3feb9
remove that
amylizzle Oct 30, 2024
c18de10
don't double copy appearances
amylizzle Oct 30, 2024
c63f765
Merge branch 'master' into appearanceRefCounts
amylizzle Nov 8, 2024
2a11400
fix client image bugs
amylizzle Nov 11, 2024
f69f4be
Merge remote-tracking branch 'upstream/master' into appearanceRefCounts
amylizzle Nov 28, 2024
6945e90
fix merge
amylizzle Nov 28, 2024
dd9bb44
Merge branch 'master' into appearanceRefCounts
amylizzle Nov 30, 2024
b8ea258
Merge branch 'master' into appearanceRefCounts
amylizzle Dec 4, 2024
ccd1651
rename appearances
amylizzle Dec 26, 2024
425cf9b
no more hashes
amylizzle Dec 27, 2024
7e75397
lint roller
amylizzle Dec 27, 2024
de0e32d
try a thing
amylizzle Dec 29, 2024
b0b3981
Merge branch 'master' into appearanceRefCounts
amylizzle Dec 29, 2024
13b01fd
fix failing to GC
amylizzle Dec 29, 2024
ed8b9f0
remove collect call
amylizzle Dec 29, 2024
52c6f55
remove the TTL queue
amylizzle Dec 29, 2024
ab39b71
Only register movables' appearances when in PVS range
wixoaGit Dec 29, 2024
719f315
fix
amylizzle Dec 29, 2024
dce94c8
Add the ability to debug turf icons
wixoaGit Jan 1, 2025
3a8c33b
Fix off-by-one in turf icon debugging
wixoaGit Jan 2, 2025
5593112
Update the area overlay when changing a turf's area
wixoaGit Jan 2, 2025
732301b
Mark `ColorMatrix.Equals()` as pure
wixoaGit Jan 3, 2025
4b548c5
Make MutableAppearance disposable, allowing for pooling
wixoaGit Jan 3, 2025
26be28e
Code cleanup
wixoaGit Jan 5, 2025
1e54318
Fix some NREs
wixoaGit Jan 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Content.IntegrationTests/DMProject/Tests/icons.dmi
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
plane = 123
icon_state = "subclass"

/proc/RunTest()
/proc/test_images()
ASSERT(image('icons.dmi', "mob") != null)

var/image/test = new /image/subclass
ASSERT(test.plane == 123)
ASSERT(test.icon_state == "subclass")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
out += dir
ASSERT(out == 14)

/proc/RunTest()
/proc/test_nonlocal_var()
var/mob/m = new
m.dodir()
2 changes: 2 additions & 0 deletions Content.IntegrationTests/DMProject/code.dm
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,7 @@
test_color_matrix()
test_range()
test_verb_duplicate()
test_nonlocal_var()
test_images()
test_filter_init()
world.log << "IntegrationTests successful, /world/New() exiting..."
2 changes: 2 additions & 0 deletions Content.IntegrationTests/DMProject/environment.dme
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "Tests/color_matrix.dm"
#include "Tests/range.dm"
#include "Tests/verb_duplicate.dm"
#include "Tests/nonlocal_var.dm"
#include "Tests/image.dm"
#include "Tests/filter_initial.dm"
#include "map.dmm"
#include "interface.dmf"
2 changes: 0 additions & 2 deletions Content.Tests/DMProject/Tests/Image/Image.dm

This file was deleted.

7 changes: 4 additions & 3 deletions Content.Tests/DMProject/Tests/Savefile/ExportText.dm
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/obj/savetest
var/obj/savetest/recurse = null
/datum/savetest
var/name
var/datum/savetest/recurse = null

/proc/RunTest()
var/obj/savetest/O = new() //create a test object
var/datum/savetest/O = new() //create a test object
O.name = "test"
//O.recurse = O //TODO

Expand Down
4 changes: 2 additions & 2 deletions Content.Tests/DummyDreamMapManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ public void InitializeAtoms(List<DreamMapJson>? maps) { }

public void SetTurf(DreamObjectTurf turf, DreamObjectDefinition type, DreamProcArguments creationArguments) { }

public void SetTurfAppearance(DreamObjectTurf turf, IconAppearance appearance) { }
public void SetTurfAppearance(DreamObjectTurf turf, MutableAppearance appearance) { }

public void SetAreaAppearance(DreamObjectArea area, IconAppearance appearance) { }
public void SetAreaAppearance(DreamObjectArea area, MutableAppearance appearance) { }

public void SetArea(DreamObjectTurf turf, DreamObjectArea area) { }

Expand Down
2 changes: 1 addition & 1 deletion DMCompiler/DMStandard/Types/Image.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/image
parent_type = /datum

//note these values also need to be set in IconAppearance.cs
//note these values also need to be set in MutableAppearance.cs
var/alpha = 255
var/appearance
var/appearance_flags = 0
Expand Down
10 changes: 10 additions & 0 deletions OpenDreamClient/EntryPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ public override void PostInit() {
IoCManager.Resolve<IDreamSoundEngine>().Initialize();

_netManager.RegisterNetMessage<MsgAllAppearances>(RxAllAppearances);
_netManager.RegisterNetMessage<MsgNewAppearance>(RxNewAppearance);

if (_configurationManager.GetCVar(CVars.DisplayCompat))
_dreamInterface.OpenAlert(
Expand Down Expand Up @@ -112,6 +113,15 @@ private void RxAllAppearances(MsgAllAppearances message) {
clientAppearanceSystem.SetAllAppearances(message.AllAppearances);
}

private void RxNewAppearance(MsgNewAppearance message) {
if (!_entitySystemManager.TryGetEntitySystem<ClientAppearanceSystem>(out var clientAppearanceSystem)) {
Logger.GetSawmill("opendream").Error("Received MsgNewAppearance before initializing entity systems");
return;
}

clientAppearanceSystem.OnNewAppearance(message);
}

// As of RobustToolbox v0.90.0.0 there's a TileEdgeOverlay that breaks our rendering
// because we don't have an ITileDefinition for each tile.
// This removes that overlay immediately after MapSystem adds it.
Expand Down
2 changes: 1 addition & 1 deletion OpenDreamClient/Input/ContextMenu/ContextMenuPopup.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public ContextMenuPopup() {
_metadataQuery = _entityManager.GetEntityQuery<MetaDataComponent>();
}

public void RepopulateEntities(ClientObjectReference[] entities, int? turfId) {
public void RepopulateEntities(ClientObjectReference[] entities, uint? turfId) {
ContextMenu.RemoveAllChildren();

if (_transformSystem == null)
Expand Down
57 changes: 43 additions & 14 deletions OpenDreamClient/Input/ContextMenu/VerbMenuPopup.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
using OpenDreamClient.Rendering;
using OpenDreamShared.Dream;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Client.ViewVariables;
using Robust.Shared.Map;

namespace OpenDreamClient.Input.ContextMenu;

Expand Down Expand Up @@ -40,26 +42,53 @@ public VerbMenuPopup(ClientVerbSystem? verbSystem, sbyte seeInvisible, ClientObj
}

#if TOOLS
// If we're compiling with TOOLS and this is an entity, provide the option to use RT's VV or our icon debugger
// We add some additional debugging tools in TOOLS mode
var iconDebugButton = AddButton("Debug Icon");

iconDebugButton.OnPressed += _ => {
DreamIcon icon;
switch (_target.Type) {
case ClientObjectReference.RefType.Entity:
var entityManager = IoCManager.Resolve<IEntityManager>();
var entityId = entityManager.GetEntity(_target.Entity);
if (!entityManager.TryGetComponent(entityId, out DMISpriteComponent? spriteComponent)) {
Logger.GetSawmill("opendream")
.Error($"Failed to get sprite component for {entityId} when trying to debug its icon");
return;
}

icon = spriteComponent.Icon;
break;
case ClientObjectReference.RefType.Turf:
var mapManager = IoCManager.Resolve<IMapManager>();
var mapId = new MapId(_target.TurfZ);
var mapPos = new Vector2(_target.TurfX, _target.TurfY);
if (!mapManager.TryFindGridAt(mapId, mapPos, out var gridUid, out var grid)) {
Logger.GetSawmill("opendream")
.Error($"Failed to get icon for {_target} when trying to debug its icon");
return;
}

var entitySystemManager = IoCManager.Resolve<IEntitySystemManager>();
var mapSystem = entitySystemManager.GetEntitySystem<MapSystem>();
var appearanceSystem = entitySystemManager.GetEntitySystem<ClientAppearanceSystem>();
var tileRef = mapSystem.GetTileRef(gridUid, grid, (Vector2i)mapPos);
icon = appearanceSystem.GetTurfIcon((uint)tileRef.Tile.TypeId);
break;
default:
return;
}

new IconDebugWindow(icon).Show();
};

// If this is an entity, provide the option to use RT's VV
if (_target.Type == ClientObjectReference.RefType.Entity) {
var viewVariablesButton = AddButton("RT ViewVariables");
var iconDebugButton = AddButton("Debug Icon");

viewVariablesButton.OnPressed += _ => {
IoCManager.Resolve<IClientViewVariablesManager>().OpenVV(_target.Entity);
};

iconDebugButton.OnPressed += _ => {
var entityManager = IoCManager.Resolve<IEntityManager>();
var entityId = entityManager.GetEntity(_target.Entity);
if (!entityManager.TryGetComponent(entityId, out DMISpriteComponent? spriteComponent)) {
Logger.GetSawmill("opendream")
.Error($"Failed to get sprite component for {entityId} when trying to debug its icon");
return;
}

new IconDebugWindow(spriteComponent.Icon).Show();
};
}
#endif
}
Expand Down
4 changes: 2 additions & 2 deletions OpenDreamClient/Input/MouseInputSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,14 @@ public void HandleStatClick(string atomRef, bool isRight, bool isMiddle) {
}
}

private (ClientObjectReference Atom, Vector2i IconPosition)? GetTurfUnderMouse(MapCoordinates mapCoords, out int? turfId) {
private (ClientObjectReference Atom, Vector2i IconPosition)? GetTurfUnderMouse(MapCoordinates mapCoords, out uint? turfId) {
// Grid coordinates are half a meter off from entity coordinates
mapCoords = new MapCoordinates(mapCoords.Position + new Vector2(0.5f), mapCoords.MapId);

if (_mapManager.TryFindGridAt(mapCoords, out var gridEntity, out var grid)) {
Vector2i position = _mapSystem.CoordinatesToTile(gridEntity, grid, _mapSystem.MapToGrid(gridEntity, mapCoords));
_mapSystem.TryGetTile(grid, position, out Tile tile);
turfId = tile.TypeId;
turfId = (uint)tile.TypeId;
Vector2i turfIconPosition = (Vector2i) ((mapCoords.Position - position) * EyeManager.PixelsPerMeter);
MapCoordinates worldPosition = _mapSystem.GridTileToWorld(gridEntity, grid, position);

Expand Down
38 changes: 19 additions & 19 deletions OpenDreamClient/Interface/DebugWindows/IconDebugWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,25 +44,25 @@ private void Update() {

// Would be nice if we could use ViewVariables instead, but I couldn't find a nice way to do that
// Would be especially nice if we could use VV to make these editable
AddPropertyIfNotDefault("Name", appearance.Name, IconAppearance.Default.Name);
AddPropertyIfNotDefault("Icon State", appearance.IconState, IconAppearance.Default.IconState);
AddPropertyIfNotDefault("Direction", appearance.Direction, IconAppearance.Default.Direction);
AddPropertyIfNotDefault("Inherits Direction", appearance.InheritsDirection, IconAppearance.Default.InheritsDirection);
AddPropertyIfNotDefault("Pixel Offset X/Y", appearance.PixelOffset, IconAppearance.Default.PixelOffset);
AddPropertyIfNotDefault("Pixel Offset W/Z", appearance.PixelOffset2, IconAppearance.Default.PixelOffset2);
AddPropertyIfNotDefault("Color", appearance.Color, IconAppearance.Default.Color);
AddPropertyIfNotDefault("Alpha", appearance.Alpha, IconAppearance.Default.Alpha);
AddPropertyIfNotDefault("Glide Size", appearance.GlideSize, IconAppearance.Default.GlideSize);
AddPropertyIfNotDefault("Layer", appearance.Layer, IconAppearance.Default.Layer);
AddPropertyIfNotDefault("Plane", appearance.Plane, IconAppearance.Default.Plane);
AddPropertyIfNotDefault("Blend Mode", appearance.BlendMode, IconAppearance.Default.BlendMode);
AddPropertyIfNotDefault("Appearance Flags", appearance.AppearanceFlags, IconAppearance.Default.AppearanceFlags);
AddPropertyIfNotDefault("Invisibility", appearance.Invisibility, IconAppearance.Default.Invisibility);
AddPropertyIfNotDefault("Opacity", appearance.Opacity, IconAppearance.Default.Opacity);
AddPropertyIfNotDefault("Override", appearance.Override, IconAppearance.Default.Override);
AddPropertyIfNotDefault("Render Source", appearance.RenderSource, IconAppearance.Default.RenderSource);
AddPropertyIfNotDefault("Render Target", appearance.RenderTarget, IconAppearance.Default.RenderTarget);
AddPropertyIfNotDefault("Mouse Opacity", appearance.MouseOpacity, IconAppearance.Default.MouseOpacity);
AddPropertyIfNotDefault("Name", appearance.Name, MutableAppearance.Default.Name);
AddPropertyIfNotDefault("Icon State", appearance.IconState, MutableAppearance.Default.IconState);
AddPropertyIfNotDefault("Direction", appearance.Direction, MutableAppearance.Default.Direction);
AddPropertyIfNotDefault("Inherits Direction", appearance.InheritsDirection, MutableAppearance.Default.InheritsDirection);
AddPropertyIfNotDefault("Pixel Offset X/Y", appearance.PixelOffset, MutableAppearance.Default.PixelOffset);
AddPropertyIfNotDefault("Pixel Offset W/Z", appearance.PixelOffset2, MutableAppearance.Default.PixelOffset2);
AddPropertyIfNotDefault("Color", appearance.Color, MutableAppearance.Default.Color);
AddPropertyIfNotDefault("Alpha", appearance.Alpha, MutableAppearance.Default.Alpha);
AddPropertyIfNotDefault("Glide Size", appearance.GlideSize, MutableAppearance.Default.GlideSize);
AddPropertyIfNotDefault("Layer", appearance.Layer, MutableAppearance.Default.Layer);
AddPropertyIfNotDefault("Plane", appearance.Plane, MutableAppearance.Default.Plane);
AddPropertyIfNotDefault("Blend Mode", appearance.BlendMode, MutableAppearance.Default.BlendMode);
AddPropertyIfNotDefault("Appearance Flags", appearance.AppearanceFlags, MutableAppearance.Default.AppearanceFlags);
AddPropertyIfNotDefault("Invisibility", appearance.Invisibility, MutableAppearance.Default.Invisibility);
AddPropertyIfNotDefault("Opacity", appearance.Opacity, MutableAppearance.Default.Opacity);
AddPropertyIfNotDefault("Override", appearance.Override, MutableAppearance.Default.Override);
AddPropertyIfNotDefault("Render Source", appearance.RenderSource, MutableAppearance.Default.RenderSource);
AddPropertyIfNotDefault("Render Target", appearance.RenderTarget, MutableAppearance.Default.RenderTarget);
AddPropertyIfNotDefault("Mouse Opacity", appearance.MouseOpacity, MutableAppearance.Default.MouseOpacity);

foreach (var overlay in _icon.Overlays) {
AddDreamIconButton(OverlaysGrid, overlay);
Expand Down
62 changes: 41 additions & 21 deletions OpenDreamClient/Rendering/ClientAppearanceSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
using OpenDreamClient.Resources;
using OpenDreamClient.Resources.ResourceTypes;
using Robust.Shared.Timing;
using OpenDreamShared.Network.Messages;

namespace OpenDreamClient.Rendering;

internal sealed class ClientAppearanceSystem : SharedAppearanceSystem {
private Dictionary<int, IconAppearance> _appearances = new();
private readonly Dictionary<int, List<Action<IconAppearance>>> _appearanceLoadCallbacks = new();
private readonly Dictionary<int, DreamIcon> _turfIcons = new();
private Dictionary<uint, ImmutableAppearance> _appearances = new();
private readonly Dictionary<uint, List<Action<ImmutableAppearance>>> _appearanceLoadCallbacks = new();
private readonly Dictionary<uint, DreamIcon> _turfIcons = new();
private readonly Dictionary<DreamFilter, ShaderInstance> _filterShaders = new();

[Dependency] private readonly IEntityManager _entityManager = default!;
Expand All @@ -23,7 +24,7 @@ internal sealed class ClientAppearanceSystem : SharedAppearanceSystem {
[Dependency] private readonly DMISpriteSystem _spriteSystem = default!;

public override void Initialize() {
SubscribeNetworkEvent<NewAppearanceEvent>(OnNewAppearance);
SubscribeNetworkEvent<RemoveAppearanceEvent>(e => _appearances.Remove(e.AppearanceId));
SubscribeNetworkEvent<AnimationEvent>(OnAnimation);
SubscribeLocalEvent<DMISpriteComponent, WorldAABBEvent>(OnWorldAABB);
}
Expand All @@ -34,19 +35,21 @@ public override void Shutdown() {
_turfIcons.Clear();
}

public void SetAllAppearances(Dictionary<int, IconAppearance> appearances) {
public void SetAllAppearances(Dictionary<uint, ImmutableAppearance> appearances) {
_appearances = appearances;

foreach (KeyValuePair<int, IconAppearance> pair in _appearances) {
//need to do this because all overlays can't be resolved until the whole appearance table is populated
foreach(KeyValuePair<uint, ImmutableAppearance> pair in _appearances) {
pair.Value.ResolveOverlays(this);
if (_appearanceLoadCallbacks.TryGetValue(pair.Key, out var callbacks)) {
foreach (var callback in callbacks) callback(pair.Value);
}
}
}

public void LoadAppearance(int appearanceId, Action<IconAppearance> loadCallback) {
public void LoadAppearance(uint appearanceId, Action<ImmutableAppearance> loadCallback) {
if (_appearances.TryGetValue(appearanceId, out var appearance)) {
loadCallback(appearance);
return;
}

if (!_appearanceLoadCallbacks.ContainsKey(appearanceId)) {
Expand All @@ -56,8 +59,8 @@ public void LoadAppearance(int appearanceId, Action<IconAppearance> loadCallback
_appearanceLoadCallbacks[appearanceId].Add(loadCallback);
}

public DreamIcon GetTurfIcon(int turfId) {
int appearanceId = turfId - 1;
public DreamIcon GetTurfIcon(uint turfId) {
uint appearanceId = turfId;

if (!_turfIcons.TryGetValue(appearanceId, out var icon)) {
icon = new DreamIcon(_spriteSystem.RenderTargetPool, _gameTiming, _clyde, this, appearanceId);
Expand All @@ -67,22 +70,31 @@ public DreamIcon GetTurfIcon(int turfId) {
return icon;
}

private void OnNewAppearance(NewAppearanceEvent e) {
_appearances[e.AppearanceId] = e.Appearance;
public void OnNewAppearance(MsgNewAppearance e) {
uint appearanceId = e.Appearance.MustGetId();
_appearances[appearanceId] = e.Appearance;
_appearances[appearanceId].ResolveOverlays(this);

if (_appearanceLoadCallbacks.TryGetValue(e.AppearanceId, out var callbacks)) {
foreach (var callback in callbacks) callback(e.Appearance);
if (_appearanceLoadCallbacks.TryGetValue(appearanceId, out var callbacks)) {
foreach (var callback in callbacks) callback(_appearances[appearanceId]);
}
}

private void OnAnimation(AnimationEvent e) {
EntityUid ent = _entityManager.GetEntity(e.Entity);
if (!_entityManager.TryGetComponent<DMISpriteComponent>(ent, out var sprite))
return;

LoadAppearance(e.TargetAppearanceId, targetAppearance => {
sprite.Icon.StartAppearanceAnimation(targetAppearance, e.Duration, e.Easing, e.Loop, e.Flags, e.Delay, e.ChainAnim);
});
if(e.Entity == NetEntity.Invalid && e.TurfId is not null) { //it's a turf or area
if(_turfIcons.TryGetValue(e.TurfId.Value-1, out var turfIcon))
LoadAppearance(e.TargetAppearanceId, targetAppearance => {
turfIcon.StartAppearanceAnimation(targetAppearance, e.Duration, e.Easing, e.Loop, e.Flags, e.Delay, e.ChainAnim);
});
} else { //image or movable
EntityUid ent = _entityManager.GetEntity(e.Entity);
if (!_entityManager.TryGetComponent<DMISpriteComponent>(ent, out var sprite))
return;

LoadAppearance(e.TargetAppearanceId, targetAppearance => {
sprite.Icon.StartAppearanceAnimation(targetAppearance, e.Duration, e.Easing, e.Loop, e.Flags, e.Delay, e.ChainAnim);
});
}
}

private void OnWorldAABB(EntityUid uid, DMISpriteComponent comp, ref WorldAABBEvent e) {
Expand Down Expand Up @@ -197,4 +209,12 @@ public ShaderInstance GetFilterShader(DreamFilter filter, Dictionary<string, IRe
_filterShaders[filter] = instance;
return instance;
}

public override ImmutableAppearance MustGetAppearanceById(uint appearanceId) {
return _appearances[appearanceId];
}

public override void RemoveAppearance(ImmutableAppearance appearance) {
throw new NotImplementedException();
}
}
Loading
Loading