Files
Nitrox/NitroxClient/MonoBehaviours/BaseLeakManager.cs
2025-07-06 00:23:46 +02:00

122 lines
4.1 KiB
C#

using System.Collections.Generic;
using NitroxClient.Communication;
using NitroxClient.GameLogic;
using NitroxModel.DataStructures;
using NitroxModel.Packets;
using NitroxModel_Subnautica.DataStructures;
using UnityEngine;
namespace NitroxClient.MonoBehaviours;
public class BaseLeakManager : MonoBehaviour
{
private Dictionary<Int3, NitroxId> idByRelativeCell;
private Base @base;
private BaseHullStrength baseHullStrength;
private NitroxId baseId;
public void Awake()
{
if (!TryGetComponent(out baseHullStrength))
{
Log.Error($"Tried adding a {nameof(BaseLeakManager)} to a GameObject that isn't a base, deleting it.");
Destroy(this);
return;
}
@base = baseHullStrength.baseComp;
@base.TryGetNitroxId(out baseId);
idByRelativeCell = new();
}
/// <summary>
/// Either creates or updates existing leaks by modifying the base cell's health.
/// Also registers the leak's id for further use.
/// </summary>
public void EnsureLeak(Int3 relativeCell, NitroxId cellId, float health)
{
Int3 absoluteCell = Absolute(relativeCell);
Transform cellObject = @base.GetCellObject(absoluteCell);
if (!cellObject)
{
return;
}
idByRelativeCell[relativeCell] = cellId;
if (cellObject.TryGetComponent(out LiveMixin cellLiveMixin))
{
// Health goes from 0 to 100
float deltaHealth = health - cellLiveMixin.health;
if (Mathf.Abs(deltaHealth) > 1)
{
// Useful part of BaseHullStrength.CrushDamageUpdate
this.Resolve<LiveMixinManager>().SyncRemoteHealth(cellLiveMixin, health, cellObject.position, DamageType.Pressure);
// Only play noise if the leak lost health
if (deltaHealth >= 0)
{
return;
}
// Spawning multiple leaks would result in a big sounds when loading the game
if (Multiplayer.Main && Multiplayer.Main.InitialSyncCompleted)
{
// Code from BaseHullStrength.CrushDamageUpdate
int num = 0;
if (baseHullStrength.totalStrength <= -3f)
{
num = 2;
}
else if (baseHullStrength.totalStrength <= -2f)
{
num = 1;
}
if (baseHullStrength.crushSounds[num] != null)
{
using (PacketSuppressor<FMODAssetPacket>.Suppress())
{
Utils.PlayFMODAsset(baseHullStrength.crushSounds[num], cellObject, 20f);
}
}
ErrorMessage.AddMessage(Language.main.GetFormat("BaseHullStrDamageDetected", baseHullStrength.totalStrength));
}
}
}
}
public void HealLeakToMax(Int3 relativeCell)
{
Transform cellObject = @base.GetCellObject(Absolute(relativeCell));
if (cellObject && cellObject.TryGetComponent(out LiveMixin liveMixin))
{
this.Resolve<LiveMixinManager>().SyncRemoteHealth(liveMixin, liveMixin.maxHealth);
idByRelativeCell.Remove(relativeCell);
}
}
public Int3 Absolute(Int3 relativeCell)
{
return relativeCell + @base.anchor;
}
public Int3 Relative(Int3 absoluteCell)
{
return absoluteCell - @base.anchor;
}
public LeakRepaired RemoveLeakByAbsoluteCell(Int3 absoluteCell)
{
Int3 relativeCell = Relative(absoluteCell);
if (idByRelativeCell.TryGetValue(relativeCell, out NitroxId cellId))
{
idByRelativeCell.Remove(relativeCell);
return new(baseId, cellId, relativeCell.ToDto());
}
return null;
}
public bool TryGetAbsoluteCellId(Int3 absoluteCell, out NitroxId cellId)
{
return idByRelativeCell.TryGetValue(Relative(absoluteCell), out cellId);
}
}