diff --git a/Content.Server/ADT/SizeAttribute/SizeAttributeComponent.cs b/Content.Server/ADT/SizeAttribute/SizeAttributeComponent.cs new file mode 100644 index 00000000000..d617a633a3d --- /dev/null +++ b/Content.Server/ADT/SizeAttribute/SizeAttributeComponent.cs @@ -0,0 +1,14 @@ +using Content.Shared.Cloning; + +namespace Content.Server.ADT.SizeAttribute +{ + [RegisterComponent] + public sealed partial class SizeAttributeComponent : Component, ITransferredByCloning + { + [DataField("short")] + public bool Short = false; + + [DataField("tall")] + public bool Tall = false; + } +} \ No newline at end of file diff --git a/Content.Server/ADT/SizeAttribute/SizeAttributeSystem.cs b/Content.Server/ADT/SizeAttribute/SizeAttributeSystem.cs new file mode 100644 index 00000000000..ac64100bb53 --- /dev/null +++ b/Content.Server/ADT/SizeAttribute/SizeAttributeSystem.cs @@ -0,0 +1,94 @@ +using System.Numerics; +using Robust.Server.GameObjects; +using Robust.Shared.Physics; +using Robust.Shared.Physics.Collision.Shapes; +using Robust.Shared.Physics.Systems; +using Content.Shared.Item.PseudoItem; + +namespace Content.Server.ADT.SizeAttribute +{ + public sealed class SizeAttributeSystem : EntitySystem + { + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly SharedPhysicsSystem _physics = default!; + [Dependency] private readonly AppearanceSystem _appearance = default!; + [Dependency] private readonly FixtureSystem _fixtures = default!; + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnComponentInit); + } + + private void OnComponentInit(EntityUid uid, SizeAttributeComponent component, ComponentInit args) + { + if (!TryComp(uid, out var whitelist)) + return; + + if (whitelist.Tall && component.Tall) + { + Scale(uid, component, whitelist.TallScale, whitelist.TallDensity, whitelist.TallCosmeticOnly); + PseudoItem(uid, component, whitelist.TallPseudoItem); + } + else if (whitelist.Short && component.Short) + { + Scale(uid, component, whitelist.ShortScale, whitelist.ShortDensity, whitelist.ShortCosmeticOnly); + PseudoItem(uid, component, whitelist.ShortPseudoItem); + } + } + + private void PseudoItem(EntityUid uid, SizeAttributeComponent component, bool active) + { + if (active) + { + if (TryComp(uid, out var pseudoI)) + return; + + _entityManager.AddComponent(uid); + } + else + { + if (!TryComp(uid, out var pseudoI)) + return; + + _entityManager.RemoveComponent(uid); + } + } + + private void Scale(EntityUid uid, SizeAttributeComponent component, float scale, float density, bool cosmeticOnly) + { + if (scale <= 0f && density <= 0f) + return; + + _entityManager.EnsureComponent(uid); + + var appearanceComponent = _entityManager.EnsureComponent(uid); + if (!_appearance.TryGetData(uid, ScaleVisuals.Scale, out var oldScale, appearanceComponent)) + oldScale = Vector2.One; + + _appearance.SetData(uid, ScaleVisuals.Scale, oldScale * scale, appearanceComponent); + + if (!cosmeticOnly && _entityManager.TryGetComponent(uid, out FixturesComponent? manager)) + { + foreach (var (id, fixture) in manager.Fixtures) + { + if (!fixture.Hard || fixture.Density <= 1f) + continue; // This will skip the flammable fixture and any other fixture that is not supposed to contribute to mass + + switch (fixture.Shape) + { + case PhysShapeCircle circle: + _physics.SetPositionRadius(uid, id, fixture, circle, circle.Position * scale, circle.Radius * scale, manager); + break; + default: + throw new NotImplementedException(); + } + + _physics.SetDensity(uid, id, fixture, density); + } + } + } + } + + [ByRefEvent] + public readonly record struct ScaleEntityEvent(EntityUid Uid) { } +} \ No newline at end of file diff --git a/Content.Server/ADT/SizeAttribute/SizeAttributeWhitelistComponent.cs b/Content.Server/ADT/SizeAttribute/SizeAttributeWhitelistComponent.cs index 3816ce8b7ab..fdf8b813d02 100644 --- a/Content.Server/ADT/SizeAttribute/SizeAttributeWhitelistComponent.cs +++ b/Content.Server/ADT/SizeAttribute/SizeAttributeWhitelistComponent.cs @@ -1,6 +1,6 @@ using Robust.Shared.Physics.Collision.Shapes; -namespace Content.Server.SizeAttribute +namespace Content.Server.ADT.SizeAttribute { [RegisterComponent] public sealed partial class SizeAttributeWhitelistComponent : Component diff --git a/Content.Shared/ADT/Cloning/ITransferredByCloning.cs b/Content.Shared/ADT/Cloning/ITransferredByCloning.cs new file mode 100644 index 00000000000..31deaff5017 --- /dev/null +++ b/Content.Shared/ADT/Cloning/ITransferredByCloning.cs @@ -0,0 +1,8 @@ +namespace Content.Shared.Cloning; + +/// +/// Indicates that this Component should be transferred to the new entity when the entity is cloned (for example, using a cloner) +/// +public interface ITransferredByCloning +{ +} \ No newline at end of file diff --git a/Content.Shared/ADT/Item/PseudoItemComponent.cs b/Content.Shared/ADT/Item/PseudoItemComponent.cs new file mode 100644 index 00000000000..5190e3a3623 --- /dev/null +++ b/Content.Shared/ADT/Item/PseudoItemComponent.cs @@ -0,0 +1,19 @@ +using Content.Shared.Cloning; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Shared.Item.PseudoItem; +/// +/// For entities that behave like an item under certain conditions, +/// but not under most conditions. +/// +[RegisterComponent] +public sealed partial class PseudoItemComponent : Component, ITransferredByCloning +{ + [DataField("size", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string Size = "Huge"; + + public bool Active = false; + + [DataField] + public EntityUid? SleepAction; +} \ No newline at end of file diff --git a/Resources/Locale/ru-RU/ADT/traits/categories.ftl b/Resources/Locale/ru-RU/ADT/traits/categories.ftl new file mode 100644 index 00000000000..f714bd58c50 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/traits/categories.ftl @@ -0,0 +1 @@ +trait-category-height = Рост \ No newline at end of file diff --git a/Resources/Locale/ru-RU/ADT/traits/neutral.ftl b/Resources/Locale/ru-RU/ADT/traits/neutral.ftl index 16e3b5fb766..fbeb6a89824 100644 --- a/Resources/Locale/ru-RU/ADT/traits/neutral.ftl +++ b/Resources/Locale/ru-RU/ADT/traits/neutral.ftl @@ -2,4 +2,10 @@ trait-deutsch-name = Немецкий акцент trait-deutsch-desc = Вы говорите как настоящий австрийский художник! trait-moth-accent-name = Жужащий акцент -trait-moth-accent-desc = Вам либо нравятся моли, либо вы ботаник \ No newline at end of file +trait-moth-accent-desc = Вам либо нравятся моли, либо вы ботаник + +trait-tall-name = Высокий +trait-tall-desc = Вы слегка выше других представителей своего вида. + +trait-short-name = Низкий +trait-short-desc = Вы слегка ниже других представителей своего вида. \ No newline at end of file diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Player/Drask.yml b/Resources/Prototypes/ADT/Entities/Mobs/Player/Drask.yml index 9727af7e9d0..dd40d39740f 100644 --- a/Resources/Prototypes/ADT/Entities/Mobs/Player/Drask.yml +++ b/Resources/Prototypes/ADT/Entities/Mobs/Player/Drask.yml @@ -38,8 +38,8 @@ understands: - GalacticCommon - Drask - # - type: SizeAttributeWhitelist # Frontier TODO: нет такого компонента.. - # tall: true - # tallscale: 1.15 - # short: true - # shortscale: 1 + - type: SizeAttributeWhitelist # Frontier + tall: true + tallscale: 1.15 + short: true + shortscale: 1 diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Player/demon.yml b/Resources/Prototypes/ADT/Entities/Mobs/Player/demon.yml index 388c63b7ee2..8e8a6ec8cd7 100644 --- a/Resources/Prototypes/ADT/Entities/Mobs/Player/demon.yml +++ b/Resources/Prototypes/ADT/Entities/Mobs/Player/demon.yml @@ -39,10 +39,10 @@ damageRecovery: types: Asphyxiation: -1.0 - # - type: SizeAttributeWhitelist # Frontier TODO: нет такого компонента.. - # tall: true - # tallscale: 1.1 - # short: true - # shortscale: 0.9 + - type: SizeAttributeWhitelist # Frontier + tall: true + tallscale: 1.1 + short: true + shortscale: 0.9 #Weh diff --git a/Resources/Prototypes/ADT/Traits/categories.yml b/Resources/Prototypes/ADT/Traits/categories.yml new file mode 100644 index 00000000000..fec1cdb72d5 --- /dev/null +++ b/Resources/Prototypes/ADT/Traits/categories.yml @@ -0,0 +1,4 @@ +- type: traitCategory + id: Height + name: trait-category-height + maxTraitPoints: 1 \ No newline at end of file diff --git a/Resources/Prototypes/ADT/Traits/neutral.yml b/Resources/Prototypes/ADT/Traits/neutral.yml new file mode 100644 index 00000000000..f9960732ed8 --- /dev/null +++ b/Resources/Prototypes/ADT/Traits/neutral.yml @@ -0,0 +1,31 @@ +- type: trait + id: Tall + name: trait-tall-name + description: trait-tall-desc + category: Height + cost: 1 + whitelist: + components: + - SizeAttributeWhitelist + blacklist: + components: + - SizeAttribute + components: + - type: SizeAttribute + tall: true + +- type: trait + id: Short + name: trait-short-name + description: trait-short-desc + category: Height + cost: 1 + whitelist: + components: + - SizeAttributeWhitelist + blacklist: + components: + - SizeAttribute + components: + - type: SizeAttribute + short: true \ No newline at end of file