Upload from upload_mods.ps1

This commit is contained in:
Nathaniel Cosford
2025-06-04 16:44:53 +09:30
commit f1fbbe67bb
1722 changed files with 165268 additions and 0 deletions

View File

@@ -0,0 +1,786 @@
using Audio;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
/// <summary>
/// SCore's FireManager allows flammable blocks to catch and spread fire.
/// </summary>
/// <remarks>
/// The Fire Manager allows blocks to catch on fire, and allows them to spread to other blocks around it at a timed interval.
/// The following parameters are configured through the blocks.xml
/// </remarks>
public class FireManager
{
private const string AdvFeatureClass = "FireManagement";
private static readonly object Locker = new object();
private static readonly ConcurrentDictionary<Vector3i, BlockValue>
FireMap = new ConcurrentDictionary<Vector3i, BlockValue>();
private static readonly ConcurrentDictionary<Vector3i, float> ExtinguishPositions =
new ConcurrentDictionary<Vector3i, float>();
private float _checkTime = 120f;
private float _currentTime;
private const float CheckTimeLights = 0.8f;
private float _currentTimeLights;
private float _fireDamage = 1f;
private float _smokeTime = 60f;
private readonly GameRandom _random = GameManager.Instance.World.GetGameRandom();
private bool _fireSpread = true;
// Used to throttle sounds playing.
private static readonly List<Vector3i> SoundPlaying = new List<Vector3i>();
private static readonly List<Vector3i> ParticlePlaying = new List<Vector3i>();
private const int MaxLights = 32;
private static readonly HashSet<Light> Shutoff =
new HashSet<Light>();
private string _fireSound;
private string _fireParticle;
private string _smokeParticle;
private const string SaveFile = "FireManager.dat";
private ThreadManager.ThreadInfo _dataSaveThreadInfo;
private float _chanceToExtinguish = 0.05f;
public bool Enabled; // { private set; get; }
public static FireManager Instance { get; private set; }
public static void Init()
{
Instance = new FireManager();
Instance.ReadConfig();
}
private void ReadConfig()
{
var fireSpreadString = "true";
if (!StringParsers.ParseBool(fireSpreadString))
{
Debug.Log("Fire Spread Disabled.");
_fireSpread = false;
}
Enabled = true;
string option = "";
bool optionFireManager = CustomGameOptions.GetBool("CustomFireManager");
if (!optionFireManager)
{
Log.Out("Fire Manager is disabled.");
Enabled = false;
return;
}
option = "20";
if (!string.IsNullOrEmpty(option))
_checkTime = StringParsers.ParseFloat(option);
var strDamage = "50";
if (!string.IsNullOrWhiteSpace(strDamage))
_fireDamage = StringParsers.ParseFloat(strDamage);
_currentTime = -1;
var smoke = "60";
if (!string.IsNullOrWhiteSpace(smoke))
_smokeTime = StringParsers.ParseFloat(smoke);
var strFireSound = "SCoreMediumLoop";
if (!string.IsNullOrWhiteSpace(strFireSound))
_fireSound = strFireSound;
if (_fireSound == "None")
_fireSound = string.Empty;
Log.Out("Starting Fire Manager");
_fireParticle = "#@modfolder(zzz_REBIRTH__Utils):Resources/gupFireParticles.unity3d?gupBeavis05-Heavy";
_smokeParticle = "#@modfolder(zzz_REBIRTH__Utils):Resources/PathSmoke.unity3d?P_PathSmoke_X";
var optionChanceToExtinguish = "0.05";
if (!string.IsNullOrEmpty(option))
_chanceToExtinguish = StringParsers.ParseFloat(optionChanceToExtinguish);
// Read the FireManager
Load();
// Only run the Update on the server, then just distribute the data to the clients using NetPackages.
if (!SingletonMonoBehaviour<ConnectionManager>.Instance.IsServer) return;
Log.Out($" :: Fire Interval Check time: {_checkTime}");
ModEvents.GameUpdate.RegisterHandler(FireUpdate);
ModEvents.GameUpdate.RegisterHandler(LightsUpdate);
}
#region LightCode
private void LightsUpdate()
{
// Make sure to only run it once
lock (Locker)
{
_currentTimeLights -= Time.deltaTime;
if (_currentTimeLights > 0f) return;
_currentTimeLights = CheckTimeLights;
ShutoffLights();
CheckLights();
}
}
private static void ShutoffLights()
{
if (Shutoff.Count == 0) return;
if (GameManager.Instance.IsPaused()) return;
Shutoff.RemoveWhere(light => light == null);
foreach (var light in Shutoff)
{
light.intensity -= Time.deltaTime;
// Log.Out("Toning down {0}", light.intensity);
if (light.intensity > 0f) continue;
// Log.Out("Culling light out of this world");
var gameObject = light.gameObject;
gameObject.transform.parent = null;
UnityEngine.Object.Destroy(gameObject);
}
Shutoff.RemoveWhere(light => light.intensity <= 0f);
}
private static void CheckLights()
{
if (GameManager.Instance.IsPaused()) return;
var allLights = UnityEngine.Object.FindObjectsOfType<Light>();
if (allLights.Length <= MaxLights) return;
var curLights = new List<Light>();
for (var n = 0; n < allLights.Length; n += 1)
{
if (allLights[n].name != "FireLight") continue;
if (Shutoff.Contains(allLights[n])) continue;
curLights.Add(allLights[n]);
}
// AdvLogging.DisplayLog(AdvFeatureClass,$"Detect currently {curLights.Count} lights, {Shutoff.Count} being culled");
// Do nothing if we are (or will be) within limits
if (curLights.Count <= MaxLights) return;
// Otherwise choose more lights to shutoff
while (curLights.Count >= MaxLights)
{
var idx = GameManager.Instance.World.GetGameRandom().RandomRange(curLights.Count);
if (Shutoff.Contains(curLights[idx])) continue;
// Log.Out("Selected {0} for culling", idx);
Shutoff.Add(curLights[idx]);
curLights.RemoveAt(idx);
}
}
#endregion
// Poor man's timed cache
private void CheckExtinguishedPosition()
{
var worldTime = GameManager.Instance.World.GetWorldTime();
foreach (var position in ExtinguishPositions)
{
Remove(position.Key);
if (!(position.Value < worldTime) &&
!GameManager.Instance.World.GetBlock(position.Key + Vector3i.down).isair) continue;
ExtinguishPositions.TryRemove(position.Key, out var _);
ClearPos(position.Key);
}
}
public ConcurrentDictionary<Vector3i, BlockValue> GetFireMap()
{
return FireMap;
}
public int CloseFires(Vector3i position, int range = 5)
{
var count = 0;
for (var x = position.x - range; x <= position.x + range; x++)
{
for (var z = position.z - range; z <= position.z + range; z++)
{
for (int y = position.y - 2; y <= position.y + 2; y++)
{
var localPosition = new Vector3i(x, y, z);
if (IsBurning(localPosition)) count++;
}
}
}
return count;
}
public bool IsPositionCloseToFire(Vector3i position, int range = 5)
{
for (var x = position.x - range; x <= position.x + range; x++)
{
for (var z = position.z - range; z <= position.z + range; z++)
{
for (var y = position.y - 2; y <= position.y + 2; y++)
{
var localPosition = new Vector3i(x, y, z);
if (IsBurning(localPosition)) return true;
}
}
}
return false;
}
private void FireUpdate()
{
// Make sure to only run it once
lock (Locker)
{
_currentTime -= Time.deltaTime;
if (_currentTime > 0f) return;
GameManager.Instance.StopCoroutine(CheckBlocks());
GameManager.Instance.StartCoroutine(CheckBlocks());
}
}
private IEnumerator CheckBlocks()
{
if (GameManager.Instance.IsPaused()) yield break;
if (!GameManager.Instance.gameStateManager.IsGameStarted()) yield break;
//Log.Out(AdvFeatureClass,
//$"Checking Blocks for Fire: {FireMap.Count} Blocks registered. Extinguished Blocks: {ExtinguishPositions.Count}");
_currentTime = _checkTime;
var changes = new List<BlockChangeInfo>();
var neighbors = new List<Vector3i>();
CheckExtinguishedPosition();
var chunkCluster = GameManager.Instance.World.ChunkClusters[0];
if (chunkCluster == null) yield break;
var counter = 0;
var rainfallValue = WeatherManager.Instance.GetCurrentRainfallValue();
foreach (var posDict in FireMap)
{
counter++;
// only process 10 blocks per frame.
if (counter % 10 == 0)
yield return null;
var blockPos = posDict.Key;
if (!IsFlammable(blockPos))
{
Remove(blockPos);
continue;
}
var block = GameManager.Instance.World.GetBlock(blockPos);
// Get block specific damages
var damage = (int)_fireDamage;
if (block.Block.Properties.Contains("FireDamage"))
damage = block.Block.Properties.GetInt("FireDamage");
if (block.Block.blockMaterial.Properties.Contains("FireDamage"))
damage = block.Block.blockMaterial.Properties.GetInt("FireDamage");
if (block.Block.Properties.Contains("ChanceToExtinguish"))
block.Block.Properties.ParseFloat("ChanceToExtinguish", ref _chanceToExtinguish);
block.damage += damage;
if (block.damage >= block.Block.MaxDamage)
{
block.Block.SpawnDestroyParticleEffect(GameManager.Instance.World, block, blockPos, 1f,
block.Block.tintColor, -1);
var blockValue2 = block.Block.DowngradeBlock;
if (block.Block.Properties.Values.ContainsKey("FireDowngradeBlock"))
blockValue2 = Block.GetBlockValue(block.Block.Properties.Values["FireDowngradeBlock"]);
if (block.Block.Properties.Values.ContainsKey("Explosion.ParticleIndex") ||
block.Block.Properties.Classes.ContainsKey("Explosion"))
block.Block.OnBlockDestroyedByExplosion(GameManager.Instance.World, 0, blockPos, block, -1);
// Check if there's another placeholder for this block.
if (!blockValue2.isair)
blockValue2 = BlockPlaceholderMap.Instance.Replace(blockValue2,
GameManager.Instance.World.GetGameRandom(), blockPos.x, blockPos.z);
blockValue2.rotation = block.rotation;
blockValue2.meta = block.meta;
block = blockValue2;
}
if (!block.isair)
{
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage(
NetPackageManager.GetPackage<NetPackageAddFirePosition>().Setup(blockPos, -1));
}
else
{
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage(
NetPackageManager.GetPackage<NetPackageRemoveFirePosition>().Setup(blockPos, -1));
}
changes.Add(new BlockChangeInfo(0, blockPos, block));
var rand = _random.RandomRange(0f, 1f);
var extinguishChange = _chanceToExtinguish;
if (rainfallValue > 0.25)
{
extinguishChange = _chanceToExtinguish * 2f;
}
var blchanceToExtinguish = rand < extinguishChange;
// If the new block has changed, check to make sure the new block is flammable. Note: it checks the blockValue, not blockPos, since the change hasn't been committed yet.
if (!IsFlammable(block) || block.isair || blchanceToExtinguish)
{
// queue up the change
if (DynamicMeshManager.Instance != null)
DynamicMeshManager.Instance.AddChunk(blockPos, true);
Extinguish(blockPos);
continue;
}
ToggleSound(blockPos, rand < 0.10);
ToggleParticle(blockPos, true);
// If we are damaging a block, allow the fire to spread.
if (_fireSpread)
neighbors.AddRange(CheckNeighbors(blockPos));
FireMap[blockPos] = block;
}
// Send all the changes in one shot
if (changes.Count > 0)
GameManager.Instance.SetBlocksRPC(changes);
if (_fireSpread == false) yield break;
// Spread the fire to the neighbors. We delay this here so the fire does not spread too quickly or immediately, getting stuck in the above loop.
foreach (var pos in neighbors)
Add(pos);
//Debug.Log($"Sound Counter: {SoundPlaying.Count}, Fire Counter: {FireMap.Count} Particle Count: {ParticlePlaying.Count}: Heat: {heatMeter}");
}
private void ToggleSound(Vector3i blockPos, bool turnOn)
{
//if (SingletonMonoBehaviour<ConnectionManager>.Instance.IsServer) return;
if (!ThreadManager.IsMainThread()) return;
// If there's a lot of fires going on, turn off the sounds.
if (turnOn && FireMap.Count > 60)
{
turnOn = false;
}
var sound = GetFireSound(blockPos);
if (string.IsNullOrEmpty(sound)) return;
if (turnOn)
{
if (SoundPlaying.Contains(blockPos))
return;
SoundPlaying.Add(blockPos);
Manager.Play(blockPos, sound);
return;
}
// No sound?
if (!SoundPlaying.Contains(blockPos)) return;
Manager.Stop(blockPos, sound);
SoundPlaying.Remove(blockPos);
}
private void ToggleParticle(Vector3i blockPos, bool turnOn)
{
// if (SingletonMonoBehaviour<ConnectionManager>.Instance.IsServer) return;
if (!ThreadManager.IsMainThread()) return;
var randomFireParticle = GetRandomFireParticle(blockPos);
if (turnOn)
{
if (ParticlePlaying.Contains(blockPos)) return;
if (GameManager.Instance.HasBlockParticleEffect(blockPos)) return;
ParticlePlaying.Add(blockPos);
RebirthUtilities.addParticlesCentered(randomFireParticle, blockPos);
return;
}
ParticlePlaying.Remove(blockPos);
RebirthUtilities.removeParticles(blockPos);
}
private string GetFireSound(Vector3i blockPos)
{
var block = GameManager.Instance.World.GetBlock(blockPos);
var fireSound = _fireSound;
if (block.Block.Properties.Contains("FireSound"))
fireSound = block.Block.Properties.GetString("FireSound");
return fireSound;
}
private string GetRandomFireParticle(Vector3i blockPos)
{
var block = GameManager.Instance.World.GetBlock(blockPos);
var fireParticle = _fireParticle;
if (block.Block.Properties.Contains("FireParticle"))
fireParticle = block.Block.Properties.GetString("FireParticle");
if (block.Block.blockMaterial.Properties.Contains("FireParticle"))
fireParticle = block.Block.blockMaterial.Properties.GetString("FireParticle");
var randomFire = ""; // Configuration.GetPropertyValue(AdvFeatureClass, "RandomFireParticle");
if (string.IsNullOrEmpty(randomFire)) return fireParticle;
var fireParticles = randomFire.Split(',');
var randomIndex = _random.RandomRange(0, fireParticles.Length);
fireParticle = fireParticles[randomIndex];
return fireParticle;
}
private string GetRandomSmokeParticle(Vector3i blockPos)
{
var block = GameManager.Instance.World.GetBlock(blockPos);
var smokeParticle = _smokeParticle;
if (block.Block.Properties.Contains("SmokeParticle"))
smokeParticle = block.Block.Properties.GetString("SmokeParticle");
if (block.Block.blockMaterial.Properties.Contains("SmokeParticle"))
smokeParticle = block.Block.blockMaterial.Properties.GetString("SmokeParticle");
var randomSmoke = ""; // Configuration.GetPropertyValue(AdvFeatureClass, "RandomSmokeParticle");
if (string.IsNullOrEmpty(randomSmoke)) return smokeParticle;
var smokeParticles = randomSmoke.Split(',');
var randomIndex = GameManager.Instance.World.GetGameRandom().RandomRange(0, smokeParticles.Length);
smokeParticle = smokeParticles[randomIndex];
return smokeParticle;
}
// Check to see if the nearby blocks can catch fire.
private static List<Vector3i> CheckNeighbors(Vector3i blockPos)
{
var neighbors = new List<Vector3i>();
foreach (var direction in Vector3i.AllDirections)
{
var position = blockPos + direction;
if (FireMap.ContainsKey(position))
continue;
if (IsFlammable(position))
neighbors.Add(position);
}
return neighbors;
}
private static bool IsNearWater(Vector3i blockPos)
{
foreach (var direction in Vector3i.AllDirections)
{
var position = blockPos + direction;
var blockValue = GameManager.Instance.World.GetBlock(position);
if (blockValue.isWater) return true;
if (blockValue.Block is BlockLiquidv2) return true;
// A21 water check.
if (GameManager.Instance.World.GetWaterPercent(position) > 0.25f) return true;
}
return false;
}
private static bool IsFlammable(BlockValue blockValue)
{
if (blockValue.Block.HasAnyFastTags(FastTags<TagGroup.Global>.Parse("inflammable"))) return false;
if (blockValue.ischild) return false;
if (blockValue.isair) return false;
if (blockValue.isWater) return false;
// if (blockValue.Block.Properties.Values.ContainsKey("Explosion.ParticleIndex")) return true;
if (blockValue.Block.HasAnyFastTags(FastTags<TagGroup.Global>.Parse("flammable"))) return true;
var blockMaterial = blockValue.Block.blockMaterial;
var matID = "Mplants, Mcorn, Mhay"; // Configuration.GetPropertyValue(AdvFeatureClass, "MaterialID");
if (matID.Contains(blockMaterial.id)) return true;
var matDamage = "wood, cloth, corn, grass, plastic, leaves, cactus, mushroom, hay, paper, trash, backpack, organic"; // Configuration.GetPropertyValue(AdvFeatureClass, "MaterialDamage");
if (!string.IsNullOrEmpty(matDamage) && blockMaterial.DamageCategory != null)
if (matDamage.Contains(blockMaterial.DamageCategory))
return true;
var matSurface = "wood, cloth, corn, grass, plastic, leaves, cactus, mushroom, hay, paper, trash, backpack, organic"; // Configuration.GetPropertyValue(AdvFeatureClass, "MaterialSurface");
if (string.IsNullOrEmpty(matSurface) || blockMaterial.SurfaceCategory == null) return false;
return matSurface.Contains(blockMaterial.SurfaceCategory);
}
private static bool IsFlammable(Vector3i blockPos)
{
if (GameManager.Instance.World.IsWithinTraderArea(blockPos)) return false;
if (ExtinguishPositions.ContainsKey(blockPos)) return false;
// If its already burning, then don't do any other check
if (IsBurning(blockPos)) return true;
if (IsNearWater(blockPos)) return false;
// Check the block value.
var blockValue = GameManager.Instance.World.GetBlock(blockPos);
return IsFlammable(blockValue);
}
private static void Write(BinaryWriter bw)
{
// Save the burning blocks.
var writeOut = "";
foreach (var temp in FireMap)
writeOut += $"{temp.Key};";
writeOut = writeOut.TrimEnd(';');
bw.Write(writeOut);
// Save the blocks we've put out
var writeOut2 = "";
foreach (var temp in ExtinguishPositions.Keys)
writeOut2 += $"{temp};";
writeOut2 = writeOut2.TrimEnd(';');
bw.Write(writeOut2);
}
private void Read(BinaryReader br)
{
// Read burning blocks
var positions = br.ReadString();
foreach (var position in positions.Split(';'))
{
if (string.IsNullOrEmpty(position)) continue;
var vector = StringParsers.ParseVector3i(position);
AddBlock(vector);
}
// Read extinguished blocks.
var extingished = br.ReadString();
foreach (var position in extingished.Split(';'))
{
if (string.IsNullOrEmpty(position)) continue;
var vector = StringParsers.ParseVector3i(position);
ExtinguishBlock(vector);
}
}
public void ClearPosOnly(Vector3i blockPos)
{
ToggleSound(blockPos, false);
ToggleParticle(blockPos, false);
}
public void ClearPos(Vector3i blockPos)
{
ClearPosOnly(blockPos);
if (!SingletonMonoBehaviour<ConnectionManager>.Instance.IsServer)
{
SingletonMonoBehaviour<ConnectionManager>.Instance.SendToServer(
NetPackageManager.GetPackage<NetPackageRemoveParticleEffect>().Setup(blockPos, -1));
return;
}
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage(
NetPackageManager.GetPackage<NetPackageRemoveParticleEffect>().Setup(blockPos, -1));
}
public void Add(Vector3i blockPos, int entityID = -1)
{
if (!IsFlammable(blockPos))
return;
AddBlock(blockPos);
if (!SingletonMonoBehaviour<ConnectionManager>.Instance.IsServer)
{
SingletonMonoBehaviour<ConnectionManager>.Instance.SendToServer(
NetPackageManager.GetPackage<NetPackageAddFirePosition>().Setup(blockPos, entityID));
return;
}
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage(
NetPackageManager.GetPackage<NetPackageAddFirePosition>().Setup(blockPos, entityID));
}
// General call to remove the fire from a block, and add an extinguished counter, so blocks can be temporarily immune to restarting.
public void Extinguish(Vector3i blockPos, int entityID = -1)
{
ExtinguishBlock(blockPos);
if (!SingletonMonoBehaviour<ConnectionManager>.Instance.IsServer)
{
SingletonMonoBehaviour<ConnectionManager>.Instance.SendToServer(
NetPackageManager.GetPackage<NetPackageAddExtinguishPosition>().Setup(blockPos, entityID));
return;
}
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage(
NetPackageManager.GetPackage<NetPackageAddExtinguishPosition>().Setup(blockPos, entityID));
}
public void Remove(Vector3i blockPos, int entityID = -1)
{
RemoveFire(blockPos);
if (!SingletonMonoBehaviour<ConnectionManager>.Instance.IsServer)
{
SingletonMonoBehaviour<ConnectionManager>.Instance.SendToServer(
NetPackageManager.GetPackage<NetPackageRemoveFirePosition>().Setup(blockPos, entityID));
return;
}
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage(
NetPackageManager.GetPackage<NetPackageRemoveFirePosition>().Setup(blockPos, entityID));
}
public void RemoveFire(Vector3i blockPos)
{
//if (!FireMap.ContainsKey(blockPos)) return;
ToggleSound(blockPos, false);
ToggleParticle(blockPos, false);
FireMap.TryRemove(blockPos, out _);
}
public void ExtinguishBlock(Vector3i blockPos)
{
//Log.Out("FireManager-ExtinguishBlock START");
var worldTime = GameManager.Instance.World.GetWorldTime();
var expiry = worldTime + _smokeTime;
// Seems like sometimes the dedicated and clients are out of sync, so this is a shot in the dark to see if we just skip the expired position check, and just
// keep resetting the expired time.
ExtinguishPositions[blockPos] = expiry;
FireMap.TryRemove(blockPos, out _);
var block = GameManager.Instance.World.GetBlock(blockPos);
ToggleSound(blockPos, false);
if (block.isair || !(_smokeTime > 0))
{
//Log.Out("FireManager-ExtinguishBlock 1");
return;
}
var randomSmokeParticle = GetRandomSmokeParticle(blockPos);
//Log.Out("FireManager-ExtinguishBlock randomSmokeParticle: " + randomSmokeParticle);
RebirthUtilities.addParticlesCentered(randomSmokeParticle, blockPos);
}
// Add flammable blocks to the Fire Map
public void AddBlock(Vector3i blockPos)
{
var block = GameManager.Instance.World.GetBlock(blockPos);
if (!FireMap.TryAdd(blockPos, block)) return;
ToggleSound(blockPos, true);
ToggleParticle(blockPos, true);
}
public static bool IsBurning(Vector3i blockPos)
{
return Instance.Enabled && FireMap.ContainsKey(blockPos);
}
private int SaveDataThreaded(ThreadManager.ThreadInfo threadInfo)
{
var pooledExpandableMemoryStream =
(PooledExpandableMemoryStream)threadInfo.parameter;
var text = $"{GameIO.GetSaveGameDir()}/{SaveFile}";
if (File.Exists(text))
File.Copy(text, $"{GameIO.GetSaveGameDir()}/{SaveFile}.bak", true);
pooledExpandableMemoryStream.Position = 0L;
StreamUtils.WriteStreamToFile(pooledExpandableMemoryStream, text);
Log.Out("FireManager saved {0} bytes", new object[]
{
pooledExpandableMemoryStream.Length
});
MemoryPools.poolMemoryStream.FreeSync(pooledExpandableMemoryStream);
return -1;
}
private void Save()
{
if (_dataSaveThreadInfo == null || !ThreadManager.ActiveThreads.ContainsKey("silent_FireDataSave"))
{
Log.Out($"FireManager saving {FireMap.Count} Fires...");
var pooledExpandableMemoryStream = MemoryPools.poolMemoryStream.AllocSync(true);
using (var pooledBinaryWriter = MemoryPools.poolBinaryWriter.AllocSync(false))
{
pooledBinaryWriter.SetBaseStream(pooledExpandableMemoryStream);
Write(pooledBinaryWriter);
}
_dataSaveThreadInfo = ThreadManager.StartThread("silent_FireDataSave", null,
SaveDataThreaded, null,
System.Threading.ThreadPriority.Normal, pooledExpandableMemoryStream);
}
else
{
Log.Out("Not Saving. Thread still running?");
}
}
private void Load()
{
var path = $"{GameIO.GetSaveGameDir()}/{SaveFile}";
if (!Directory.Exists(GameIO.GetSaveGameDir()) || !File.Exists(path)) return;
try
{
using var fileStream = File.OpenRead(path);
using var pooledBinaryReader = MemoryPools.poolBinaryReader.AllocSync(false);
pooledBinaryReader.SetBaseStream(fileStream);
Read(pooledBinaryReader);
}
catch (Exception)
{
path = $"{GameIO.GetSaveGameDir()}/{SaveFile}.bak";
if (File.Exists(path))
{
using var fileStream2 = File.OpenRead(path);
using var pooledBinaryReader2 = MemoryPools.poolBinaryReader.AllocSync(false);
pooledBinaryReader2.SetBaseStream(fileStream2);
Read(pooledBinaryReader2);
}
}
Log.Out($"Fire Manager {path} Loaded: {FireMap.Count}");
}
public void Reset()
{
//Log.Out("Removing all blocks that are on fire and smoke.");
lock (Locker)
{
foreach (var position in FireMap.Keys)
Remove(position);
foreach (var position in ExtinguishPositions.Keys)
RebirthUtilities.removeParticles(position);
FireMap.Clear();
ExtinguishPositions.Clear();
Save();
}
}
}