Milira update (#3671)

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
banumbas 2026-01-16 15:41:45 +03:00 committed by GitHub
parent a266f024ec
commit 20f0f5f466
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
48 changed files with 490 additions and 53 deletions

View file

@ -1,35 +0,0 @@
using Content.Shared._Sunrise.Abilities.Milira;
using Content.Shared.Inventory.Events;
using Content.Shared.Tag;
namespace Content.Client._Sunrise.Abilities.Milira;
/// <summary>
/// Клиентская система WingFlight с блокировкой одевания брони при раскрытых крыльях
/// </summary>
public sealed class WingToggleClientSystem : SharedWingFlightSystem
{
[Dependency] private readonly TagSystem _tagSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<WingToggleComponent, IsEquippingAttemptEvent>(OnEquipAttempt);
}
private void OnEquipAttempt(Entity<WingToggleComponent> ent, ref IsEquippingAttemptEvent args)
{
if (!ent.Comp.WingsOpened)
return;
if (ent.Comp.BlockedSlots != null && ent.Comp.BlockedSlots.Contains(args.Slot))
{
if (ent.Comp.AllowedTag != null && _tagSystem.HasTag(args.Equipment, ent.Comp.AllowedTag.Value))
return;
args.Cancel();
}
}
}

View file

@ -34,7 +34,6 @@ public sealed partial class WingToggleSystem : SharedWingFlightSystem
SubscribeLocalEvent<WingToggleComponent, MapInitEvent>(OnWingToggleMapInit);
SubscribeLocalEvent<WingToggleComponent, ComponentShutdown>(OnWingToggleShutdown);
SubscribeLocalEvent<WingToggleComponent, ToggleActionEvent>(OnWingToggleAction);
SubscribeLocalEvent<WingToggleComponent, IsEquippingAttemptEvent>(OnEquipAttempt);
}
private void OnWingToggleMapInit(Entity<WingToggleComponent> ent, ref MapInitEvent args)
@ -68,6 +67,9 @@ public sealed partial class WingToggleSystem : SharedWingFlightSystem
if (!humanoid.MarkingSet.Markings.TryGetValue(MarkingCategories.Tail, out var markings) || markings.Count == 0)
return false;
if (TryComp<WingFlightComponent>(ent, out var wingFlight) && wingFlight.InertiaActive)
return false;
if (!ent.Comp.WingsOpened)
{
if (!CanOpenWings(ent))
@ -125,7 +127,10 @@ public sealed partial class WingToggleSystem : SharedWingFlightSystem
foreach (var slot in ent.Comp.BlockedSlots)
{
if (_inventory.TryGetSlotEntity(ent.Owner, slot, out _))
if (!_inventory.TryGetSlotEntity(ent.Owner, slot, out var equippedEntity))
continue;
if (ent.Comp.AllowedTag == null || !_tagSystem.HasTag(equippedEntity.Value, ent.Comp.AllowedTag.Value))
return false;
}
@ -139,19 +144,4 @@ public sealed partial class WingToggleSystem : SharedWingFlightSystem
_actions.SetToggled(ent.Comp.ActionEntity.Value, ent.Comp.WingsOpened);
}
private void OnEquipAttempt(Entity<WingToggleComponent> ent, ref IsEquippingAttemptEvent args)
{
if (!ent.Comp.WingsOpened)
return;
if (ent.Comp.BlockedSlots != null && ent.Comp.BlockedSlots.Contains(args.Slot))
{
if (ent.Comp.AllowedTag != null && _tagSystem.HasTag(args.Equipment, ent.Comp.AllowedTag.Value))
return;
args.Cancel();
}
}
}

View file

@ -94,7 +94,8 @@ public sealed partial class FleshCultSystem : EntitySystem
"Vox",
"HumanoidXeno",
"Predator",
"Tajaran"
"Tajaran",
"Milira"
];
public override void Initialize()
@ -119,3 +120,4 @@ public sealed partial class FleshCultSystem : EntitySystem
UpdateHeart(frameTime);
}
}

View file

