From 202e80693db71a7edb49bc749cba16a6b37fa346 Mon Sep 17 00:00:00 2001 From: banumbas Date: Mon, 7 Apr 2025 13:33:56 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D1=81=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=81=20=D0=BF=D0=BE=D0=BB=D0=B8=D0=BC=D0=BE=D1=80?= =?UTF-8?q?=D1=84=D0=BE=D0=BC.=20(#1668)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RandomHumanoidAppearanceComponent.cs | 24 +++++- .../Systems/RandomHumanoidAppearanceSystem.cs | 36 ++++++++- .../Polymorph/Systems/PolymorphSystem.cs | 12 +++ .../Polymorph/PolymorphPrototype.cs | 8 ++ .../_Sunrise/Entities/Mobs/NPCs/animals.yml | 14 ++-- .../_Sunrise/Entities/Mobs/Player/felinid.yml | 4 + .../Mobs/Player/randomization-race.yml | 73 ++++++++++++++++++ .../Objects/Specific/rehydrateable.yml | 2 +- .../_Sunrise/Polymorphs/polymorph.yml | 26 ++++--- .../Prototypes/_Sunrise/Reagents/medicine.yml | 67 ---------------- .../Prototypes/_Sunrise/Reagents/special.yml | 67 ++++++++++++++++ .../inferior_vulpkanin.png | Bin 1580 -> 3049 bytes 12 files changed, 247 insertions(+), 86 deletions(-) create mode 100644 Resources/Prototypes/_Sunrise/Entities/Mobs/Player/randomization-race.yml create mode 100644 Resources/Prototypes/_Sunrise/Reagents/special.yml diff --git a/Content.Server/Humanoid/Components/RandomHumanoidAppearanceComponent.cs b/Content.Server/Humanoid/Components/RandomHumanoidAppearanceComponent.cs index 5efea024f4..3c46359073 100644 --- a/Content.Server/Humanoid/Components/RandomHumanoidAppearanceComponent.cs +++ b/Content.Server/Humanoid/Components/RandomHumanoidAppearanceComponent.cs @@ -1,5 +1,6 @@ using Content.Shared.Humanoid.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set; +using Content.Shared.Humanoid.Markings; // Sunrise-Edit namespace Content.Server.CharacterAppearance.Components; @@ -7,8 +8,29 @@ namespace Content.Server.CharacterAppearance.Components; public sealed partial class RandomHumanoidAppearanceComponent : Component { [DataField("randomizeName")] public bool RandomizeName = true; + /// /// After randomizing, sets the hair style to this, if possible /// [DataField] public string? Hair = null; -} + + // Sunrise-Start + /// + /// Настраивает цвет кожи в HEX формате. Учитывайте что только бежевые и темные цвета могут подойти человекоподобным. Советую подбирать цвет прям в игре. + /// + [DataField] + public Color? SkinColor = null; + + /// + /// Настраивает цвет волос в HEX формате + /// + [DataField] + public Color? HairColor = null; + + /// + /// Настраивает цвет бороды в HEX формате + /// + [DataField] + public Color? FacialHairColor = null; + // Sunrise-End +} \ No newline at end of file diff --git a/Content.Server/Humanoid/Systems/RandomHumanoidAppearanceSystem.cs b/Content.Server/Humanoid/Systems/RandomHumanoidAppearanceSystem.cs index 2822fb69e1..1fbd02b00c 100644 --- a/Content.Server/Humanoid/Systems/RandomHumanoidAppearanceSystem.cs +++ b/Content.Server/Humanoid/Systems/RandomHumanoidAppearanceSystem.cs @@ -1,6 +1,7 @@ using Content.Server.CharacterAppearance.Components; using Content.Shared.Humanoid; using Content.Shared.Preferences; +using Content.Shared.Humanoid.Markings; // Sunrise-Edit namespace Content.Server.Humanoid.Systems; @@ -33,5 +34,38 @@ public sealed class RandomHumanoidAppearanceSystem : EntitySystem if (component.RandomizeName) _metaData.SetEntityName(uid, profile.Name); + + // Sunrise-Start + if (TryComp(uid, out var humanoidAppearance)) + { + if (component.SkinColor != null) + _humanoid.SetSkinColor(uid, component.SkinColor.Value, humanoid: humanoidAppearance); + + if (component.HairColor != null) + SetMarkingColor(uid, MarkingCategories.Hair, component.HairColor.Value, humanoidAppearance); + + if (component.FacialHairColor != null) // Да, цвет бороды, йоу. + SetMarkingColor(uid, MarkingCategories.FacialHair, component.FacialHairColor.Value, humanoidAppearance); + } + // Sunrise-End } -} + + // Sunrise-Start + private void SetMarkingColor(EntityUid uid, MarkingCategories category, Color color, + HumanoidAppearanceComponent humanoid) + { + if (!humanoid.MarkingSet.Markings.TryGetValue(category, out var markings)) + return; + + foreach (var marking in markings) + { + for (var i = 0; i < marking.MarkingColors.Count; i++) + { + marking.SetColor(i, color); + } + } + + Dirty(uid, humanoid); + } + // Sunrise-End +} \ No newline at end of file diff --git a/Content.Server/Polymorph/Systems/PolymorphSystem.cs b/Content.Server/Polymorph/Systems/PolymorphSystem.cs index e305109ad5..0f94f70f67 100644 --- a/Content.Server/Polymorph/Systems/PolymorphSystem.cs +++ b/Content.Server/Polymorph/Systems/PolymorphSystem.cs @@ -22,6 +22,10 @@ using Robust.Shared.Map; using Robust.Shared.Prototypes; using Robust.Shared.Timing; using Robust.Shared.Utility; +// Sunrise-Start +using Content.Shared.EntityEffects; +using Content.Shared.Mind.Components; +// Sunrise-End namespace Content.Server.Polymorph.Systems; @@ -183,6 +187,14 @@ public sealed partial class PolymorphSystem : EntitySystem /// public EntityUid? PolymorphEntity(EntityUid uid, PolymorphConfiguration configuration) { + // Sunrise-Start + if (configuration.BlockIfHasMind + && TryComp(uid, out var mindContainer) + && mindContainer.HasMind) + { + return null; + } + // Sunrise-End // if it's already morphed, don't allow it again with this condition active. if (!configuration.AllowRepeatedMorphs && HasComp(uid)) return null; diff --git a/Content.Shared/Polymorph/PolymorphPrototype.cs b/Content.Shared/Polymorph/PolymorphPrototype.cs index 07901b1857..812d016f51 100644 --- a/Content.Shared/Polymorph/PolymorphPrototype.cs +++ b/Content.Shared/Polymorph/PolymorphPrototype.cs @@ -140,6 +140,14 @@ public sealed partial record PolymorphConfiguration /// [DataField] public LocId? ExitPolymorphPopup = "polymorph-revert-popup-generic"; + + // Sunrise-Start + /// + /// Если true, полиморф будет заблокирован для сущностей с MindContainerComponent.HasMind + /// + [DataField(serverOnly: false)] + public bool BlockIfHasMind = false; + // Sunrise-End } public enum PolymorphInventoryChange : byte diff --git a/Resources/Prototypes/_Sunrise/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/_Sunrise/Entities/Mobs/NPCs/animals.yml index f21b2abd15..c56d88d59b 100644 --- a/Resources/Prototypes/_Sunrise/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/_Sunrise/Entities/Mobs/NPCs/animals.yml @@ -21,16 +21,16 @@ group: InferiorVulpkanin - type: LizardAccent - type: ReplacementAccent - accent: kobold + accent: dog - type: Speech - speechSounds: Lizard - speechVerb: Reptilian - allowedEmotes: ['Thump'] + speechSounds: Vulpkanin + speechVerb: Vulpkanin + allowedEmotes: ['Growl', 'Bark', 'Howl', 'Whines'] - type: Vocal sounds: - Male: MaleReptilian - Female: FemaleReptilian - Unsexed: MaleReptilian + Male: MaleVulpkanin + Female: FemaleVulpkanin + Unsexed: MaleVulpkanin - type: BodyEmotes soundsId: ReptilianBodyEmotes - type: TypingIndicator diff --git a/Resources/Prototypes/_Sunrise/Entities/Mobs/Player/felinid.yml b/Resources/Prototypes/_Sunrise/Entities/Mobs/Player/felinid.yml index f1fbc9e22f..ca691ed719 100644 --- a/Resources/Prototypes/_Sunrise/Entities/Mobs/Player/felinid.yml +++ b/Resources/Prototypes/_Sunrise/Entities/Mobs/Player/felinid.yml @@ -12,6 +12,10 @@ components: - type: RandomHumanoidAppearance randomizeName: false + hair: HumanHairBigafro + skinColor: "#331500FF" + hairColor: "#331500FF" + facialHairColor: "#331500FF" #На случай если вдруг появится борода. - type: NpcFactionMember factions: - Syndicate diff --git a/Resources/Prototypes/_Sunrise/Entities/Mobs/Player/randomization-race.yml b/Resources/Prototypes/_Sunrise/Entities/Mobs/Player/randomization-race.yml new file mode 100644 index 0000000000..58d94d41f6 --- /dev/null +++ b/Resources/Prototypes/_Sunrise/Entities/Mobs/Player/randomization-race.yml @@ -0,0 +1,73 @@ +- type: entity + parent: MobHuman + id: MobHumanRandomization + categories: [ HideSpawnMenu ] + components: + - type: RandomHumanoidAppearance + randomizeName: false + skinColor: "#E5BDA0FF" + +- type: entity + parent: MobReptilian + id: MobReptilianRandomization + categories: [ HideSpawnMenu ] + components: + - type: RandomHumanoidAppearance + randomizeName: false + +- type: entity + parent: MobTajaran + id: MobTajaranRandomization + categories: [ HideSpawnMenu ] + components: + - type: RandomHumanoidAppearance + randomizeName: false + +- type: entity + parent: MobSlimePerson + id: MobSlimePersonRandomization + categories: [ HideSpawnMenu ] + components: + - type: RandomHumanoidAppearance + randomizeName: false + +- type: entity + parent: MobMoth + id: MobMothRandomization + categories: [ HideSpawnMenu ] + components: + - type: RandomHumanoidAppearance + randomizeName: false + +- type: entity + parent: MobSwine + id: MobSwineRandomization + categories: [ HideSpawnMenu ] + components: + - type: RandomHumanoidAppearance + randomizeName: false + +- type: entity + parent: MobVox + id: MobVoxRandomization + categories: [ HideSpawnMenu ] + components: + - type: RandomHumanoidAppearance + randomizeName: false + +- type: entity + parent: MobVulpkanin + id: MobVulpkaninRandomization + categories: [ HideSpawnMenu ] + components: + - type: RandomHumanoidAppearance + randomizeName: false + +- type: entity + parent: MobFelinid + id: MobFelinidRandomization + categories: [ HideSpawnMenu ] + components: + - type: RandomHumanoidAppearance + randomizeName: false + skinColor: "#E5BDA0FF" \ No newline at end of file diff --git a/Resources/Prototypes/_Sunrise/Entities/Objects/Specific/rehydrateable.yml b/Resources/Prototypes/_Sunrise/Entities/Objects/Specific/rehydrateable.yml index 320aa4695f..719226b6f0 100644 --- a/Resources/Prototypes/_Sunrise/Entities/Objects/Specific/rehydrateable.yml +++ b/Resources/Prototypes/_Sunrise/Entities/Objects/Specific/rehydrateable.yml @@ -41,4 +41,4 @@ components: - type: Rehydratable possibleSpawns: - - MobFelinid \ No newline at end of file + - MobFelinidRandomization \ No newline at end of file diff --git a/Resources/Prototypes/_Sunrise/Polymorphs/polymorph.yml b/Resources/Prototypes/_Sunrise/Polymorphs/polymorph.yml index 4aa9a5a287..121bcce02d 100644 --- a/Resources/Prototypes/_Sunrise/Polymorphs/polymorph.yml +++ b/Resources/Prototypes/_Sunrise/Polymorphs/polymorph.yml @@ -11,81 +11,89 @@ - type: polymorph id: PermanentlyHuman configuration: - entity: MobHuman + entity: MobHumanRandomization forced: true transferName: true inventory: Transfer revertOnCrit: false revertOnDeath: false + blockIfHasMind: true - type: polymorph id: PermanentlyReptilian configuration: - entity: MobReptilian + entity: MobReptilianRandomization forced: true transferName: true inventory: Transfer revertOnCrit: false revertOnDeath: false + blockIfHasMind: true - type: polymorph id: PermanentlyTajaran configuration: - entity: MobTajaran + entity: MobTajaranRandomization forced: true transferName: true inventory: Transfer revertOnCrit: false revertOnDeath: false allowRepeatedMorphs: true + blockIfHasMind: true - type: polymorph id: PermanentlySlime configuration: - entity: MobSlimePerson + entity: MobSlimePersonRandomization forced: true transferName: true revertOnCrit: false revertOnDeath: false + blockIfHasMind: true - type: polymorph id: PermanentlyMoth configuration: - entity: MobMoth + entity: MobMothRandomization forced: true transferName: true inventory: Transfer revertOnCrit: false revertOnDeath: false + blockIfHasMind: true - type: polymorph id: PermanentlySwine configuration: - entity: MobSwine + entity: MobSwineRandomization forced: true transferName: true inventory: Transfer revertOnCrit: false revertOnDeath: false + blockIfHasMind: true - type: polymorph id: PermanentlyVox configuration: - entity: MobVox + entity: MobVoxRandomization forced: true transferName: true revertOnCrit: false revertOnDeath: false + blockIfHasMind: true - type: polymorph id: PermanentlyVulpkanin configuration: - entity: MobVulpkanin + entity: MobVulpkaninRandomization forced: true - transferName: true + transferName: true inventory: Transfer revertOnCrit: false revertOnDeath: false + blockIfHasMind: true # TODO: Генетика #- type: polymorph diff --git a/Resources/Prototypes/_Sunrise/Reagents/medicine.yml b/Resources/Prototypes/_Sunrise/Reagents/medicine.yml index 75f36469b2..e69de29bb2 100644 --- a/Resources/Prototypes/_Sunrise/Reagents/medicine.yml +++ b/Resources/Prototypes/_Sunrise/Reagents/medicine.yml @@ -1,67 +0,0 @@ -- type: reagent - id: Darvinium - name: reagent-name-darvinium - group: Medicine - desc: reagent-desc-darvinium - physicalDesc: reagent-physical-desc-glowing - color: "#59b23a" - metabolisms: - Medicine: - metabolismRate: 250 - effects: - - !type:Polymorph - prototype: PermanentlyHuman - conditions: - - !type:OrganType - type: Primate - - !type:ReagentThreshold - min: 5 - - !type:Polymorph - prototype: PermanentlyReptilian - conditions: - - !type:OrganType - type: Kobold - - !type:ReagentThreshold - min: 5 - - !type:Polymorph - prototype: PermanentlyTajaran - conditions: - - !type:OrganType - type: Felinid - - !type:ReagentThreshold - min: 5 - - !type:Polymorph - prototype: PermanentlySlime - conditions: - - !type:OrganType - type: WildSlime - - !type:ReagentThreshold - min: 5 - - !type:Polymorph - prototype: PermanentlyMoth - conditions: - - !type:OrganType - type: Mothroach - - !type:ReagentThreshold - min: 5 - - !type:Polymorph - prototype: PermanentlySwine - conditions: - - !type:OrganType - type: Pig - - !type:ReagentThreshold - min: 5 - - !type:Polymorph - prototype: PermanentlyVox - conditions: - - !type:OrganType - type: Chiken - - !type:ReagentThreshold - min: 5 - - !type:Polymorph - prototype: PermanentlyVulpkanin - conditions: - - !type:OrganType - type: InferiorVulpkanin - - !type:ReagentThreshold - min: 5 \ No newline at end of file diff --git a/Resources/Prototypes/_Sunrise/Reagents/special.yml b/Resources/Prototypes/_Sunrise/Reagents/special.yml new file mode 100644 index 0000000000..f4ccbbc6c0 --- /dev/null +++ b/Resources/Prototypes/_Sunrise/Reagents/special.yml @@ -0,0 +1,67 @@ +- type: reagent + id: Darvinium + name: reagent-name-darvinium + group: Special + desc: reagent-desc-darvinium + physicalDesc: reagent-physical-desc-glowing + color: "#59b23a" + metabolisms: + Medicine: + metabolismRate: 250 + effects: + - !type:Polymorph + prototype: PermanentlyHuman + conditions: + - !type:OrganType + type: Primate + - !type:ReagentThreshold + min: 5 + - !type:Polymorph + prototype: PermanentlyReptilian + conditions: + - !type:OrganType + type: Kobold + - !type:ReagentThreshold + min: 5 + - !type:Polymorph + prototype: PermanentlyTajaran + conditions: + - !type:OrganType + type: Felinid + - !type:ReagentThreshold + min: 5 + - !type:Polymorph + prototype: PermanentlySlime + conditions: + - !type:OrganType + type: WildSlime + - !type:ReagentThreshold + min: 5 + - !type:Polymorph + prototype: PermanentlyMoth + conditions: + - !type:OrganType + type: Mothroach + - !type:ReagentThreshold + min: 5 + - !type:Polymorph + prototype: PermanentlySwine + conditions: + - !type:OrganType + type: Pig + - !type:ReagentThreshold + min: 5 + - !type:Polymorph + prototype: PermanentlyVox + conditions: + - !type:OrganType + type: Chiken + - !type:ReagentThreshold + min: 5 + - !type:Polymorph + prototype: PermanentlyVulpkanin + conditions: + - !type:OrganType + type: InferiorVulpkanin + - !type:ReagentThreshold + min: 5 \ No newline at end of file diff --git a/Resources/Textures/_Sunrise/Mobs/Animals/inferior_vulpkanin.rsi/inferior_vulpkanin.png b/Resources/Textures/_Sunrise/Mobs/Animals/inferior_vulpkanin.rsi/inferior_vulpkanin.png index a198b4cbb129335127f61cccb61b063083a23304..bc396fff3ce190fe0c9e65b79eb3c1663079641b 100644 GIT binary patch delta 3031 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 B1Q!4R