Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 83 additions & 1 deletion Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,20 @@ public void RefreshTraits()
tooltipParts.Add($"You must not be: {string.Join(", ", names)}");
}

// HardLight: Required traits
if (trait.RequiredTraits.Count > 0)
{
var names = new List<string>();
foreach (var reqId in trait.RequiredTraits)
{
if (_prototypeManager.TryIndex(reqId, out var reqProto))
names.Add($"[color=#FFD700]{Loc.GetString(reqProto.Name)}[/color]");
}
if (names.Count > 0)
tooltipParts.Add($"Requires: {string.Join(", ", names)}");
}
// HardLight end

if (tooltipParts.Count > 0)
selector.SetTooltip(string.Join("\n", tooltipParts));
}
Expand Down Expand Up @@ -828,6 +842,30 @@ public void RefreshTraits()
else
{
Profile = Profile?.WithoutTraitPreference(trait.ID, _prototypeManager);

// HardLight - Cascade deselect: remove any traits that required this one
if (Profile != null)
{
var toRemove = new List<ProtoId<TraitPrototype>>();
foreach (var selectedTraitId in Profile.TraitPreferences)
{
if (!_prototypeManager.TryIndex<TraitPrototype>(selectedTraitId, out var selectedProto))
continue;

if (selectedProto.RequiredTraits.Contains(trait.ID))
toRemove.Add(selectedTraitId);
}

foreach (var removeId in toRemove)
{
Profile = Profile.WithoutTraitPreference(removeId, _prototypeManager);

// Also uncheck the UI selector
if (allSelectors.TryGetValue(removeId, out var depSelector))
depSelector.Preference = false;
}
}
// HardLight end
}

SetDirty();
Expand Down Expand Up @@ -1024,6 +1062,20 @@ private void UpdateTraitIncompatibilityVisibility(Dictionary<ProtoId<TraitProtot
}
}

// HardLight - Hide traits whose required traits are not all selected
if (!hide && thisProto.RequiredTraits.Count > 0)
{
foreach (var requiredId in thisProto.RequiredTraits)
{
if (!selected.Contains(requiredId))
{
hide = true;
break;
}
}
}
// HardLight end

if (!hide)
{
foreach (var sel in selected)
Expand Down Expand Up @@ -1727,6 +1779,36 @@ private void EnforceSpeciesTraitRestrictions()
toRemove.Add(traitId);
}

// HardLight - Also remove traits whose required traits are not selected
// Iterate until stable since removing one trait may cascade
bool changed;
do
{
changed = false;
foreach (var traitId in Profile.TraitPreferences)
{
if (toRemove.Contains(traitId))
continue;

if (!_prototypeManager.TryIndex(traitId, out TraitPrototype? trait))
continue;

if (trait.RequiredTraits.Count == 0)
continue;

foreach (var reqId in trait.RequiredTraits)
{
if (!Profile.TraitPreferences.Contains(reqId) || toRemove.Contains(reqId))
{
toRemove.Add(traitId);
changed = true;
break;
}
}
}
} while (changed);
// HardLight end

foreach (var traitId in toRemove)
{
Profile = Profile.WithoutTraitPreference(traitId, _prototypeManager);
Expand Down Expand Up @@ -2300,4 +2382,4 @@ private void UpdateCompanyControls()
}
}
}
}
}
10 changes: 8 additions & 2 deletions Content.Shared/Traits/TraitPrototype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,17 @@ public sealed partial class TraitPrototype : IPrototype, IComparable<TraitProtot
public ProtoId<TraitCategoryPrototype>? Category;

/// <summary>
/// List of traits that ca't be taken together with this one.
/// List of traits that can't be taken together with this one.
/// </summary>
[DataField]
public HashSet<ProtoId<TraitPrototype>> MutuallyExclusiveTraits { get; private set; } = new();