@ -0,0 +1,50 @@
using Content.Shared._Sunrise.Abilities.Milira;
using Content.Shared.Inventory.Events;
using Content.Shared.Tag;
namespace Content.Shared._Sunrise.Abilities.Milira;
/// <summary>
/// Shared система WingFlight с блокировкой одевания брони при раскрытых крыльях
/// </summary>
public sealed class WingToggleSharedSystem : SharedWingFlightSystem
{
[Dependency] private readonly TagSystem _tagSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<WingToggleComponent, IsEquippingAttemptEvent>(OnEquipAttempt);
SubscribeLocalEvent<WingToggleComponent, IsEquippingTargetAttemptEvent>(OnEquipTargetAttempt);
}
private bool ShouldCancelEquip(Entity<WingToggleComponent> ent, string slot, EntityUid equipment)
{
if (!ent.Comp.WingsOpened)
return false;
if (ent.Comp.BlockedSlots != null && ent.Comp.BlockedSlots.Contains(slot))
{
if (ent.Comp.AllowedTag != null && _tagSystem.HasTag(equipment, ent.Comp.AllowedTag.Value))
return false;
return true;
}
return false;
}
private void OnEquipAttempt(Entity<WingToggleComponent> ent, ref IsEquippingAttemptEvent args)
{
if (ShouldCancelEquip(ent, args.Slot, args.Equipment))
args.Cancel();
}
private void OnEquipTargetAttempt(Entity<WingToggleComponent> ent, ref IsEquippingTargetAttemptEvent args)
{
if (ShouldCancelEquip(ent, args.Slot, args.Equipment))
args.Cancel();
}
}

View file

@ -0,0 +1,24 @@
using Content.Shared.Whitelist;
using Robust.Shared.GameStates;
namespace Content.Shared._Sunrise.Inventory.Components;
/// <summary>
/// Ограничивает экипировку на цель при помощи вайтлиста и блеклиста.
/// Если хотите понять как использовать EntityWhitelist посмотрите на другие похожие прототипы.
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class ClothingWhitelistComponent : Component
{
/// <summary>
/// Вайтлист сущностей, которым разрешено экипировать этот предмет.
/// </summary>
[DataField]
public EntityWhitelist? Whitelist;
/// <summary>
/// Блеклист сущностей, которым запрещено экипировать этот предмет.
/// </summary>
[DataField]
public EntityWhitelist? Blacklist;
}

View file

@ -0,0 +1,28 @@
using Content.Shared.Inventory.Events;
using Content.Shared.Whitelist;
using Content.Shared._Sunrise.Inventory.Components;
namespace Content.Shared._Sunrise.Inventory.Systems;
public sealed class ClothingWhitelistSystem : EntitySystem
{
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ClothingWhitelistComponent, BeingEquippedAttemptEvent>(OnEquippedAttempt);
}
private void OnEquippedAttempt(Entity<ClothingWhitelistComponent> ent, ref BeingEquippedAttemptEvent args)
{
if (args.Cancelled)
return;
if (_whitelistSystem.CheckBoth(args.EquipTarget, ent.Comp.Blacklist, ent.Comp.Whitelist))
return;
args.Cancel();
}
}

View file

@ -4,3 +4,5 @@ ent-ClothingEyesHudSyndicateMech = визор МЕХ-пилота синдика
.desc = Профессиональный визор анализирующий в реальном времени состояние МЕХа.
ent-ClothingEyesHudDiagnosticERT = охранно-диагностический визор
.desc = Окуляр с индикатором на стекле, способный анализировать целостность и состояние роботов и экзокостюмов. Так же встроена технология охранного визора.
ent-ClothingEyesHudMilira = визор Милир
.desc = Визор, адаптированный под Милир, и сочетающий в себе преимущества медицинского сканера и защиты от вспышек.

View file

@ -38,3 +38,7 @@ ent-ClothingOuterArmorHeatAbsorb = теплозащитный жилет
.desc = Продвинутый жилет, созданный для поглощения тепла, а не отражения его. При этом обладает частичными отражающими свойствами. Слаб против пуль и ударов из-за хрупкого материала.
ent-ClothingOuterArmorBulletproofHeavy = тяжёлый бронежилет
.desc = Бронежилет типа III с дополнительной защитой плеч и ног. Отлично защищает от традиционного стрелкового оружия и частично снижает урон от взрывов.
ent-ClothingOuterArmorMiliraHeavy = тяжёлая броня Милир
.desc = Тяжёлая броня, разработанная специально для Милир, усиливает защиту и позволяет дольше держаться в воздухе.
ent-ClothingOuterArmorMiliraLight = лёгкая броня Милир
.desc = Облегчённая броня для Милир, чуть усиливающая защиту и позволяет дольше держаться в воздухе.

View file

