S&box Wiki

Revision Difference

Clothing#548177

<cat>Code.Player</cat>⤶ <title>Clothing</title>⤶ ⤶ # What is Clothing?⤶ ⤶ s&box ships with pre-made clothing that developers and players alike can use to dress their character (Pawn). You can view some of the available clothing from the main-menu. In some gamemodes, developers may wish to manually set the clothing of players, for example to create a visual distinction between teams. You can do so by loading the clothing via the `ResourceLibrary` system using the clothing's `Resource ID`.⤶ ⤶ # Resource ID's?⤶ ⤶ Resource ID's are how s&box internally holds a reference to clothing, among other assets. You can view a list of available clothing names and resource id's by adding the below console command to your game.⤶ ```csharp⤶ /// <summary>⤶ /// Debug console command to list all available s&box clothing.⤶ /// </summary>⤶ [ConCmd.Admin]⤶ public static void ListAllClothing()⤶ {⤶ foreach (var item in ResourceLibrary.GetAll<Clothing>())⤶ {⤶ Log.Info($"{item.Title} - {item.ResourceId}");⤶ }⤶ }⤶ ```⤶ ⤶ # Dressing Player's⤶ Gamemodes must implement a clothing system in order to prevent naked Pawn's from spawning. You can do so either automatically (using the players selected clothing) or manually (for team based gamemodes, etc). s&box comes with a `ClothingContainer` class that abstracts away the loading of clothes and prevents potential collisions when adding clothes (e.g. two shirts, two shoes, etc.)⤶ ## Automatically⤶ The following code will dress the player in whatever clothing they have selected from the main menu. Note that `Clothing.DressEntity` can dress any Pawn instance, such as NPC's.⤶ ```csharp⤶ `MyPlayer.Clothing.cs`⤶ ⤶ public partial class MyPlayer⤶ {⤶ public ClothingContainer Clothing { get; protected set; }⤶ ⤶ /// <summary>⤶ /// Set the clothes to whatever the player is wearing⤶ /// </summary>⤶ public void UpdateClothes(Client cl)⤶ {⤶ Clothing ??= new();⤶ Clothing.LoadFromClient(cl);⤶ }⤶ }⤶ ```⤶ ```csharp⤶ `MyPlayer.cs`⤶ ⤶ public partial class MyPlayer : Player⤶ {⤶ public override void Respawn()⤶ {⤶ UpdateClothes(Client);⤶ Clothing.DressEntity(this);⤶ }⤶ }⤶ ```⤶ ⤶ ## Manually⤶ You can also manually set player clothing, ignoring what they may have previously configured in the main menu. This is often important for team-based gamemodes.⤶ ```csharp⤶ `MyPlayer.Clothes.cs`⤶ ⤶ public partial class MyPlayer⤶ {⤶ public ClothingContainer Clothing { get; protected set; }⤶ ⤶ private static readonly int[] TeamAClothing =⤶ {⤶ 1846461341, // Police Cap.⤶ -923065548, // Suit Jacket.⤶ 1761917151, // Tactical Vest.⤶ 1194605997, // Smart Trousers.⤶ -1377292782 // Black Boots.⤶ };⤶ ⤶ private static readonly int[] TeamBClothing =⤶ {⤶ -394380878, // Prison Jumpsuit.⤶ 591027714 // Sneakers.⤶ };⤶ ⤶ /// <summary>⤶ /// Set the clothes depending on the players team⤶ /// </summary>⤶ public void UpdateClothes(Client cl)⤶ {⤶ Clothing ??= new ClothingContainer();⤶ ⤶ var player = cl.Pawn as MyPlayer;⤶ ⤶ // Clear out any previously equipped clothing.⤶ Clothing.Clothing.Clear();⤶ ⤶ // NOTE: You could refactor this code into a `GetTeamClothing` method.⤶ if (player.Team == Team.A)⤶ {⤶ foreach (var itemId in TeamAClothing)⤶ {⤶ Clothing.Toggle(ResourceLibrary.Get<Clothing>(itemId));⤶ }⤶ }⤶ else⤶ {⤶ foreach (var itemId in TeamBClothing)⤶ {⤶ Clothing.Toggle(ResourceLibrary.Get<Clothing>(itemId));⤶ }⤶ }⤶ }⤶ }⤶ }⤶ ```⤶ # Whitelisting Clothing Categories⤶ To enable some degree of customisation, you may want to allow players to configure their hair, skin, etc, while forcing them to wear a specific shirt and pair of shoes. To do this, you can whitelist certain clothing categories and manually deserialise what the player has equipped.⤶ ```csharp⤶ `MyPlayer.Clothes.cs`⤶ ⤶ public partial class MyPlayer⤶ {⤶ public ClothingContainer Clothing { get; protected set; }⤶ ⤶ private static readonly Clothing.ClothingCategory[] WhitelistedAccessories =⤶ {⤶ Sandbox.Clothing.ClothingCategory.Skin, Sandbox.Clothing.ClothingCategory.Facial,⤶ Sandbox.Clothing.ClothingCategory.Hair⤶ };⤶ ⤶ public void UpdateClothes(Client cl)⤶ {⤶ Clothing ??= new ClothingContainer();⤶ ⤶ // Clear out any previously equipped clothing.⤶ Clothing.Clothing.Clear();⤶ ⤶ // Only loads certain client configured clothing items.⤶ // E.g. Hair, Skin, etc.⤶ DeserializeAccessories(cl.GetClientData("avatar"));⤶ ⤶ // ... Set the rest of the player's clothing manually ...⤶ // (See above)⤶ }⤶ ⤶ /// <summary>⤶ /// Deserialises client accessories and equips them.⤶ /// "Accessories" may include Hair, Skin, Etc.⤶ /// </summary>⤶ /// <param name="json"></param>⤶ private void DeserializeAccessories(string json)⤶ {⤶ if (string.IsNullOrWhiteSpace(json))⤶ {⤶ return;⤶ }⤶ ⤶ try⤶ {⤶ var entries = JsonSerializer.Deserialize<ClothingContainer.Entry[]>(json);⤶ foreach (var entry in entries!)⤶ {⤶ var item = ResourceLibrary.Get<Clothing>(entry.Id);⤶ if (item == null) continue;⤶ if (!WhitelistedAccessories.Contains(item.Category)) continue;⤶ ⤶ Clothing.Toggle(item);⤶ }⤶ }⤶ catch (System.Exception e)⤶ {⤶ Log.Warning(e, "Error deserializing accessories");⤶ }⤶ }⤶ }⤶ ```