using Content.Shared.Physics; using Robust.Shared.Physics.Collision.Shapes; using Robust.Shared.Prototypes; using Robust.Shared.Utility; namespace Content.Shared.RCD; /// /// Contains the parameters for an RCD construction / operation /// [Prototype("rcd")] public sealed class RCDPrototype : IPrototype { [IdDataField] public string ID { get; private set; } = default!; /// /// The RCD mode associated with the operation /// [DataField(required: true), ViewVariables(VVAccess.ReadOnly)] public RcdMode Mode { get; private set; } = RcdMode.Invalid; /// /// The name associated with the prototype /// [DataField("name"), ViewVariables(VVAccess.ReadOnly)] public string SetName { get; private set; } = "Unknown"; /// /// The name of the radial container that this prototype will be listed under on the RCD menu /// [DataField, ViewVariables(VVAccess.ReadOnly)] public string Category { get; private set; } = "Undefined"; /// /// Texture path for this prototypes menu icon /// [DataField, ViewVariables(VVAccess.ReadOnly)] public SpriteSpecifier? Sprite { get; private set; } /// /// The entity prototype that will be constructed (mode dependent) /// [DataField, ViewVariables(VVAccess.ReadOnly)] public string? Prototype { get; private set; } /// /// Number of charges consumed when the operation is completed /// [DataField, ViewVariables(VVAccess.ReadOnly)] public int Cost { get; private set; } = 1; /// /// The length of the operation /// [DataField, ViewVariables(VVAccess.ReadOnly)] public float Delay { get; private set; } = 1f; /// /// The visual effect that plays during this operation /// [DataField("fx"), ViewVariables(VVAccess.ReadOnly)] public EntProtoId? Effect { get; private set; } /// /// A list of rules that govern where the entity prototype can be constructed /// [DataField("rules"), ViewVariables(VVAccess.ReadOnly)] public HashSet ConstructionRules { get; private set; } = new(); /// /// The collision mask used for determining whether the entity prototype will fit into a target tile /// [DataField, ViewVariables(VVAccess.ReadOnly)] public CollisionGroup CollisionMask { get; private set; } = CollisionGroup.None; /// /// Specifies a set of custom collision bounds for determining whether the entity prototype will fit into a target tile /// /// /// Should be set assuming that the entity faces south. /// Make sure that Rotation is set to RcdRotation.User if the entity is to be rotated by the user /// [DataField, ViewVariables(VVAccess.ReadOnly)] public Box2? CollisionBounds { get => _collisionBounds; private set { _collisionBounds = value; if (_collisionBounds != null) { var poly = new PolygonShape(); poly.SetAsBox(_collisionBounds.Value); CollisionPolygon = poly; } } } private Box2? _collisionBounds; /// /// The polygon shape associated with the prototype CollisionBounds (if set) /// [ViewVariables(VVAccess.ReadOnly)] public PolygonShape? CollisionPolygon { get; private set; } /// /// Governs how the local rotation of the constructed entity will be set /// [DataField, ViewVariables(VVAccess.ReadOnly)] public RcdRotation Rotation { get; private set; } = RcdRotation.User; } public enum RcdMode : byte { Invalid, Deconstruct, ConstructTile, ConstructObject, } // These are to be replaced with more flexible 'RulesRule' at a later time public enum RcdConstructionRule : byte { MustBuildOnEmptyTile, // Can only be built on empty space (e.g. lattice) CanBuildOnEmptyTile, // Can be built on empty space or replace an existing tile (e.g. hull plating) MustBuildOnSubfloor, // Can only be built on exposed subfloor (e.g. catwalks on lattice or hull plating) IsWindow, // The entity is a window and can be built on grilles IsCatwalk, // The entity is a catwalk } public enum RcdRotation : byte { Fixed, // The entity has a local rotation of zero Camera, // The rotation of the entity matches the local player camera User, // The entity can be rotated by the local player prior to placement }