/// <summary>
/// List of traits that must be selected before this trait becomes available, w/ deselect if its removed
/// </summary>
[DataField]
public HashSet<ProtoId<TraitPrototype>> RequiredTraits { get; private set; } = new();

/// <summary>
/// List of species that can't have this trait.
/// </summary>
Expand Down Expand Up @@ -121,4 +127,4 @@ public int CompareTo(TraitPrototype? other)
if (other == null) return 1;
return Cost.CompareTo(other.Cost);
}
}
}
53 changes: 53 additions & 0 deletions Resources/Locale/en-US/_HL/traits/traits.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,56 @@ hl-trait-egglayer-infertile-desc = You produce eggs very slowly and seldomly (50

pooltoy-name = Pool Toy!
pooltoy-text = You're a living inflatable, whether by some weird mutation or by being a synthetic being. You are quite resillient to blunt and naturally insulated, but are extra susceptible to pierce and slash, and you are easily knocked about by sudden forces!

hl-trait-category-supernatural = Supernatural

hl-trait-vampire-name = Vampire
hl-trait-vampire-desc = You are an undead vampire who can only feed their hunger with blood. You are immune to airloss damage, but are weak to silver.

hl-trait-werewolf-name = Werewolf
hl-trait-werewolf-desc = Exposure to the sun or UV light can transform you into a powerful but mindless creature that attacks everyone in sight. You are also weak to silver.

hl-trait-changeling-name = Changeling
hl-trait-changeling-desc = You are a shapeless creature who can only feed their hunger by absorbing DNA from others. You are weak to silver, but can transform into your victims.

hl-trait-vampire-bat-transformation-name = Bat Transformation
hl-trait-vampire-bat-transformation-desc = You can transform into a bat at the cost of hunger.

hl-trait-vampire-uv-weakness-name = UV Weakness
hl-trait-vampire-uv-weakness-desc = Exposure to the sun or UV lights will burn you.

hl-trait-vampire-light-weakness-name = Light Weakness
hl-trait-vampire-light-weakness-desc = Bright lights will weaken you.

hl-trait-werewolf-transform-name = Transform at Will
hl-trait-werewolf-transform-desc = You can transform yourself at will if you are fully fed.

hl-trait-changeling-armblade-name = Armblade
hl-trait-changeling-armblade-desc = Your arms can turn into blades to slice at others

hl-trait-changeling-armclaw-name = Armclaw
hl-trait-changeling-armclaw-desc = Your arms can turn into claws to stab at others

hl-trait-changeling-armhammer-name = Armhammer
hl-trait-changeling-armhammer-desc = Your arms can turn into a hammer to bludgeon others

hl-trait-changeling-playdead-name = Playdead
hl-trait-changeling-playdead-desc = You can reduce your functions to appear dead, and later revive at will.

hl-trait-changeling-screech-name = EMP Screech
hl-trait-changeling-screech-desc = You can screech out a shockwave that knocks others back and disables nearby electronics

hl-trait-changeling-thermaleyes-name = Thermal Eyes
hl-trait-changeling-thermaleyes-desc = You can see in the dark with toggable thermal vision

hl-trait-changeling-healing-name = Healing Factor
hl-trait-changeling-healing-desc = At the cost of hunger, you can increase your healing factor for brute and toxin damage

hl-trait-changeling-chitin-name = Chitin Armor
hl-trait-changeling-chitin-desc = Your skin is tougher than normal, allowing you to resist brute damage but it takes longer to inject chems in you

hl-trait-changeling-firevurn-name = Fire Vurnability
hl-trait-changeling-firevurn-desc = You take 50% more damage from heat sources

hl-trait-changeling-acidvurn-name = Acid Vurnability
hl-trait-changeling-acidvurn-desc = You take 50% more damage from caustic sources
6 changes: 6 additions & 0 deletions Resources/Prototypes/Traits/categories.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,9 @@
id: Physical
name: trait-category-physical
maxTraitPoints: 10

# Hardlight
- type: traitCategory
id: Supernatural
name: hl-trait-category-supernatural
maxTraitPoints: 1
161 changes: 161 additions & 0 deletions Resources/Prototypes/_HL/Traits/supernatural.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
- type: trait
id: Vampire
name: hl-trait-vampire-name
description: hl-trait-vampire-desc
category: Supernatural
cost: 1
mutuallyExclusiveTraits:
- Changeling
- Werewolf

- type: trait
id: Changeling
name: hl-trait-changeling-name
description: hl-trait-changeling-desc
category: Supernatural
cost: 1
mutuallyExclusiveTraits:
- Vampire
- Werewolf

- type: trait
id: Werewolf
name: hl-trait-werewolf-name
description: hl-trait-werewolf-desc
category: Supernatural
cost: 1
mutuallyExclusiveTraits:
- Vampire
- Changeling

# Vampire Sub-Traits

- type: trait
id: BatTransformation
name: hl-trait-vampire-bat-transformation-name
description: hl-vampire-trait-bat-transformation-desc
category: Supernatural
cost: 5
requiredTraits:
- Vampire

- type: trait
id: UVWeakness
name: hl-trait-vampire-uv-weakness-name
description: hl-trait-vampire-uv-weakness-desc
category: Supernatural
cost: -5
requiredTraits:
- Vampire

- type: trait
id: LightWeakness
name: hl-trait-vampire-light-weakness-name
description: hl-trait-vampire-light-weakness-desc
category: Supernatural
cost: -5
requiredTraits:
- Vampire

# Werewolf Sub-Traits

- type: trait
id: WerewolfTransformAtWill
name: hl-trait-werewolf-transform-name
description: hl-trait-werewolf-transform-desc
category: Supernatural
cost: 5
requiredTraits:
- Werewolf

# Changeling Sub-Traits

- type: trait
id: CLArmblade
name: hl-trait-changeling-armblade-name
description: hl-trait-changeling-armblade-desc
category: Supernatural
cost: 5
requiredTraits:
- Changeling

- type: trait
id: CLArmclaw
name: hl-trait-changeling-armclaw-name
description: hl-trait-changeling-armclaw-desc
category: Supernatural
cost: 5
requiredTraits:
- Changeling

- type: trait
id: CLArmhammer
name: hl-trait-changeling-armhammer-name
description: hl-trait-changeling-armhammer-desc
category: Supernatural
cost: 5
requiredTraits:
- Changeling

- type: trait
id: CLPlaydead
name: hl-trait-changeling-playdead-name
description: hl-trait-changeling-playdead-desc
category: Supernatural
cost: 5
requiredTraits:
- Changeling

- type: trait
id: CLScreech
name: hl-trait-changeling-screech-name
description: hl-trait-changeling-screech-desc
category: Supernatural
cost: 10
requiredTraits:
- Changeling

- type: trait
id: CLThermalEyes
name: hl-trait-changeling-thermaleyes-name
description: hl-trait-changeling-thermaleyes-desc
category: Supernatural
cost: 2
requiredTraits:
- Changeling

- type: trait
id: CLHealingFactor
name: hl-trait-changeling-healing-name
description: hl-trait-changeling-healing-desc
category: Supernatural
cost: 5
requiredTraits:
- Changeling

- type: trait
id: CLChitinArmor
name: hl-trait-changeling-chitin-name
description: hl-trait-changeling-chitin-desc
category: Supernatural
cost: -5
requiredTraits:
- Changeling

- type: trait
id: CLFireVurn
name: hl-trait-changeling-firevurn-name
description: hl-trait-changeling-firevurn-desc
category: Supernatural
cost: -5
requiredTraits:
- Changeling

- type: trait
id: CLAcidVurn
name: hl-trait-changeling-acidvurn-name
description: hl-trait-changeling-acidvurn-desc
category: Supernatural
cost: -5
requiredTraits:
- Changeling
Loading