Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaShared/SharedSource/Serialization/Editable/ConditionallyEditable.cs
2025-12-08 14:56:47 +00:00

97 lines
3.8 KiB
C#

using System;
using System.Linq;
using Barotrauma.Items.Components;
namespace Barotrauma;
[AttributeUsage(AttributeTargets.Property)]
sealed class ConditionallyEditable : Editable
{
public ConditionallyEditable(ConditionType conditionType, bool onlyInEditors = true)
{
this.conditionType = conditionType;
this.onlyInEditors = onlyInEditors;
}
private readonly ConditionType conditionType;
private readonly bool onlyInEditors;
public enum ConditionType
{
//These need to exist at compile time, so it is a little awkward
//I would love to see a better way to do this
AllowLinkingWifiToChat,
IsSwappableItem,
AllowRotating,
Attachable,
/// <summary>
/// Does the entity currently have a physics body?
/// </summary>
HasBody,
/// <summary>
/// Does the entity normally have a physics body? Can be used if a property should be enabled on a wall whose collisions have been disabled.
/// </summary>
HasBodyByDefault,
Pickable,
OnlyByStatusEffectsAndNetwork,
HasIntegratedButtons,
IsToggleableController,
HasConnectionPanel,
DeteriorateUnderStress,
ReceivesSubmarineImpacts
}
public bool IsEditable(ISerializableEntity entity)
{
if (onlyInEditors && Screen.Selected is { IsEditor: false }) { return false; }
return conditionType switch
{
ConditionType.AllowLinkingWifiToChat
=> GameMain.NetworkMember is not { ServerSettings.AllowLinkingWifiToChat: false },
ConditionType.IsSwappableItem
=> entity is Item item && item.Prefab.SwappableItem != null,
ConditionType.AllowRotating
=> (entity is Item item && (item.body == null || item.body.BodyType == FarseerPhysics.BodyType.Static) && item.Prefab.AllowRotatingInEditor)
|| (entity is Structure structure && structure.Prefab.AllowRotatingInEditor),
ConditionType.Attachable
=> GetComponent<Holdable>(entity) is Holdable { Attachable: true },
ConditionType.HasBody
=> entity is Structure { HasBody: true } or Item { body: not null },
ConditionType.HasBodyByDefault
=> entity is Structure { Prefab.Body: true } or Item { body: not null },
ConditionType.Pickable
=> entity is Item item && item.GetComponent<Pickable>() != null,
ConditionType.OnlyByStatusEffectsAndNetwork
=> GameMain.NetworkMember is { IsServer: true },
ConditionType.HasIntegratedButtons
=> GetComponent<Door>(entity) is { HasIntegratedButtons: true },
ConditionType.IsToggleableController
=> GetComponent<Controller>(entity) is Controller { IsToggle: true } controller &&
controller.Item.GetComponent<ConnectionPanel>() != null,
ConditionType.HasConnectionPanel
=> GetComponent<ConnectionPanel>(entity) != null,
ConditionType.DeteriorateUnderStress
=> entity is Item repairableItem && repairableItem.Components.Any(c => c is IDeteriorateUnderStress),
ConditionType.ReceivesSubmarineImpacts
=> entity is Item { Prefab.ReceiveSubmarineImpacts: true },
_
=> false
};
static T GetComponent<T>(ISerializableEntity e) where T : ItemComponent
{
if (e is T t) { return t; }
if (e is Item item)
{
return item.GetComponent<T>();
}
if (e is ItemComponent ic)
{
return ic.Item.GetComponent<T>();
}
return null;
}
}
}