Skip to content

Commit

Permalink
only one particle
Browse files Browse the repository at this point in the history
  • Loading branch information
amylizzle committed Feb 20, 2025
1 parent 4f2e9a2 commit 58950e8
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 125 deletions.
22 changes: 8 additions & 14 deletions OpenDreamClient/Rendering/DreamViewOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -375,13 +375,10 @@ private void ProcessIconComponents(DreamIcon icon, Vector2 position, EntityUid u
result.Add(maptext);
}

//query entity for particles component
//if it has one, add it to the result list
foreach(var particleNetEntity in icon.Appearance.Particles)
if(_particlesManager.TryGetParticleSystem(_entityManager.GetEntity(particleNetEntity), out var particlesSystem)){
current.Particles ??= new();
current.Particles.Add(particlesSystem);
}
//query entity for particles component - check for parent to make sure this is the top level entity
if(parentIcon is null && _particlesManager.TryGetParticleSystem(uid, out var particlesSystem)){
current.Particles = particlesSystem;
}

//flatten KeepTogetherGroup. Done here so we get implicit recursive iteration down the tree.
if (current.KeepTogetherGroup?.Count > 0) {
Expand Down Expand Up @@ -460,13 +457,10 @@ public void DrawIcon(DrawingHandleWorld handle, Vector2i renderTargetSize, Rende
var pixelPosition = (iconMetaData.Position + positionOffset) * EyeManager.PixelsPerMeter;

if(iconMetaData.Particles is not null) {
foreach(var particleSystem in iconMetaData.Particles){
var renderTarget = _renderTargetPool.Rent(particleSystem.RenderSize);

handle.UseShader(GetBlendAndColorShader(iconMetaData, ignoreColor: true));
particleSystem.Draw(handle, CalculateDrawingMatrix(iconMetaData.TransformToApply, pixelPosition, particleSystem.RenderSize, renderTargetSize));
}
handle.UseShader(GetBlendAndColorShader(iconMetaData, ignoreColor: true));
iconMetaData.Particles.Draw(handle, CalculateDrawingMatrix(iconMetaData.TransformToApply, pixelPosition, iconMetaData.Particles.RenderSize, renderTargetSize));
}

//if frame is null, this doesn't require a draw, so return NOP
if (frame == null)
return;
Expand Down Expand Up @@ -815,7 +809,7 @@ internal sealed class RendererMetaData : IComparable<RendererMetaData> {
public Texture? TextureOverride;
public string? Maptext;
public Vector2i? MaptextSize;
public List<ParticleSystem>? Particles;
public ParticleSystem? Particles;

public bool IsPlaneMaster => (AppearanceFlags & AppearanceFlags.PlaneMaster) != 0;
public bool HasRenderSource => !string.IsNullOrEmpty(RenderSource);
Expand Down
87 changes: 0 additions & 87 deletions OpenDreamRuntime/Objects/Types/DreamList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -858,93 +858,6 @@ public override int GetLength() {
}
}

// atom.particles list
// Operates on an atom's appearance
public sealed class DreamParticlesList : DreamList {
[Dependency] private readonly AtomManager _atomManager = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
private readonly PvsOverrideSystem? _pvsOverrideSystem;

private readonly List<DreamObjectParticles> _particles = new();
private readonly DreamObject _atom;

public DreamParticlesList(DreamObjectDefinition listDef, PvsOverrideSystem? pvsOverrideSystem, DreamObject atom) : base(listDef, 0) {
IoCManager.InjectDependencies(this);

_pvsOverrideSystem = pvsOverrideSystem;
_atom = atom;
}

public override List<DreamValue> GetValues() {
var values = new List<DreamValue>(_particles.Count);

foreach (var particlesObject in _particles) {
values.Add(new(particlesObject));
}

return values;
}

public override void Cut(int start = 1, int end = 0) {
int count = _particles.Count + 1;
if (end == 0 || end > count) end = count;

_particles.RemoveRange(start - 1, end - start);
_atomManager.UpdateAppearance(_atom, appearance => {
appearance.Particles.RemoveRange(start - 1, end - start);
});
}

public override DreamValue GetValue(DreamValue key) {
if (!key.TryGetValueAsInteger(out var particlesIndex) || particlesIndex < 1)
throw new Exception($"Invalid index into particles list: {key}");
if (particlesIndex > _particles.Count)
throw new Exception($"Atom only has {_particles.Count} particles element(s), cannot index {particlesIndex}");

return new DreamValue(_particles[particlesIndex - 1]);
}

public override void SetValue(DreamValue key, DreamValue value, bool allowGrowth = false) {
throw new Exception("Cannot write to an index of a particles list");
}

public override void AddValue(DreamValue value) {
EntityUid entity;
if (value.TryGetValueAsDreamObject<DreamObjectParticles>(out var particles)) {
if (_particles.Contains(particles))
return; // particles cannot contain duplicates
_particles.Add(particles);
entity = particles.Entity;
} else if (value == DreamValue.Null) {
return; // particles cannot contain nulls
} else {
throw new Exception($"Cannot add {value} to a particles list");
}

// TODO: Only override the entity's visibility if its parent atom is visible
if (entity != EntityUid.Invalid)
_pvsOverrideSystem?.AddGlobalOverride(entity);

_atomManager.UpdateAppearance(_atom, appearance => {
// Add even an invalid UID to keep this and _visContents in sync
appearance.Particles.Add(_entityManager.GetNetEntity(entity));
});
}

public override void RemoveValue(DreamValue value) {
if (!value.TryGetValueAsDreamObject<DreamObjectParticles>(out var particles))
return;

_particles.Remove(particles);
_atomManager.UpdateAppearance(_atom, appearance => {
appearance.Particles.Remove(_entityManager.GetNetEntity(particles.Entity));
});
}

public override int GetLength() {
return _particles.Count;
}
}


// atom.filters list
Expand Down
21 changes: 0 additions & 21 deletions OpenDreamRuntime/Objects/Types/DreamObjectAtom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,12 @@ public class DreamObjectAtom : DreamObject {
public readonly DreamOverlaysList Overlays;
public readonly DreamOverlaysList Underlays;
public readonly DreamVisContentsList VisContents;
public readonly DreamParticlesList Particles;
public readonly DreamFilterList Filters;
public DreamList? VisLocs; // TODO: Implement

public DreamObjectAtom(DreamObjectDefinition objectDefinition) : base(objectDefinition) {
Overlays = new(ObjectTree.List.ObjectDefinition, this, AppearanceSystem, false);
Underlays = new(ObjectTree.List.ObjectDefinition, this, AppearanceSystem, true);
VisContents = new(ObjectTree.List.ObjectDefinition, PvsOverrideSystem, this);
Particles = new(ObjectTree.List.ObjectDefinition, PvsOverrideSystem, this);
Filters = new(ObjectTree.List.ObjectDefinition, this);

AtomManager.AddAtom(this);
Expand Down Expand Up @@ -75,10 +72,6 @@ protected override bool TryGetVar(string varName, out DreamValue value) {
case "vis_contents":
value = new(VisContents);
return true;
case "particles":
value = new(Particles);
return true;

default:
if (AtomManager.IsValidAppearanceVar(varName)) {
var appearance = AtomManager.MustGetAppearance(this);
Expand Down Expand Up @@ -151,20 +144,6 @@ protected override void SetVar(string varName, DreamValue value) {

break;
}
case "particles": {
Particles.Cut();

if (value.TryGetValueAsDreamList(out var valueList)) {
// TODO: This should postpone UpdateAppearance until after everything is added
foreach (DreamValue particlesValue in valueList.GetValues()) {
Particles.AddValue(particlesValue);
}
} else if (!value.IsNull) {
Particles.AddValue(value);
}

break;
}
case "filters": {
Filters.Cut();

Expand Down
21 changes: 21 additions & 0 deletions OpenDreamRuntime/Objects/Types/DreamObjectMovable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class DreamObjectMovable : DreamObjectAtom {
private readonly TransformComponent _transformComponent;
private readonly MovableContentsList _contents;
private string? _screenLoc;
private DreamObjectParticles? _particles;

private string? ScreenLoc {
get => _screenLoc;
Expand Down Expand Up @@ -94,6 +95,9 @@ protected override bool TryGetVar(string varName, out DreamValue value) {

value = new DreamValue(locs);
return true;
case "particles":
value = new(_particles);
return true;
default:
return base.TryGetVar(varName, out value);
}
Expand Down Expand Up @@ -138,6 +142,23 @@ protected override void SetVar(string varName, DreamValue value) {

ScreenLoc = screenLoc;
break;
case "particles":
if (value.TryGetValueAsDreamObject<DreamObjectParticles>(out var particles)) {
if(particles == _particles){
ParticlesSystem!.MarkDirty((Entity, _particles.ParticlesComponent));
return;
}
if (_particles != null)
EntityManager.RemoveComponent(Entity, _particles.ParticlesComponent);
_particles = particles;
EntityManager.AddComponent(Entity, _particles.ParticlesComponent);
ParticlesSystem!.MarkDirty((Entity, _particles.ParticlesComponent));
} else {
_particles = null;
if (_particles != null)
EntityManager.RemoveComponent(Entity, _particles.ParticlesComponent);
}
break;
default:
base.SetVar(varName, value);
break;
Expand Down
4 changes: 1 addition & 3 deletions OpenDreamRuntime/Objects/Types/DreamObjectParticles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ public sealed class DreamObjectParticles : DreamObject {
private List<string> _iconStates = new();

public DreamObjectParticles(DreamObjectDefinition objectDefinition) : base(objectDefinition) {
Entity = EntityManager.SpawnEntity(null, new MapCoordinates(0, 0, MapId.Nullspace)); //spawning an entity in nullspace means it never actually gets sent to any clients until it's put in the particles list on an atom, when PVS override happens
ParticlesComponent = EntityManager.AddComponent<DreamParticlesComponent>(Entity);
ParticlesComponent = new DreamParticlesComponent();
//populate component with settings from type
foreach(KeyValuePair<string,DreamValue> kv in objectDefinition.Variables){
if(!(kv.Key == "parent_type" || kv.Key == "type" || kv.Key == "vars"))
Expand Down Expand Up @@ -279,7 +278,6 @@ protected override void SetVar(string varName, DreamValue value) {
}
break;
}
ParticlesSystem!.MarkDirty((Entity, ParticlesComponent));
base.SetVar(varName, value); //all calls should set the internal vars, so GetVar() can just be default also
}

Expand Down

0 comments on commit 58950e8

Please sign in to comment.