Skip to content

Commit

Permalink
Trait Points (#434)
Browse files Browse the repository at this point in the history
# Description

Some improvements to loadouts too.

---

# TODO

- [x] Points logic
- [x] Server-side validation
- [x] Categorize traits
- [x] Assign points to traits
- [x] Header costs
- [x] Sort entries
- [x] Max traits
	- [x] Communicate max traits
- [x] Point bar
- [x] Group exclusivity
- Black outline on text
- [x] Fix existing component whitelists

---

<details><summary><h1>Media</h1></summary>
<p>

## Accurate except for small details


![image](https://github.com/Simple-Station/Einstein-Engines/assets/77995199/c0ab2fbf-3bce-4e54-81d5-8e546d6b3c0b)

### Something to note:


![image](https://github.com/Simple-Station/Einstein-Engines/assets/77995199/09a3948e-0c9f-4f57-b297-f62063b11845)


![image](https://github.com/Simple-Station/Einstein-Engines/assets/77995199/35d76095-0714-4613-a17b-73df25a9a832)


![image](https://github.com/Simple-Station/Einstein-Engines/assets/77995199/87149e5c-0af2-4ac0-bbde-52f317a008a0)

</p>
</details>

---

# Changelog

:cl:
- add: Added trait points
- add: Added categories for traits

---------

Co-authored-by: VMSolidus <[email protected]>
  • Loading branch information
DEATHB4DEFEAT and VMSolidus authored Jun 20, 2024
1 parent 2961bf4 commit d3ed34f
Show file tree
Hide file tree
Showing 60 changed files with 1,621 additions and 960 deletions.
21 changes: 16 additions & 5 deletions Content.Client/Preferences/UI/HumanoidProfileEditor.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -142,18 +142,29 @@
<BoxContainer Name="CAntagList" Orientation="Vertical" />
</ScrollContainer>
</BoxContainer>
<BoxContainer Orientation="Vertical" Margin="10">
<BoxContainer Name="CTraitsTab" Orientation="Vertical" Margin="10">
<!-- Traits -->
<ScrollContainer VerticalExpand="True">
<BoxContainer Name="CTraitsList" Orientation="Vertical" />
</ScrollContainer>
<Label Name="TraitPointsLabel" HorizontalAlignment="Stretch" Align="Center" />
<ProgressBar Name="TraitPointsBar" MaxValue="1" Value="1" MaxHeight="8" Margin="0 5" />

<Button Name="TraitsShowUnusableButton"
Text="{Loc 'humanoid-profile-editor-traits-show-unusable-button'}"
ToolTip="{Loc 'humanoid-profile-editor-traits-show-unusable-button-tooltip'}"
ToggleMode="True"
Margin="0 0 0 5" />

<TabContainer Name="CTraitsTabs" VerticalExpand="True" />
</BoxContainer>
<BoxContainer Name="CLoadoutsTab" Orientation="Vertical" Margin="10">
<!-- Loadouts -->
<Label Name="LoadoutPointsLabel" HorizontalAlignment="Stretch" Align="Center" />
<ProgressBar Name="LoadoutPointsBar" MaxValue="1" Value="1" MaxHeight="8" Margin="0 5" />

<Button Name="CHideShowUnusableButton" Text="{Loc 'humanoid-profile-editor-loadouts-show-unusable-button'}" ToolTip="{Loc 'humanoid-profile-editor-loadouts-show-unusable-button-tooltip'}" ToggleMode="True" Margin="0 0 0 5" />
<Button Name="LoadoutsShowUnusableButton"
Text="{Loc 'humanoid-profile-editor-loadouts-show-unusable-button'}"
ToolTip="{Loc 'humanoid-profile-editor-loadouts-show-unusable-button-tooltip'}"
ToggleMode="True"
Margin="0 0 0 5" />

<TabContainer Name="CLoadoutsTabs" VerticalExpand="True" />
</BoxContainer>
Expand Down
555 changes: 440 additions & 115 deletions Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion Content.Client/Traits/ParacusiaSystem.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using System.Numerics;
using Content.Shared.Traits.Assorted;
using Content.Shared.Traits.Assorted.Systems;
using Robust.Shared.Random;
using Robust.Client.Player;
using Robust.Shared.Player;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Timing;
using Content.Shared.Traits.Assorted.Components;

namespace Content.Client.Traits;

Expand Down
2 changes: 1 addition & 1 deletion Content.Server/Flash/FlashSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
using Content.Shared.Inventory;
using Content.Shared.Physics;
using Content.Shared.Tag;
using Content.Shared.Traits.Assorted;
using Content.Shared.Weapons.Melee.Events;
using Robust.Server.Audio;
using Robust.Server.GameObjects;
using Robust.Shared.Audio;
using Robust.Shared.Timing;
using InventoryComponent = Content.Shared.Inventory.InventoryComponent;
using Content.Shared.Traits.Assorted.Components;

namespace Content.Server.Flash
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Content.Server.StationEvents.Components;
using Content.Server.Traits.Assorted;
using Content.Shared.Mind.Components;
using Content.Shared.Traits.Assorted;
using Content.Shared.Traits.Assorted.Components;

namespace Content.Server.StationEvents.Events;

Expand Down
2 changes: 2 additions & 0 deletions Content.Server/Traits/Assorted/ParacusiaSystem.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Content.Shared.Traits.Assorted;
using Content.Shared.Traits.Assorted.Systems;
using Robust.Shared.Audio;
using Content.Shared.Traits.Assorted.Components;

namespace Content.Server.Traits.Assorted;

Expand Down
40 changes: 19 additions & 21 deletions Content.Server/Traits/TraitSystem.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
using System.Linq;
using Content.Server.GameTicking;
using Content.Server.Players.PlayTimeTracking;
using Content.Shared.Customization.Systems;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Roles;
using Content.Shared.Traits;
using Pidgin.Configuration;
using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager;

namespace Content.Server.Traits;

public sealed class TraitSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly ISerializationManager _serializationManager = default!;
[Dependency] private readonly SharedHandsSystem _sharedHandsSystem = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly ISerializationManager _serialization = default!;
[Dependency] private readonly SharedHandsSystem _hands = default!;
[Dependency] private readonly CharacterRequirementsSystem _characterRequirements = default!;
[Dependency] private readonly PlayTimeTrackingManager _playTimeTracking = default!;
[Dependency] private readonly IConfigurationManager _configuration = default!;

public override void Initialize()
{
Expand All @@ -25,16 +34,17 @@ private void OnPlayerSpawnComplete(PlayerSpawnCompleteEvent args)
{
foreach (var traitId in args.Profile.TraitPreferences)
{
if (!_prototypeManager.TryIndex<TraitPrototype>(traitId, out var traitPrototype))
if (!_prototype.TryIndex<TraitPrototype>(traitId, out var traitPrototype))
{
Log.Warning($"No trait found with ID {traitId}!");
return;
}

if (traitPrototype.Whitelist != null && !traitPrototype.Whitelist.IsValid(args.Mob))
continue;

if (traitPrototype.Blacklist != null && traitPrototype.Blacklist.IsValid(args.Mob))
if (!_characterRequirements.CheckRequirementsValid(traitPrototype, traitPrototype.Requirements,
_prototype.Index<JobPrototype>(args.JobId ?? _prototype.EnumeratePrototypes<JobPrototype>().First().ID),
args.Profile, _playTimeTracking.GetTrackerTimes(args.Player),
EntityManager, _prototype, _configuration,
out _))
continue;

// Add all components required by the prototype
Expand All @@ -43,22 +53,10 @@ private void OnPlayerSpawnComplete(PlayerSpawnCompleteEvent args)
if (HasComp(args.Mob, entry.Component.GetType()))
continue;

var comp = (Component) _serializationManager.CreateCopy(entry.Component, notNullableOverride: true);
var comp = (Component) _serialization.CreateCopy(entry.Component, notNullableOverride: true);
comp.Owner = args.Mob;
EntityManager.AddComponent(args.Mob, comp);
}

// Add item required by the trait
if (traitPrototype.TraitGear != null)
{
if (!TryComp(args.Mob, out HandsComponent? handsComponent))
continue;

var coords = Transform(args.Mob).Coordinates;
var inhandEntity = EntityManager.SpawnEntity(traitPrototype.TraitGear, coords);
_sharedHandsSystem.TryPickup(args.Mob, inhandEntity, checkActionBlocker: false,
handsComp: handsComponent);
}
}
}
}
2 changes: 1 addition & 1 deletion Content.Server/Zombies/ZombieSystem.Transform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
using Content.Shared.Weapons.Melee;
using Content.Shared.Zombies;
using Content.Shared.Prying.Components;
using Content.Shared.Traits.Assorted;
using Robust.Shared.Audio.Systems;
using Content.Shared.Traits.Assorted.Components;

namespace Content.Server.Zombies
{
Expand Down
24 changes: 22 additions & 2 deletions Content.Shared/CCVar/CCVars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -341,14 +341,34 @@ public static readonly CVarDef<bool>
public static readonly CVarDef<bool> DebugCoordinatesAdminOnly =
CVarDef.Create("game.debug_coordinates_admin_only", true, CVar.SERVER | CVar.REPLICATED);


/// <summary>
/// Whether to allow characters to select traits.
/// </summary>
public static readonly CVarDef<bool> GameTraitsEnabled =
CVarDef.Create("game.traits_enabled", true, CVar.REPLICATED);

/// <summary>
/// How many traits a character can have at most.
/// </summary>
public static readonly CVarDef<int> GameTraitsMax =
CVarDef.Create("game.traits_max", 5, CVar.REPLICATED);

/// <summary>
/// How many points a character should start with.
/// </summary>
public static readonly CVarDef<int> GameTraitsDefaultPoints =
CVarDef.Create("game.traits_default_points", 5, CVar.REPLICATED);


/// <summary>
/// Whether or not to allow characters to select loadout items.
/// Whether to allow characters to select loadout items.
/// </summary>
public static readonly CVarDef<bool> GameLoadoutsEnabled =
CVarDef.Create("game.loadouts_enabled", true, CVar.REPLICATED);

/// <summary>
/// How many points to give to each player for loadouts.
/// How many points to give to each player for loadouts.
/// </summary>
public static readonly CVarDef<int> GameLoadoutsPoints =
CVarDef.Create("game.loadouts_points", 14, CVar.REPLICATED);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Content.Shared.Clothing.Loadouts.Prototypes;


/// <summary>
/// A prototype defining a valid category for <see cref="LoadoutPrototype"/>s to go into.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using Content.Shared.Clothing.Loadouts.Systems;
using Content.Shared.Customization.Systems;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;

namespace Content.Shared.Clothing.Loadouts.Prototypes;


[Prototype("loadout")]
public sealed class LoadoutPrototype : IPrototype
{
Expand All @@ -17,7 +19,7 @@ public sealed class LoadoutPrototype : IPrototype
/// <summary>
/// Which tab category to put this under
/// </summary>
[DataField(customTypeSerializer:typeof(PrototypeIdSerializer<LoadoutCategoryPrototype>))]
[DataField, ValidatePrototypeId<LoadoutCategoryPrototype>]
public string Category = "Uncategorized";

/// <summary>
Expand All @@ -41,5 +43,5 @@ public sealed class LoadoutPrototype : IPrototype


[DataField]
public List<LoadoutRequirement> Requirements = new();
public List<CharacterRequirement> Requirements = new();
}
Loading

0 comments on commit d3ed34f

Please sign in to comment.