source: OniSplit/Particles/Particle.cs

Last change on this file was 1114, checked in by iritscen, 5 years ago

Adding OniSplit source code (v0.9.99.0). Many thanks to Neo for all his work over the years.

File size: 8.0 KB
Line 
1using System;
2using System.Collections.Generic;
3
4namespace Oni.Particles
5{
6 internal class Particle
7 {
8 #region Private data
9 private ParticleFlags1 flags1;
10 private ParticleFlags2 flags2;
11 private SpriteType spriteType;
12 private DisableDetailLevel disableDetailLevel;
13 private Value lifetime;
14 private Value collisionRadius;
15 private float aiDodgeRadius;
16 private float aiAlertRadius;
17 private string flybySoundName;
18 private Appearance appearance;
19 private Attractor attractor;
20 private List<Variable> variables;
21 private List<Emitter> emitters;
22 private List<Event> events;
23 #endregion
24
25 #region private struct ActionRange
26
27 private struct ActionRange
28 {
29 internal ActionRange(BinaryReader reader)
30 {
31 First = reader.ReadUInt16();
32 Last = reader.ReadUInt16();
33 }
34
35 public bool IsEmpty => First == Last;
36
37 public int First { get; set; }
38 public int Last { get; set; }
39 }
40
41 #endregion
42
43 public Particle()
44 {
45 lifetime = Value.FloatZero;
46 collisionRadius = Value.FloatZero;
47 appearance = new Appearance();
48 attractor = new Attractor();
49 variables = new List<Variable>();
50 emitters = new List<Emitter>();
51 events = new List<Event>();
52 }
53
54 public Particle(BinaryReader reader)
55 : this()
56 {
57 appearance = new Appearance();
58 attractor = new Attractor();
59
60 reader.Skip(8);
61 flags1 = (ParticleFlags1)reader.ReadInt32();
62 flags2 = (ParticleFlags2)reader.ReadInt32();
63 spriteType = (SpriteType)((int)(flags1 & ParticleFlags1.SpriteModeMask) >> 5);
64 disableDetailLevel = (DisableDetailLevel)((int)(flags2 & ParticleFlags2.DisableLevelMask) >> 5);
65 reader.Skip(4);
66
67 int variableCount = reader.ReadUInt16();
68 int actionCount = reader.ReadUInt16();
69 int emitterCount = reader.ReadUInt16();
70 reader.Skip(2);
71
72 variables = new List<Variable>(variableCount);
73 emitters = new List<Emitter>(actionCount);
74 events = new List<Event>(emitterCount);
75
76 ActionRange[] eventActions = new ActionRange[16];
77
78 for (int i = 0; i < 16; i++)
79 eventActions[i] = new ActionRange(reader);
80
81 lifetime = Value.Read(reader);
82 collisionRadius = Value.Read(reader);
83 aiDodgeRadius = reader.ReadSingle();
84 aiAlertRadius = reader.ReadSingle();
85 flybySoundName = reader.ReadString(16);
86 appearance = new Appearance(reader);
87 attractor = new Attractor(reader);
88 reader.Skip(12);
89
90 for (int i = 0; i < variableCount; i++)
91 variables.Add(new Variable(reader));
92
93 EventAction[] actions = new EventAction[actionCount];
94
95 for (int i = 0; i < actionCount; i++)
96 actions[i] = new EventAction(reader);
97
98 try
99 {
100 for (int i = 0; i < emitterCount; i++)
101 emitters.Add(new Emitter(reader));
102 }
103 catch (System.IO.EndOfStreamException)
104 {
105 // ignore corrupted particles that contain an invalid emitter count field
106 }
107
108 for (int i = 0; i < eventActions.Length; i++)
109 {
110 ActionRange range = eventActions[i];
111
112 if (!range.IsEmpty)
113 events.Add(new Event((EventType)i, actions, range.First, range.Last - range.First));
114 }
115 }
116
117 public void Write(BinaryWriter writer)
118 {
119 List<EventAction> actions = new List<EventAction>();
120 ActionRange[] ranges = new ActionRange[16];
121
122 for (int i = 0; i < ranges.Length; i++)
123 {
124 Event e = events.Find(x => (int)x.Type == i);
125
126 ActionRange range = new ActionRange();
127 range.First = actions.Count;
128 range.Last = actions.Count + (e == null ? 0 : e.Actions.Count);
129 ranges[i] = range;
130
131 if (e != null)
132 actions.AddRange(e.Actions);
133 }
134
135 writer.Write((int)flags1 | ((int)spriteType << 5));
136 writer.Write((int)flags2 | ((int)disableDetailLevel << 5));
137 writer.Skip(4);
138 writer.WriteUInt16(variables.Count);
139 writer.WriteUInt16(actions.Count);
140 writer.WriteUInt16(emitters.Count);
141 writer.WriteUInt16(256);
142
143 for (int i = 0; i < ranges.Length; i++)
144 {
145 writer.WriteUInt16(ranges[i].First);
146 writer.WriteUInt16(ranges[i].Last);
147 }
148
149 lifetime.Write(writer);
150 collisionRadius.Write(writer);
151 writer.Write(aiDodgeRadius);
152 writer.Write(aiAlertRadius);
153 writer.Write(flybySoundName, 16);
154 appearance.Write(writer);
155 attractor.Write(writer);
156 writer.Skip(12);
157
158 foreach (Variable variable in variables)
159 variable.Write(writer);
160
161 foreach (EventAction action in actions)
162 action.Write(writer);
163
164 foreach (Emitter emitter in emitters)
165 emitter.Write(writer);
166 }
167
168 public ParticleFlags1 Flags1
169 {
170 get
171 {
172 return (flags1 & ~ParticleFlags1.SpriteModeMask);
173 }
174 set
175 {
176 flags1 = value;
177 }
178 }
179
180 public ParticleFlags2 Flags2
181 {
182 get
183 {
184 return (flags2 & ~ParticleFlags2.DisableLevelMask);
185 }
186 set
187 {
188 flags2 = value;
189 }
190 }
191
192 public SpriteType SpriteType
193 {
194 get
195 {
196 return spriteType;
197 }
198 set
199 {
200 spriteType = value;
201 }
202 }
203
204 public DisableDetailLevel DisableDetailLevel
205 {
206 get
207 {
208 return disableDetailLevel;
209 }
210 set
211 {
212 disableDetailLevel = value;
213 }
214 }
215
216 public string FlyBySoundName
217 {
218 get
219 {
220 return flybySoundName;
221 }
222 set
223 {
224 flybySoundName = value;
225 }
226 }
227
228 public Value Lifetime
229 {
230 get
231 {
232 return lifetime;
233 }
234 set
235 {
236 lifetime = value;
237 }
238 }
239
240 public Value CollisionRadius
241 {
242 get
243 {
244 return collisionRadius;
245 }
246 set
247 {
248 collisionRadius = value;
249 }
250 }
251
252 public float AIDodgeRadius
253 {
254 get
255 {
256 return aiDodgeRadius;
257 }
258 set
259 {
260 aiDodgeRadius = value;
261 }
262 }
263
264 public float AIAlertRadius
265 {
266 get
267 {
268 return aiAlertRadius;
269 }
270 set
271 {
272 aiAlertRadius = value;
273 }
274 }
275
276 public Appearance Appearance => appearance;
277
278 public Attractor Attractor => attractor;
279
280 public List<Variable> Variables => variables;
281
282 public List<Emitter> Emitters => emitters;
283
284 public List<Event> Events => events;
285 }
286}
Note: See TracBrowser for help on using the repository browser.