@ -39,6 +39,8 @@ ent-ClothingOuterHardsuitPrivateerArmored = бронескафандр фрил
.suffix = Pirate
ent-ClothingOuterHardsuitChameleon = синдикатовский хамелеон
.desc = Глядя на его материалы, в голове невольно всплывают образы из области научной фантастики.
ent-ClothingOuterHardsuitMilira = скафандр Милир
.desc = Скафандр, созданный специально для Милир, даёт защиту и позволяет дольше находиться в полёте.
ent-ClothingOuterHardsuitInfiltration = скафандр инфильтратора
.desc = Усиленный скафандр Синдиката, созданный для скрытных операций. Совмещает защиту и активную маскировку.
ent-ClothingOuterHardsuitSalvageGoliath = шахтёрский скафандр «Голиаф»

View file

@ -89,3 +89,4 @@ research-technology-advanced-spray = Продвинутые спреи
research-technology-quantum-fiber-weaving = Плетение квантового волокна
research-technology-bluespace-cargo-transport = Блюспейс-транспортировка грузов
research-technology-advance-secborgs-combat = Продвинутые боевые модули СБ боргов
research-technology-milira-equipment = Снаряжение Милир

View file

@ -78,6 +78,7 @@
- HumanoidXeno
- Predator
- Resomi
- Milira
randomizeName: false
components:
- type: GhostRole
@ -139,6 +140,7 @@
- HumanoidXeno
- Predator
- Resomi
- Milira
randomizeName: false
components:
- type: GhostRole
@ -187,6 +189,7 @@
- HumanoidXeno
- Predator
- Resomi
- Milira
parent: ERTLeader
components:
- type: GhostRole
@ -227,6 +230,7 @@
- HumanoidXeno
- Predator
- Resomi
- Milira
components:
- type: GhostRole
name: ghost-role-information-ert-leader-name
@ -276,6 +280,7 @@
- HumanoidXeno
- Predator
- Resomi
- Milira
parent: ERTLeader
components:
- type: BibleUser
@ -325,6 +330,7 @@
- HumanoidXeno
- Predator
- Resomi
- Milira
parent: ERTChaplain
components:
- type: GhostRole
@ -376,6 +382,7 @@
- HumanoidXeno
- Predator
- Resomi
- Milira
parent: ERTLeader
components:
- type: GhostRole
@ -424,6 +431,7 @@
- HumanoidXeno
- Predator
- Resomi
- Milira
parent: ERTJanitor
components:
- type: GhostRole
@ -474,6 +482,7 @@
- HumanoidXeno
- Predator
- Resomi
- Milira
parent: ERTLeader
components:
- type: GhostRole
@ -522,6 +531,7 @@
- HumanoidXeno
- Predator
- Resomi
- Milira
parent: ERTEngineer
components:
- type: GhostRole
@ -572,6 +582,7 @@
- HumanoidXeno
- Predator
- Resomi
- Milira
parent: ERTLeader
components:
- type: GhostRole
@ -620,6 +631,7 @@
- HumanoidXeno
- Predator
- Resomi
- Milira
parent: ERTSecurity
components:
- type: GhostRole
@ -659,6 +671,7 @@
- HumanoidXeno
- Predator
- Resomi
- Milira
parent: ERTSecurityEVA
components:
- type: GhostRole
@ -709,6 +722,7 @@
- HumanoidXeno
- Predator
- Resomi
- Milira
parent: ERTLeader
components:
- type: GhostRole
@ -757,6 +771,7 @@
- HumanoidXeno
- Predator
- Resomi
- Milira
parent: ERTMedical
components:
- type: GhostRole
@ -802,6 +817,7 @@
- HumanoidXeno
- Predator
- Resomi
- Milira
components:
- type: Loadout
prototypes: [CBURNGear]
@ -877,6 +893,7 @@
- Felinid
- HumanoidXeno
- Predator
- Milira
components:
- type: RandomHumanoidAppearance
randomizeName: false
@ -902,6 +919,7 @@
- Felinid
- HumanoidXeno
- Predator
- Milira
components:
- type: RandomHumanoidAppearance
randomizeName: false

View file

@ -46,3 +46,22 @@
- Inorganic
- Silicon
- Mech
- type: entity
parent: [ClothingEyesBase, ShowMedicalIcons]
id: ClothingEyesHudMilira
name: milira hud
description: A heads-up display that combines the advantages of a medical scanner.
components:
- type: Sprite
sprite: _Sunrise/Clothing/Eyes/Hud/milira_hud.rsi
- type: Clothing
sprite: _Sunrise/Clothing/Eyes/Hud/milira_hud.rsi
- type: FlashImmunity
- type: ClothingWhitelist
whitelist:
tags:
- Milira
- type: Tag
tags:
- HudMedical

