-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLastSeenParticles.cs
118 lines (98 loc) · 3.98 KB
/
LastSeenParticles.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using Sandbox.Game.Entities;
using Sandbox.Game.World;
using VRage.Game;
using VRage.Game.Entity;
using VRage.Utils;
using VRageMath;
using VRageRender;
using VRageRender.Messages;
namespace Digi.ParticleEditor
{
public class LastSeenParticles : EditorComponentBase
{
public bool ShowLiveNames { get; set; } = false;
public readonly Dictionary<string, int> Recent = new Dictionary<string, int>();
Func<MyParticleEffect, MyParticleEffectState> StateGetter;
StringBuilder SB = new StringBuilder(512);
public LastSeenParticles(Editor editor) : base(editor)
{
AlwaysUpdate = true;
MySession.AfterLoading += SessionLoaded;
try
{
FieldInfo field = typeof(MyParticleEffect).GetField("m_state", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField);
StateGetter = FieldAccess.CreateGetter<MyParticleEffect, MyParticleEffectState>(field);
}
catch(Exception e)
{
Log.Error(e);
}
}
public override void Dispose()
{
MySession.AfterLoading -= SessionLoaded;
}
void SessionLoaded()
{
Recent.Clear();
}
public override void Update()
{
int tick = MySession.Static.GameplayFrameCounter;
Vector3D cameraPos = MySector.MainCamera.Position;
foreach(MyParticleEffect effect in MyParticlesManager.Effects)
{
if(effect.IsEmittingStopped || effect.IsStopped)
continue; // prob not needed but can't hurt
Recent[effect.Data.Name] = tick;
if(ShowLiveNames && StateGetter != null)
{
Vector3D worldPos = effect.WorldMatrix.Translation;
MyParticleEffectState state = StateGetter.Invoke(effect);
uint parentId = state.ParentID;
double distance = 0;
SB.Clear();
SB.Append(effect.Data != null ? effect.GetName() : "(Data=null)").Append('\n');
if(parentId != uint.MaxValue)
{
MyEntity parent = MyEntities.GetEntityFromRenderObjectID(parentId) as MyEntity;
if(parent == null)
{
SB.Append("(RenderID not found=").Append(parentId).Append(")");
}
else
{
worldPos = Vector3D.Transform(worldPos, parent.WorldMatrix);
distance = Vector3D.Distance(cameraPos, worldPos);
}
}
else
{
distance = Vector3D.Distance(cameraPos, worldPos);
}
float textScale = 0.6f;
if(distance > 5)
{
textScale = 0.5f;
if(distance > 1000)
SB.Append(Math.Round(distance / 1000, 2)).Append(" km");
else
SB.Append(Math.Round(distance, 2)).Append(" m");
}
Color color;
if(distance <= 50)
color = Color.Lerp(Color.SkyBlue, Color.Yellow, (float)(distance / 50));
else if(distance <= 100)
color = Color.Lerp(Color.Yellow, Color.OrangeRed, (float)((distance - 50) / 50));
else
color = Color.OrangeRed;
MyRenderProxy.DebugDrawText3D(worldPos, SB.ToString(), color, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER);
}
}
}
}
}