Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
SubsystemWeather.cs
浏览该文件的文档.
1using Engine;
2using Engine.Audio;
5
6namespace Game {
9
11
13
15
17
18 public Random m_random = new();
19
20 public Dictionary<GameWidget, Dictionary<Point2, PrecipitationShaftParticleSystem>> m_activeShafts = [];
21
22 public List<PrecipitationShaftParticleSystem> m_toRemove = [];
23
24 public Dictionary<GameWidget, Vector2?> m_lastShaftsUpdatePositions = [];
25
27
29
31
33
35
36 public double m_fogStartTime;
37
38 public double m_fogEndTime;
39
40 public float m_fogRampTime;
41
42 public const int m_rainSoundRadius = 7;
43
44 public float m_rainVolumeFactor;
45
47
48 public int[] m_shuffledOrder;
49
50 public static int[] m_drawOrders = [50];
51
53
54 public SubsystemSky SubsystemSky { get; set; }
55
56 public SubsystemTime SubsystemTime { get; set; }
57
59
61
62 public virtual Color RainColor { get; set; }
63
64 public virtual Color SnowColor { get; set; }
65
66 public virtual float PrecipitationIntensity { get; set; }
67
68 public virtual int FogSeed { get; set; }
69
70 public virtual float FogProgress { get; set; }
71
72 public virtual float FogIntensity { get; set; }
73
74 public virtual bool IsPrecipitationStarted {
75 get {
76 if (m_subsystemGameInfo.TotalElapsedGameTime >= m_precipitationStartTime) {
77 return m_subsystemGameInfo.TotalElapsedGameTime < m_precipitationEndTime - m_precipitationRampTime;
78 }
79 return false;
80 }
81 }
82
83 public virtual bool IsFogStarted {
84 get {
85 if (m_subsystemGameInfo.TotalElapsedGameTime >= m_fogStartTime) {
86 return m_subsystemGameInfo.TotalElapsedGameTime < m_fogEndTime - m_fogRampTime;
87 }
88 return false;
89 }
90 }
91
92 public int[] DrawOrders => m_drawOrders;
93
95
96 public static Func<int, int> GetTemperatureAdjustmentAtHeight =
97 y => (int)MathF.Round(y > 64 ? -0.0008f * MathUtils.Sqr(y - 64) : 0.1f * (64 - y));
98
99 public static Func<int, int, bool> IsPlaceFrozen = (temperature, y) => temperature + GetTemperatureAdjustmentAtHeight(y) <= 0;
100 public static Func<int, int, bool> ShaftHasSnowOnIce = (x, z) => MathUtils.Hash((uint)((x & 0xFFFF) | (z << 16))) > 429496729;
101
103 int shaftValue = SubsystemTerrain.Terrain.GetShaftValue(x, z);
104 int seasonalTemperature = SubsystemTerrain.Terrain.GetSeasonalTemperature(shaftValue);
105 int num = Terrain.ExtractTopHeight(shaftValue);
107 if (IsPlaceFrozen(seasonalTemperature, num)) {
108 result = default;
109 result.Intensity = PrecipitationIntensity;
110 result.Type = PrecipitationType.Snow;
111 result.YLimit = num + 1;
112 return result;
113 }
114 int seasonalHumidity = SubsystemTerrain.Terrain.GetSeasonalHumidity(shaftValue);
115 if (seasonalTemperature <= 8
116 || seasonalHumidity >= 8) {
117 result = default;
118 result.Intensity = PrecipitationIntensity;
119 result.Type = PrecipitationType.Rain;
120 result.YLimit = num + 1;
121 return result;
122 }
123 result = default;
124 result.Intensity = 0f;
125 result.Type = PrecipitationType.Rain;
126 result.YLimit = num + 1;
127 return result;
128 }
129
130 public virtual void ManualLightingStrike(Vector3 position, Vector3 direction) {
131 int num = Terrain.ToCell(position.X + direction.X * 32f);
132 int num2 = Terrain.ToCell(position.Z + direction.Z * 32f);
133 Vector3? vector = null;
134 for (int i = 0; i < 300; i++) {
135 int num3 = m_random.Int(-8, 8);
136 int num4 = m_random.Int(-8, 8);
137 int num5 = num + num3;
138 int num6 = num2 + num4;
139 int num7 = SubsystemTerrain.Terrain.CalculateTopmostCellHeight(num5, num6);
140 if (!vector.HasValue
141 || num7 > vector.Value.Y) {
142 vector = new Vector3(num5, num7, num6);
143 }
144 }
145 if (vector.HasValue) {
146 SubsystemSky.MakeLightningStrike(vector.Value, true);
147 }
148 }
149
150 public virtual void ManualPrecipitationStart() {
151 m_precipitationStartTime = m_subsystemGameInfo.TotalElapsedGameTime;
152 m_precipitationEndTime = double.PositiveInfinity;
154 }
155
156 public virtual void ManualPrecipitationEnd() {
158 m_precipitationEndTime = m_subsystemGameInfo.TotalElapsedGameTime + m_precipitationRampTime;
159 }
160
161 public virtual void ManualFogStart() {
162 m_fogStartTime = m_subsystemGameInfo.TotalElapsedGameTime;
163 m_fogEndTime = double.PositiveInfinity;
164 m_fogRampTime = 3f;
165 }
166
167 public virtual void ManualFogEnd() {
168 m_fogRampTime = 3f;
169 m_fogEndTime = m_subsystemGameInfo.TotalElapsedGameTime + m_fogRampTime;
170 }
171
172 public virtual void Draw(Camera camera, int drawOrder) {
173 int num = SettingsManager.VisibilityRange > 128 ? 9 :
175 int num2 = num * num;
176 Dictionary<Point2, PrecipitationShaftParticleSystem> activeShafts = GetActiveShafts(camera.GameWidget);
177 byte b = (byte)(255f * MathUtils.Lerp(0.15f, 1f, SubsystemSky.SkyLightIntensity));
178 byte b2 = (byte)(255f * MathUtils.Lerp(0.15f, 1f, SubsystemSky.SkyLightIntensity));
179 Color rainColor = new(b, b, b);
180 Color snowColor = new(b2, b2, b2);
182 "SetRainAndSnowColor",
183 modloader => {
184 modloader.SetRainAndSnowColor(ref rainColor, ref snowColor);
185 return false;
186 }
187 );
188 RainColor = rainColor;
189 SnowColor = snowColor;
190 Vector2 vector = new(camera.ViewPosition.X, camera.ViewPosition.Z);
191 Point2 point = Terrain.ToCell(vector);
192 m_lastShaftsUpdatePositions.TryGetValue(camera.GameWidget, out Vector2? value);
193 if (value.HasValue
194 && !(Vector2.DistanceSquared(value.Value, vector) > 1f)) {
195 return;
196 }
198 m_toRemove.Clear();
199 foreach (PrecipitationShaftParticleSystem value2 in activeShafts.Values) {
200 if (MathUtils.Sqr(value2.Point.X + 0.5f - vector.X) + MathUtils.Sqr(value2.Point.Y + 0.5f - vector.Y) > num2 + 1f) {
201 m_toRemove.Add(value2);
202 }
203 }
205 if (m_subsystemParticles.ContainsParticleSystem(item)) {
206 m_subsystemParticles.RemoveParticleSystem(item);
207 }
208 activeShafts.Remove(item.Point);
209 }
210 for (int i = point.X - num; i <= point.X + num; i++) {
211 for (int j = point.Y - num; j <= point.Y + num; j++) {
212 if (MathUtils.Sqr(i + 0.5f - vector.X) + MathUtils.Sqr(j + 0.5f - vector.Y) <= num2) {
213 Point2 point2 = new(i, j);
214 if (!activeShafts.ContainsKey(point2)) {
215 PrecipitationShaftParticleSystem precipitationShaftParticleSystem = new(camera.GameWidget, this, m_random, point2);
216 m_subsystemParticles.AddParticleSystem(precipitationShaftParticleSystem);
217 activeShafts.Add(point2, precipitationShaftParticleSystem);
218 }
219 }
220 }
221 }
222 }
223
224 public virtual void Update(float dt) {
226 UpdateLightning(dt);
227 UpdateFog(dt);
228 }
229
230 public override void Load(ValuesDictionary valuesDictionary) {
231 m_subsystemGameInfo = Project.FindSubsystem<SubsystemGameInfo>(true);
232 SubsystemTerrain = Project.FindSubsystem<SubsystemTerrain>(true);
234 SubsystemSky = Project.FindSubsystem<SubsystemSky>(true);
235 m_subsystemParticles = Project.FindSubsystem<SubsystemParticles>(true);
236 SubsystemTime = Project.FindSubsystem<SubsystemTime>(true);
237 m_subsystemAudio = Project.FindSubsystem<SubsystemAudio>(true);
238 m_subsystemSeasons = Project.FindSubsystem<SubsystemSeasons>(true);
239 m_precipitationStartTime = valuesDictionary.GetValue<double>("WeatherStartTime");
240 m_precipitationEndTime = valuesDictionary.GetValue<double>("WeatherEndTime");
241 m_precipitationRampTime = valuesDictionary.GetValue("WeatherRampTime", 25f);
242 PrecipitationIntensity = valuesDictionary.GetValue("PrecipitationIntensity", 0f);
243 m_lightningIntensity = valuesDictionary.GetValue<float>("LightningIntensity");
244 m_fogStartTime = valuesDictionary.GetValue<double>("FogStartTime");
245 m_fogEndTime = valuesDictionary.GetValue<double>("FogEndTime");
246 m_fogRampTime = valuesDictionary.GetValue("FogRampTime", 25f);
247 FogIntensity = valuesDictionary.GetValue("FogIntensity", 0f);
248 FogProgress = valuesDictionary.GetValue("FogProgress", 0f);
249 m_rainSound = m_subsystemAudio.CreateSound("Audio/Rain");
250 m_rainSound.IsLooped = true;
251 m_rainSound.Volume = 0f;
257 for (int i = -7; i <= 7; i++) {
258 for (int j = -7; j <= 7; j++) {
259 float distance = MathF.Sqrt(i * i + j * j);
260 m_rainVolumeFactor += m_subsystemAudio.CalculateVolume(distance, 1f);
261 }
262 }
263 m_subsystemBlocksScanner.ScanningChunkCompleted += delegate(TerrainChunk chunk) {
264 if (m_subsystemGameInfo.WorldSettings.EnvironmentBehaviorMode == EnvironmentBehaviorMode.Living) {
265 FreezeThawAndDepositSnow(chunk, 0.66f, 0.66f, false);
266 }
267 };
268 SubsystemTerrain.TerrainUpdater.ChunkInitialized += delegate(TerrainChunk chunk) {
269 if (m_subsystemGameInfo.WorldSettings.EnvironmentBehaviorMode == EnvironmentBehaviorMode.Living) {
270 FreezeThawAndDepositSnow(chunk, 1f, 1f, m_subsystemGameInfo.WorldSettings.AreWeatherEffectsEnabled);
271 FreezeThawAndDepositSnow(chunk, 0.66f, 0.66f, m_subsystemGameInfo.WorldSettings.AreWeatherEffectsEnabled);
272 }
273 };
274 }
275
276 public override void Save(ValuesDictionary valuesDictionary) {
277 valuesDictionary.SetValue("WeatherStartTime", m_precipitationStartTime);
278 valuesDictionary.SetValue("WeatherEndTime", m_precipitationEndTime);
279 valuesDictionary.SetValue("WeatherRampTime", m_precipitationRampTime);
280 valuesDictionary.SetValue("WeatherIntensity", PrecipitationIntensity);
281 valuesDictionary.SetValue("LightningIntensity", m_lightningIntensity);
282 valuesDictionary.SetValue("FogStartTime", m_fogStartTime);
283 valuesDictionary.SetValue("FogEndTime", m_fogEndTime);
284 valuesDictionary.SetValue("FogRampTime", m_fogRampTime);
285 valuesDictionary.SetValue("FogIntensity", FogIntensity);
286 valuesDictionary.SetValue("FogProgress", FogProgress);
287 }
288
289 public virtual void UpdatePrecipitation(float dt) {
290 if (m_subsystemGameInfo.TotalElapsedGameTime > m_precipitationEndTime) {
291 float num = 0f;
292 float num2 = 0f;
293 float probability = 0f;
294 switch (m_subsystemSeasons.Season) {
295 case Season.Summer:
296 num = 1f;
297 num2 = 1f;
298 probability = 0.5f;
299 break;
300 case Season.Autumn:
301 num = 1.5f;
302 num2 = 1f;
303 probability = 0.5f;
304 break;
305 case Season.Winter:
306 num = 1f;
307 num2 = 0f;
308 probability = 0f;
309 break;
310 case Season.Spring:
311 num = 1.5f;
312 num2 = 2f;
313 probability = 1f;
314 break;
315 }
316 if (m_precipitationEndTime == 0.0) {
317 if (m_subsystemGameInfo.WorldSettings.StartingPositionMode == StartingPositionMode.Hard) {
318 m_precipitationStartTime = m_subsystemGameInfo.TotalElapsedGameTime + 60f * m_random.Float(0f, 2f);
319 m_lightningIntensity = m_random.Float(0.66f, 1f) * num2;
320 }
321 else {
322 m_precipitationStartTime = m_subsystemGameInfo.TotalElapsedGameTime + 60f * m_random.Float(3f, 6f);
323 m_lightningIntensity = m_random.Float(0.33f, 0.66f) * num2;
324 }
325 }
326 else {
327 m_precipitationStartTime = m_subsystemGameInfo.TotalElapsedGameTime + 60f * m_random.Float(5f, 45f) / num;
328 m_lightningIntensity = m_random.Bool(probability) ? MathUtils.Saturate(m_random.Float(0.33f, 1f) * num2) : 0f;
329 }
331 m_precipitationRampTime = m_random.Float(10f, 30f);
332 }
333 if (m_subsystemGameInfo.WorldSettings.AreWeatherEffectsEnabled) {
336 }
337 else {
339 }
340 }
341 else {
343 }
344 if (Time.PeriodicEvent(0.33000001311302185, 0.0)) {
345 float num3 = 0f;
346 if (PrecipitationIntensity > 0f) {
347 float num4 = 0f;
348 Vector3 vector = default;
349 foreach (Vector3 listenerPosition in m_subsystemAudio.ListenerPositions) {
350 int num5 = Terrain.ToCell(listenerPosition.X) - 7;
351 int num6 = Terrain.ToCell(listenerPosition.Z) - 7;
352 int num7 = Terrain.ToCell(listenerPosition.X) + 7;
353 int num8 = Terrain.ToCell(listenerPosition.Z) + 7;
354 for (int i = num5; i <= num7; i++) {
355 for (int j = num6; j <= num8; j++) {
356 PrecipitationShaftInfo precipitationShaftInfo = GetPrecipitationShaftInfo(i, j);
357 if (precipitationShaftInfo.Type == PrecipitationType.Rain
358 && precipitationShaftInfo.Intensity > 0f) {
359 vector.X = i + 0.5f;
360 vector.Y = MathUtils.Max(precipitationShaftInfo.YLimit, listenerPosition.Y);
361 vector.Z = j + 0.5f;
362 float num9 = vector.X - listenerPosition.X;
363 float num10 = 8f * (vector.Y - listenerPosition.Y);
364 float num11 = vector.Z - listenerPosition.Z;
365 float distance = MathF.Sqrt(num9 * num9 + num10 * num10 + num11 * num11);
366 num4 += m_subsystemAudio.CalculateVolume(distance, 1f) * precipitationShaftInfo.Intensity;
367 }
368 }
369 }
370 }
371 num3 = MathUtils.Max(num3, num4);
372 }
374 }
375 m_rainSound.Volume = MathUtils.Saturate(
377 );
379 m_rainSound.Play();
380 }
381 else {
382 m_rainSound.Pause();
383 }
384 }
385
386 public virtual void UpdateLightning(float dt) {
387 if (PrecipitationIntensity != 1f
388 || !SubsystemTime.PeriodicGameTimeEvent(1.0, 0.0)) {
389 return;
390 }
391 TerrainChunk[] allocatedChunks = SubsystemTerrain.Terrain.AllocatedChunks;
392 for (int i = 0; i < allocatedChunks.Length; i++) {
393 TerrainChunk terrainChunk = allocatedChunks[m_random.Int(0, allocatedChunks.Length - 1)];
394 if (terrainChunk.State < TerrainChunkState.InvalidVertices1
395 || !m_random.Bool(m_lightningIntensity * 0.0002f)) {
396 continue;
397 }
398 int num = terrainChunk.Origin.X + m_random.Int(0, 15);
399 int num2 = terrainChunk.Origin.Y + m_random.Int(0, 15);
400 Vector3? vector = null;
401 for (int j = num - 8; j < num + 8; j++) {
402 for (int k = num2 - 8; k < num2 + 8; k++) {
403 int topHeight = SubsystemTerrain.Terrain.GetTopHeight(j, k);
404 if (!vector.HasValue
405 || topHeight > vector.Value.Y) {
406 vector = new Vector3(j, topHeight, k);
407 }
408 }
409 }
410 if (vector.HasValue) {
411 SubsystemSky.MakeLightningStrike(vector.Value, false);
412 break;
413 }
414 }
415 }
416
417 public virtual void UpdateFog(float dt) {
418 if (m_subsystemGameInfo.TotalElapsedGameTime > m_fogEndTime) {
419 float num = m_subsystemSeasons.Season == Season.Autumn || m_subsystemSeasons.Season == Season.Winter ? 1.75f : 1f;
420 if (m_fogEndTime == 0.0
421 && m_subsystemGameInfo.WorldSettings.StartingPositionMode == StartingPositionMode.Hard) {
422 m_fogStartTime = m_subsystemGameInfo.TotalElapsedGameTime + 60f * m_random.Float(1f, 10f) / num;
423 }
424 else {
425 m_fogStartTime = m_subsystemGameInfo.TotalElapsedGameTime + 60f * m_random.Float(10f, 40f) / num;
426 }
427 m_fogEndTime = m_fogStartTime + 60f * m_random.Float(4f, 7f) * num;
428 m_fogRampTime = m_random.Float(20f, 40f);
429 FogProgress = 0f;
430 }
432 if (m_subsystemGameInfo.WorldSettings.AreWeatherEffectsEnabled) {
433 if (IsFogStarted) {
435 FogProgress += dt / (float)(m_fogEndTime - m_fogStartTime);
436 }
437 else {
439 }
440 }
441 else {
442 FogIntensity = 0f;
443 }
444 }
445
446 public virtual Dictionary<Point2, PrecipitationShaftParticleSystem> GetActiveShafts(GameWidget gameWidget) {
447 if (!m_activeShafts.TryGetValue(gameWidget, out Dictionary<Point2, PrecipitationShaftParticleSystem> value)) {
448 value = [];
449 m_activeShafts.Add(gameWidget, value);
450 }
451 return value;
452 }
453
454 public virtual void FreezeThawAndDepositSnow(TerrainChunk chunk, float freezeProbability, float thawProbability, bool forceDepositSnow) {
455 if (m_shuffledOrder == null) {
456 m_shuffledOrder = Enumerable.Range(0, 256).ToArray();
457 }
458 m_shuffledOrder.RandomShuffle(i => m_random.Int(i));
459 Terrain terrain = SubsystemTerrain.Terrain;
460 for (int j = 0; j < m_shuffledOrder.Length; j++) {
461 int num = m_shuffledOrder[j] & 0xF;
462 int num2 = m_shuffledOrder[j] >> 4;
463 int num3 = chunk.GetTopHeightFast(num, num2);
464 int cellValueFast = chunk.GetCellValueFast(num, num3, num2);
465 int num4 = Terrain.ExtractContents(cellValueFast);
466 int num5 = chunk.Origin.X + num;
467 int num6 = num3;
468 int num7 = chunk.Origin.Y + num2;
469 PrecipitationShaftInfo precipitationShaftInfo = GetPrecipitationShaftInfo(num5, num7);
470 if (precipitationShaftInfo.Type == PrecipitationType.Snow) {
471 if (!m_random.Bool(freezeProbability)) {
472 continue;
473 }
474 if (num4 == 18
475 && SubsystemTerrain.TerrainContentsGenerator.CalculateOceanShoreDistance(num5, num7) > -35f) {
476 int cellContents = terrain.GetCellContents(num5 + 1, num6, num7);
477 int cellContents2 = terrain.GetCellContents(num5 - 1, num6, num7);
478 int cellContents3 = terrain.GetCellContents(num5, num6, num7 - 1);
479 int cellContents4 = terrain.GetCellContents(num5, num6, num7 + 1);
480 bool num8 = BlocksManager.FluidBlocks[cellContents] == null && cellContents != 0;
481 bool flag = BlocksManager.FluidBlocks[cellContents2] == null && cellContents2 != 0;
482 bool flag2 = BlocksManager.FluidBlocks[cellContents3] == null && cellContents3 != 0;
483 bool flag3 = BlocksManager.FluidBlocks[cellContents4] == null && cellContents4 != 0;
484 if (num8
485 || flag
486 || flag2
487 || flag3) {
488 SubsystemTerrain.ChangeCell(num5, num6, num7, Terrain.MakeBlockValue(62));
489 }
490 }
491 else {
492 if ((!forceDepositSnow && !(precipitationShaftInfo.Intensity > 0.5f))
493 || num6 + 1 >= 255) {
494 continue;
495 }
496 if (SubsystemSnowBlockBehavior.CanSupportSnow(cellValueFast)) {
497 if (num4 != 62
498 || ShaftHasSnowOnIce(num5, num7)) {
499 SubsystemTerrain.ChangeCell(num5, num6 + 1, num7, Terrain.MakeBlockValue(61));
500 }
501 }
502 else if (SubsystemSnowBlockBehavior.CanBeReplacedBySnow(cellValueFast)) {
503 SubsystemTerrain.ChangeCell(num5, num6, num7, Terrain.MakeBlockValue(61));
504 }
505 }
506 }
507 else {
508 if (!m_random.Bool(thawProbability)) {
509 continue;
510 }
511 for (;
512 num6 > 0;
513 num3--, num6--, cellValueFast = chunk.GetCellValueFast(num, num3, num2), num4 = Terrain.ExtractContents(cellValueFast)) {
514 switch (num4) {
515 case 61:
516 SubsystemTerrain.DestroyCell(
517 0,
518 num5,
519 num6,
520 num7,
521 0,
522 true,
523 true
524 );
525 continue;
526 case 62:
527 SubsystemTerrain.DestroyCell(
528 0,
529 num5,
530 num6,
531 num7,
532 0,
533 false,
534 true
535 );
536 continue;
537 }
538 break;
539 }
540 }
541 }
542 }
543 }
544}
Engine.Vector3 Vector3
static float Remainder(float x, float y)
static int Hash(int key)
static float Saturate(float x)
static int Max(int x1, int x2)
static int Sqr(int x)
static float Lerp(float x1, float x2, float f)
static bool PeriodicEvent(double period, double offset)
定义 Time.cs:63
static float MinAudibleVolume
static FluidBlock[] FluidBlocks
Vector3 ViewPosition
GameWidget GameWidget
override void Load(ValuesDictionary valuesDictionary)
static Func< int, int, bool > ShaftHasSnowOnIce
virtual void ManualPrecipitationStart()
SubsystemBlocksScanner m_subsystemBlocksScanner
virtual void FreezeThawAndDepositSnow(TerrainChunk chunk, float freezeProbability, float thawProbability, bool forceDepositSnow)
virtual RainSplashParticleSystem RainSplashParticleSystem
List< PrecipitationShaftParticleSystem > m_toRemove
virtual void UpdatePrecipitation(float dt)
static Func< int, int > GetTemperatureAdjustmentAtHeight
SubsystemSeasons m_subsystemSeasons
static Func< int, int, bool > IsPlaceFrozen
SubsystemGameInfo m_subsystemGameInfo
virtual void Update(float dt)
virtual PrecipitationShaftInfo GetPrecipitationShaftInfo(int x, int z)
override void Save(ValuesDictionary valuesDictionary)
virtual void UpdateFog(float dt)
virtual Dictionary< Point2, PrecipitationShaftParticleSystem > GetActiveShafts(GameWidget gameWidget)
SubsystemParticles m_subsystemParticles
Dictionary< GameWidget, Dictionary< Point2, PrecipitationShaftParticleSystem > > m_activeShafts
Dictionary< GameWidget, Vector2?> m_lastShaftsUpdatePositions
SubsystemTerrain SubsystemTerrain
virtual void UpdateLightning(float dt)
virtual SnowSplashParticleSystem SnowSplashParticleSystem
virtual void Draw(Camera camera, int drawOrder)
virtual void ManualLightingStrike(Vector3 position, Vector3 direction)
TerrainChunkState State
virtual int GetCellValueFast(int index)
virtual int GetTopHeightFast(int x, int z)
static int ExtractContents(int value)
static int ToCell(float x)
virtual int GetCellContents(int x, int y, int z)
static int ExtractTopHeight(int value)
static int MakeBlockValue(int contents)
ValuesDictionary ValuesDictionary
static void HookAction(string HookName, Func< ModLoader, bool > action)
执行Hook
static float DistanceSquared(Vector2 v1, Vector2 v2)