View file

@ -524,3 +524,25 @@
Blunt: 0.8
Slash: 0.8
Piercing: 0.8
# Milira
- type: entity
parent: ClothingHeadEVAHelmetBase
id: ClothingHeadHelmetHardsuitMilira
name: milira hardsuit helmet
description: A hardsuit helmet for Milira species.
components:
- type: Sprite
sprite: _Sunrise/Clothing/Head/Hardsuits/milira_helmet.rsi
- type: Clothing
sprite: _Sunrise/Clothing/Head/Hardsuits/milira_helmet.rsi
- type: PressureProtection
highPressureMultiplier: 0.45
lowPressureMultiplier: 1000
- type: Armor
modifiers:
coefficients:
Blunt: 0.9
Slash: 0.9
Piercing: 0.9

View file

@ -474,3 +474,70 @@
- type: Construction
graph: UpgradeArmorVest
node: bullet_heavy
# Milira
- type: entity
parent: ClothingOuterArmorBase
id: ClothingOuterArmorMiliraHeavy
name: milira armor heavy
description: Heavy armor for Milir, extending flight and providing protection.
components:
- type: Sprite
sprite: _Sunrise/Clothing/OuterClothing/Armor/Milira/heavy.rsi
- type: Clothing
sprite: _Sunrise/Clothing/OuterClothing/Armor/Milira/heavy.rsi
- type: ClothingWhitelist
whitelist:
tags:
- Milira
- type: Tag
tags:
- WingToggleAllowed
- type: Pierceable
level: Metal
- type: Armor
modifiers:
coefficients:
Blunt: 0.6
Slash: 0.7
Piercing: 0.6
Heat: 0.7
- type: ExplosionResistance
damageCoefficient: 0.75
- type: StaminaResistance
damageCoefficient: 0.7
- type: ClothingSpeedModifier
walkModifier: 0.85
sprintModifier: 0.85
- type: entity
parent: ClothingOuterArmorBase
id: ClothingOuterArmorMiliraLight
name: milira armor light
description: Light armor for Milir, extending flight and providing weak protection.
components:
- type: Sprite
sprite: _Sunrise/Clothing/OuterClothing/Armor/Milira/light.rsi
- type: Clothing
sprite: _Sunrise/Clothing/OuterClothing/Armor/Milira/light.rsi
- type: ClothingWhitelist
whitelist:
tags:
- Milira
- type: Tag
tags:
- WingToggleAllowed
- type: Pierceable
level: Metal
- type: Armor
modifiers:
coefficients:
Blunt: 0.65
Slash: 0.7
Piercing: 0.7
Heat: 0.7
- type: StaminaResistance
damageCoefficient: 0.7
- type: ExplosionResistance
damageCoefficient: 0.75

View file

@ -643,6 +643,43 @@
- Hardsuit
- WhitelistChameleon
# Milira
- type: entity
parent: ClothingOuterHardsuitBase
id: ClothingOuterHardsuitMilira
name: milira hardsuit
description: Hardsuit for Milir, extending flight and provides weak protection.
components:
- type: Sprite
sprite: _Sunrise/Clothing/OuterClothing/Hardsuits/milira_hardsuit.rsi
- type: Clothing
sprite: _Sunrise/Clothing/OuterClothing/Hardsuits/milira_hardsuit.rsi
- type: ExplosionResistance
damageCoefficient: 0.7
- type: StaminaResistance
damageCoefficient: 0.7
- type: Pierceable
level: Metal
- type: Armor
modifiers:
coefficients:
Blunt: 0.6
Slash: 0.6
Piercing: 0.7
Heat: 0.6
- type: ClothingSpeedModifier
walkModifier: 0.85
sprintModifier: 0.85
- type: ToggleableClothing
clothingPrototype: ClothingHeadHelmetHardsuitMilira
- type: ClothingWhitelist
whitelist:
tags:
- Milira
- type: Tag
tags:
- WingToggleAllowed
#Modsuits
#Modsuit parent
- type: entity

View file

@ -65,6 +65,9 @@
damageModifierSet: Milira
- type: FootprintEmitter
- type: Carriable
- type: Tag
tags:
- Milira
- type: entity
save: false

