Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
PrecipitationShaftParticleSystem.cs
浏览该文件的文档.
1using Engine;
3
4namespace Game {
6 public class Particle {
7 public bool IsActive;
8
9 public bool GenerateSplash;
10
11 public byte TextureSlot;
12
14
16
18
20
22
23 public float Speed;
24
25 public float YLimit;
26 }
27
28 public const float m_viewHeight = 10f;
29
30 public const int m_particlesCount = 4;
31
33
35
37
39
41
43
44 public bool m_isVisible;
45
46 public bool m_isEmpty;
47
48 public float? m_lastViewY;
49
50 public float m_toCreate;
51
52 public float m_averageSpeed;
53
55
57
58 public float m_intensity;
59
60 public int m_yLimit;
61
62 public int m_topmostValue;
63
65
66 public double m_lastUpdateTime = -1.7976931348623157E+308;
67
68 public float m_lastSkylightIntensity = -3.40282347E+38f;
69
70 public bool m_needsInitialize;
71
72 public Point2 Point { get; set; }
73
74 public PrecipitationShaftParticleSystem(GameWidget gameWidget, SubsystemWeather subsystemWeather, Random random, Point2 point) {
75 m_gameWidget = gameWidget;
76 m_subsystemWeather = subsystemWeather;
77 m_random = random;
78 Point = point;
79 for (int i = 0; i < m_particles.Length; i++) {
80 m_particles[i] = new Particle();
81 }
82 Initialize();
83 }
84
85 public override bool Simulate(float dt) {
86 if (m_subsystemWeather.SubsystemTime.GameTime - m_lastUpdateTime > 1.0
87 || MathF.Abs(m_lastSkylightIntensity - m_subsystemWeather.SubsystemSky.SkyLightIntensity) > 0.1f) {
88 m_lastUpdateTime = m_subsystemWeather.SubsystemTime.GameTime;
89 m_lastSkylightIntensity = m_subsystemWeather.SubsystemSky.SkyLightIntensity;
90 PrecipitationShaftInfo precipitationShaftInfo = m_subsystemWeather.GetPrecipitationShaftInfo(Point.X, Point.Y);
91 m_intensity = precipitationShaftInfo.Intensity;
92 m_yLimit = precipitationShaftInfo.YLimit;
93 m_topmostValue = m_subsystemWeather.SubsystemTerrain.Terrain.GetCellValue(Point.X, precipitationShaftInfo.YLimit - 1, Point.Y);
94 m_topmostBelowValue = m_subsystemWeather.SubsystemTerrain.Terrain.GetCellValue(Point.X, precipitationShaftInfo.YLimit - 2, Point.Y);
95 if (precipitationShaftInfo.Type != m_precipitationType) {
96 m_needsInitialize = true;
97 }
98 }
99 Camera activeCamera = m_gameWidget.ActiveCamera;
100 if (!m_isEmpty
101 || (m_intensity > 0f && m_yLimit < activeCamera.ViewPosition.Y + 5f)) {
102 Vector2 v = Vector2.Normalize(new Vector2(activeCamera.ViewDirection.X, activeCamera.ViewDirection.Z));
104 new Vector2(Point.X + 0.5f - activeCamera.ViewPosition.X + 0.7f * v.X, Point.Y + 0.5f - activeCamera.ViewPosition.Z + 0.7f * v.Y)
105 );
106 float num = Vector2.Dot(v, v2);
107 m_isVisible = num > 0.5f;
108 if (m_isVisible) {
109 if (m_needsInitialize) {
110 m_needsInitialize = false;
111 Initialize();
112 }
113 float y = activeCamera.ViewPosition.Y;
114 float num2 = y - 5f;
115 float num3 = y + 5f;
116 float num4;
117 float num5;
118 if (m_lastViewY.HasValue) {
119 if (y < m_lastViewY.Value) {
120 num4 = num2;
121 num5 = m_lastViewY.Value - 5f;
122 }
123 else {
124 num4 = m_lastViewY.Value + 5f;
125 num5 = num3;
126 }
127 }
128 else {
129 num4 = num2;
130 num5 = num3;
131 }
132 float num6 = (num5 - num4) / 10f * m_particles.Length * m_intensity;
133 int num7 = (int)num6 + (m_random.Float(0f, 1f) < num6 - (int)num6 ? 1 : 0);
134 m_lastViewY = y;
135 m_toCreate += m_particles.Length * m_intensity / 10f * m_averageSpeed * dt;
136 m_isEmpty = true;
137 float num8 = m_precipitationType == PrecipitationType.Rain ? 0f : 0.03f;
138 for (int i = 0; i < m_particles.Length; i++) {
139 Particle particle = m_particles[i];
140 if (particle.IsActive) {
141 if (particle.YLimit == 0f
142 && particle.Position.Y <= m_yLimit + num8) {
143 RaycastParticle(particle);
144 }
145 bool flag = particle.YLimit != 0f && particle.Position.Y <= particle.YLimit + num8;
146 if (!flag
147 && particle.Position.Y >= num2
148 && particle.Position.Y <= num3) {
149 particle.Position.Y -= particle.Speed * dt;
150 m_isEmpty = false;
151 continue;
152 }
153 particle.IsActive = false;
154 if (particle.GenerateSplash && flag) {
156 && m_random.Bool(0.5f)) {
157 m_subsystemWeather.RainSplashParticleSystem.AddSplash(
159 new Vector3(particle.Position.X, particle.YLimit + num8, particle.Position.Z),
160 m_subsystemWeather.RainColor
161 );
162 }
164 m_subsystemWeather.SnowSplashParticleSystem.AddSplash(
166 new Vector3(particle.Position.X, particle.YLimit + num8, particle.Position.Z),
167 m_size,
168 m_subsystemWeather.SnowColor,
169 particle.TextureSlot
170 );
171 }
172 }
173 }
174 else if (num7 > 0) {
175 particle.Position.X = Point.X + m_random.Float(0f, 1f);
176 particle.Position.Y = m_random.Float(num4, num5);
177 particle.Position.Z = Point.Y + m_random.Float(0f, 1f);
178 particle.IsActive = particle.Position.Y >= m_yLimit;
179 particle.YLimit = 0f;
180 num7--;
181 }
182 else if (m_toCreate >= 1f) {
183 particle.Position.X = Point.X + m_random.Float(0f, 1f);
184 particle.Position.Y = m_random.Float(num3 - m_averageSpeed * dt, num3);
185 particle.Position.Z = Point.Y + m_random.Float(0f, 1f);
186 particle.IsActive = particle.Position.Y >= m_yLimit;
187 particle.YLimit = 0f;
188 m_toCreate -= 1f;
189 }
190 }
191 m_toCreate -= MathF.Floor(m_toCreate);
192 }
193 else {
194 m_needsInitialize = true;
195 }
196 }
197 return false;
198 }
199
200 public override void Draw(Camera camera) {
201 if (!m_isVisible
202 || m_isEmpty
203 || camera.GameWidget != m_gameWidget) {
204 return;
205 }
206 m_batch ??= SubsystemParticles.PrimitivesRenderer.TexturedBatch(
207 m_texture,
208 false,
209 0,
211 null,
214 );
215 float num = camera.ViewPosition.Y + 5f;
216 Vector3 viewDirection = camera.ViewDirection;
217 Vector3 vector = Vector3.Normalize(Vector3.Cross(viewDirection, Vector3.UnitY));
218 Vector3 v = m_precipitationType == PrecipitationType.Rain ? Vector3.UnitY : Vector3.Normalize(Vector3.Cross(viewDirection, vector));
219 Vector3 vector2 = vector * m_size.X;
220 Vector3 vector3 = v * m_size.Y;
222 Vector3 v2 = -vector2 - vector3;
223 Vector3 v3 = vector2 - vector3;
224 Vector3 v4 = vector3;
225 for (int i = 0; i < m_particles.Length; i++) {
226 Particle particle = m_particles[i];
227 if (particle.IsActive) {
228 Vector3 p = particle.Position + v2;
229 Vector3 p2 = particle.Position + v3;
230 Vector3 p3 = particle.Position + v4;
231 Color color = m_subsystemWeather.RainColor * MathUtils.Min(0.6f * (num - particle.Position.Y), 1f);
232 m_batch.QueueTriangle(
233 p,
234 p2,
235 p3,
236 particle.TexCoord1,
237 particle.TexCoord2,
238 particle.TexCoord3,
239 color
240 );
241 }
242 }
243 return;
244 }
245 Vector3 v5 = -vector2 - vector3;
246 Vector3 v6 = vector2 - vector3;
247 Vector3 v7 = vector2 + vector3;
248 Vector3 v8 = -vector2 + vector3;
249 for (int j = 0; j < m_particles.Length; j++) {
250 Particle particle2 = m_particles[j];
251 if (particle2.IsActive) {
252 Vector3 p4 = particle2.Position + v5;
253 Vector3 p5 = particle2.Position + v6;
254 Vector3 p6 = particle2.Position + v7;
255 Vector3 p7 = particle2.Position + v8;
256 Color color2 = m_subsystemWeather.SnowColor * MathUtils.Min(0.6f * (num - particle2.Position.Y), 1f);
257 m_batch.QueueQuad(
258 p4,
259 p5,
260 p6,
261 p7,
262 particle2.TexCoord1,
263 particle2.TexCoord2,
264 particle2.TexCoord3,
265 particle2.TexCoord4,
266 color2
267 );
268 }
269 }
270 }
271
272 public void RaycastParticle(Particle particle) {
273 particle.YLimit = m_yLimit;
274 particle.GenerateSplash = true;
276 if (!block.IsTransparent_(m_topmostValue)) {
277 return;
278 }
279 Ray3 ray = new(new Vector3(particle.Position.X - Point.X, 1f, particle.Position.Z - Point.Y), -Vector3.UnitY);
280 float? num = block.Raycast(ray, m_subsystemWeather.SubsystemTerrain, m_topmostValue, false, out int _, out BoundingBox _);
281 if (num.HasValue) {
282 particle.YLimit -= num.Value;
283 return;
284 }
285 particle.YLimit -= 1f;
288 particle.GenerateSplash = false;
289 }
290 }
291
292 public void Initialize() {
293 m_precipitationType = m_subsystemWeather.GetPrecipitationShaftInfo(Point.X, Point.Y).Type;
294 m_lastViewY = null;
295 m_toCreate = m_random.Float(0f, 0.9f);
296 m_batch = null;
297 m_lastSkylightIntensity = -3.40282347E+38f;
298 switch (m_precipitationType) {
299 case PrecipitationType.Rain: {
300 float num4 = 8f;
301 float num5 = 12f;
302 m_averageSpeed = (num4 + num5) / 2f;
303 m_size = new Vector2(0.02f, 0.15f);
304 m_texture = ContentManager.Get<Texture2D>("Textures/RainParticle");
305 for (int j = 0; j < m_particles.Length; j++) {
306 Particle obj = m_particles[j];
307 obj.IsActive = false;
308 obj.TexCoord1 = new Vector2(0f, 1f);
309 obj.TexCoord2 = new Vector2(1f, 1f);
310 obj.TexCoord3 = new Vector2(0.5f, 0f);
311 obj.Speed = m_random.Float(num4, num5);
312 }
313 break;
314 }
315 case PrecipitationType.Snow: {
316 float num = 0.25f;
317 float num2 = 0.5f;
318 float num3 = 3f;
319 m_averageSpeed = (num2 + num3) / 2f;
320 m_size = new Vector2(0.07f, 0.07f);
321 m_texture = ContentManager.Get<Texture2D>("Textures/SnowParticle");
322 for (int i = 0; i < m_particles.Length; i++) {
323 Particle particle = m_particles[i];
324 particle.IsActive = false;
325 particle.TextureSlot = (byte)m_random.Int(0, 15);
326 Vector2 v = new Vector2(particle.TextureSlot % 4, particle.TextureSlot / 4) * num;
327 particle.TexCoord1 = v + new Vector2(0f, 0f);
328 particle.TexCoord2 = v + new Vector2(num, 0f);
329 particle.TexCoord3 = v + new Vector2(num, num);
330 particle.TexCoord4 = v + new Vector2(0f, num);
331 particle.Speed = m_random.Float(num2, num3);
332 }
333 break;
334 }
335 default: throw new InvalidOperationException("Unknown precipitation type.");
336 }
337 }
338 }
339}
Engine.Vector3 Vector3
static readonly BlendState AlphaBlend
static readonly DepthStencilState DepthRead
static int Min(int x1, int x2)
virtual bool IsTransparent_(int value)
virtual bool IsFaceTransparent(SubsystemTerrain subsystemTerrain, int face, int value)
virtual ? float Raycast(Ray3 ray, SubsystemTerrain subsystemTerrain, int value, bool useInteractionBoxes, out int nearestBoxIndex, out BoundingBox nearestBox)
Vector3 ViewPosition
GameWidget GameWidget
Vector3 ViewDirection
static object Get(Type type, string name)
SubsystemParticles SubsystemParticles
PrecipitationShaftParticleSystem(GameWidget gameWidget, SubsystemWeather subsystemWeather, Random random, Point2 point)
static int ExtractContents(int value)
static float Dot(Vector2 v1, Vector2 v2)
static Vector2 Normalize(Vector2 v)
static Vector3 Cross(Vector3 v1, Vector3 v2)
static Vector3 Normalize(Vector3 v)
static readonly Vector3 UnitY