View file

@ -98,6 +98,8 @@
- SpeedLoaderShotgunBeanbag
# PODAVLENIE
- BolaSecurity
# Milira
- ClothingOuterArmorMiliraLight
####################################################
- type: latheRecipePack
@ -327,6 +329,9 @@
- VestSecUpgradeReflective
- VestSecUpgradeWeb
- VestSecUpgradeBulletHeavy
- ClothingOuterArmorMiliraHeavy
- ClothingOuterHardsuitMilira
- ClothingEyesHudMilira
- type: latheRecipePack
id: SecurityDynamicSunriseMech

View file

@ -461,6 +461,55 @@
Plastic: 300
Steel: 300
# Milira equipment
- type: latheRecipe
id: ClothingOuterArmorMiliraLight
result: ClothingOuterArmorMiliraLight
categories:
- Clothing
completetime: 18
materials:
Cloth: 200
Durathread: 100
Plastic: 125
Steel: 400
- type: latheRecipe
id: ClothingOuterArmorMiliraHeavy
result: ClothingOuterArmorMiliraHeavy
categories:
- Clothing
completetime: 24
materials:
Cloth: 250
Durathread: 175
Plastic: 175
Steel: 700
- type: latheRecipe
id: ClothingOuterHardsuitMilira
result: ClothingOuterHardsuitMilira
categories:
- Clothing
completetime: 30
materials:
Steel: 1000
Durathread: 250
Plastic: 250
Glass: 200
- type: latheRecipe
id: ClothingEyesHudMilira
result: ClothingEyesHudMilira
categories:
- Clothing
completetime: 12
materials:
Steel: 200
Glass: 300
Plastic: 150
- type: latheRecipe
parent: BaseWeaponRecipeLong
id: WeaponIonCarbine

View file

@ -196,6 +196,22 @@
radioChannels:
- Security
- type: technology
id: MiliraEquipment
name: research-technology-milira-equipment
icon:
sprite: _Sunrise/Clothing/OuterClothing/Armor/Milira/heavy.rsi
state: icon
discipline: Arsenal
tier: 2
cost: 7500
recipeUnlocks:
- ClothingOuterArmorMiliraHeavy
- ClothingOuterHardsuitMilira
- ClothingEyesHudMilira
radioChannels:
- Security
- type: technology
id: AdvancedLaserManipulation
name: research-technology-advance-laser

View file

@ -584,6 +584,9 @@
- type: Tag
id: SalvageSyndicateBase
- type: Tag
id: Milira
### INTERACTION TAGS ###
# Как одежда закрывает/не закрывает ту или иную область тела
- type: Tag

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 B

View file

@ -0,0 +1,26 @@
{
"version": 1,
"license": "CLA",
"copyright": "© SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "icon"
},
{
"name": "equipped-EYES",
"directions": 4
},
{
"name": "inhand-left",
"directions": 4
},
{
"name": "inhand-right",
"directions": 4
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 808 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 458 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

View file

@ -0,0 +1,26 @@
{
"version": 1,
"license": "CLA",
"copyright": "© SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "icon"
},
{
"name": "equipped-HELMET",
"directions": 4
},
{
"name": "inhand-left",
"directions": 4
},
{
"name": "inhand-right",
"directions": 4
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

View file

@ -0,0 +1,26 @@
{
"version": 1,
"license": "CLA",
"copyright": "© SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "icon"
},
{
"name": "equipped-OUTERCLOTHING",
"directions": 4
},
{
"name": "inhand-left",
"directions": 4
},
{
"name": "inhand-right",
"directions": 4
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 963 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

View file

@ -0,0 +1,26 @@
{
"version": 1,
"license": "CLA",
"copyright": "© SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "icon"
},
{
"name": "equipped-OUTERCLOTHING",
"directions": 4
},
{
"name": "inhand-left",
"directions": 4
},
{
"name": "inhand-right",
"directions": 4
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 686 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 683 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 717 B

View file

@ -0,0 +1,26 @@
{
"version": 1,
"license": "CLA",
"copyright": "© SUNRISE, An EULA/CLA with a hosting restriction, full text: https://github.com/space-sunrise/space-station-14/blob/master/CLA.txt",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "icon"
},
{
"name": "equipped-OUTERCLOTHING",
"directions": 4
},
{
"name": "inhand-left",
"directions": 4
},
{
"name": "inhand-right",
"directions": 4
}
]
}