Added hair, facial hair, magic mirror (#452)
* Added hair, facial hair, magic mirror * I forgot to commit the textures lmao * Use shader to fix hair color blending
@@ -0,0 +1,189 @@
|
|||||||
|
using System;
|
||||||
|
using Content.Shared.GameObjects.Components;
|
||||||
|
using Content.Shared.Preferences.Appearance;
|
||||||
|
using Robust.Client.GameObjects.Components.UserInterface;
|
||||||
|
using Robust.Client.Interfaces.ResourceManagement;
|
||||||
|
using Robust.Client.ResourceManagement;
|
||||||
|
using Robust.Client.UserInterface.Controls;
|
||||||
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
|
using Robust.Shared.GameObjects.Components.Renderable;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Client.GameObjects.Components
|
||||||
|
{
|
||||||
|
public class MagicMirrorBoundUserInterface : BoundUserInterface
|
||||||
|
{
|
||||||
|
#pragma warning disable 649
|
||||||
|
[Dependency] private readonly IResourceCache _resourceCache;
|
||||||
|
[Dependency] private readonly ILocalizationManager _localization;
|
||||||
|
#pragma warning restore 649
|
||||||
|
private MagicMirrorWindow _window;
|
||||||
|
|
||||||
|
public MagicMirrorBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Open()
|
||||||
|
{
|
||||||
|
base.Open();
|
||||||
|
|
||||||
|
_window = new MagicMirrorWindow(this,_resourceCache, _localization);
|
||||||
|
_window.OnClose += Close;
|
||||||
|
_window.Open();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void HairSelected(string name, bool isFacialHair)
|
||||||
|
{
|
||||||
|
SendMessage(new SharedMagicMirrorComponent.HairSelectedMessage(name, isFacialHair));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void HairColorSelected(Color color, bool isFacialHair)
|
||||||
|
{
|
||||||
|
SendMessage(new SharedMagicMirrorComponent.HairColorSelectedMessage(color, isFacialHair));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
base.Dispose(disposing);
|
||||||
|
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
_window.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FacialHairPickerWindow : HairPickerWindow
|
||||||
|
{
|
||||||
|
public FacialHairPickerWindow(IResourceCache resourceCache, ILocalizationManager localization) : base(resourceCache, localization)
|
||||||
|
{
|
||||||
|
Title = "Facial hair";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Populate()
|
||||||
|
{
|
||||||
|
var humanFacialHairRSIPath = SharedSpriteComponent.TextureRoot / "Mob/human_facial_hair.rsi";
|
||||||
|
var humanFacialHairRSI = ResourceCache.GetResource<RSIResource>(humanFacialHairRSIPath).RSI;
|
||||||
|
foreach (var (styleName, styleState) in HairStyles.FacialHairStylesMap)
|
||||||
|
{
|
||||||
|
Items.AddItem(styleName, humanFacialHairRSI[styleState].Frame0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class HairPickerWindow : SS14Window
|
||||||
|
{
|
||||||
|
public event Action<Color> OnHairColorPicked;
|
||||||
|
public event Action<string> OnHairStylePicked;
|
||||||
|
|
||||||
|
protected readonly IResourceCache ResourceCache;
|
||||||
|
protected readonly ItemList Items;
|
||||||
|
protected override Vector2? CustomSize => (300, 300);
|
||||||
|
public HairPickerWindow(IResourceCache resourceCache, ILocalizationManager localization)
|
||||||
|
{
|
||||||
|
Title = "Hair";
|
||||||
|
ResourceCache = resourceCache;
|
||||||
|
var vBox = new VBoxContainer();
|
||||||
|
Contents.AddChild(vBox);
|
||||||
|
|
||||||
|
var colorHBox = new HBoxContainer();
|
||||||
|
vBox.AddChild(colorHBox);
|
||||||
|
|
||||||
|
var colorLabel = new Label
|
||||||
|
{
|
||||||
|
Text = localization.GetString("Color: ")
|
||||||
|
};
|
||||||
|
colorHBox.AddChild(colorLabel);
|
||||||
|
|
||||||
|
var colorEdit = new LineEdit
|
||||||
|
{
|
||||||
|
SizeFlagsHorizontal = SizeFlags.FillExpand
|
||||||
|
};
|
||||||
|
colorEdit.OnTextChanged += args =>
|
||||||
|
{
|
||||||
|
var color = Color.TryFromHex(args.Text);
|
||||||
|
if (color.HasValue)
|
||||||
|
{
|
||||||
|
OnHairColorPicked?.Invoke(color.Value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
colorHBox.AddChild(colorEdit);
|
||||||
|
|
||||||
|
Items = new ItemList
|
||||||
|
{
|
||||||
|
SizeFlagsVertical = SizeFlags.FillExpand,
|
||||||
|
};
|
||||||
|
vBox.AddChild(Items);
|
||||||
|
Items.OnItemSelected += ItemSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Populate()
|
||||||
|
{
|
||||||
|
var humanHairRSIPath = SharedSpriteComponent.TextureRoot / "Mob/human_hair.rsi";
|
||||||
|
var humanHairRSI = ResourceCache.GetResource<RSIResource>(humanHairRSIPath).RSI;
|
||||||
|
foreach (var (styleName, styleState) in HairStyles.HairStylesMap)
|
||||||
|
{
|
||||||
|
Items.AddItem(styleName, humanHairRSI[styleState].Frame0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ItemSelected(ItemList.ItemListSelectedEventArgs args)
|
||||||
|
{
|
||||||
|
OnHairStylePicked?.Invoke(Items[args.ItemIndex].Text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MagicMirrorWindow : SS14Window
|
||||||
|
{
|
||||||
|
private readonly HairPickerWindow _hairPickerWindow;
|
||||||
|
private readonly FacialHairPickerWindow _facialHairPickerWindow;
|
||||||
|
|
||||||
|
public MagicMirrorWindow(MagicMirrorBoundUserInterface owner, IResourceCache resourceCache, ILocalizationManager localization)
|
||||||
|
{
|
||||||
|
Title = "Magic Mirror";
|
||||||
|
|
||||||
|
_hairPickerWindow = new HairPickerWindow(resourceCache, localization);
|
||||||
|
_hairPickerWindow.Populate();
|
||||||
|
_hairPickerWindow.OnHairStylePicked += newStyle => owner.HairSelected(newStyle, false);
|
||||||
|
_hairPickerWindow.OnHairColorPicked += newColor => owner.HairColorSelected(newColor, false);
|
||||||
|
|
||||||
|
_facialHairPickerWindow = new FacialHairPickerWindow(resourceCache, localization);
|
||||||
|
_facialHairPickerWindow.Populate();
|
||||||
|
_facialHairPickerWindow.OnHairStylePicked += newStyle => owner.HairSelected(newStyle, true);
|
||||||
|
_facialHairPickerWindow.OnHairColorPicked += newColor => owner.HairColorSelected(newColor, true);
|
||||||
|
|
||||||
|
var vBox = new VBoxContainer();
|
||||||
|
Contents.AddChild(vBox);
|
||||||
|
|
||||||
|
var hairButton = new Button
|
||||||
|
{
|
||||||
|
Text = localization.GetString("Customize hair")
|
||||||
|
};
|
||||||
|
hairButton.OnPressed += args => _hairPickerWindow.Open();
|
||||||
|
vBox.AddChild(hairButton);
|
||||||
|
|
||||||
|
var facialHairButton = new Button
|
||||||
|
{
|
||||||
|
Text = localization.GetString("Customize facial hair")
|
||||||
|
};
|
||||||
|
facialHairButton.OnPressed += args => _facialHairPickerWindow.Open();
|
||||||
|
vBox.AddChild(facialHairButton);
|
||||||
|
|
||||||
|
Size = CombinedMinimumSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
base.Dispose(disposing);
|
||||||
|
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
_hairPickerWindow.Dispose();
|
||||||
|
_facialHairPickerWindow.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
100
Content.Client/GameObjects/Components/Mobs/HairComponent.cs
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
using Content.Shared.GameObjects.Components.Mobs;
|
||||||
|
using Content.Shared.Preferences.Appearance;
|
||||||
|
using Robust.Client.GameObjects;
|
||||||
|
using Robust.Client.Graphics.Shaders;
|
||||||
|
using Robust.Client.Interfaces.GameObjects.Components;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Client.GameObjects.Components.Mobs
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class HairComponent : SharedHairComponent
|
||||||
|
{
|
||||||
|
private const string HairShaderName = "hair";
|
||||||
|
private const string HairColorParameter = "hairColor";
|
||||||
|
|
||||||
|
#pragma warning disable 649
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototypeManager;
|
||||||
|
#pragma warning restore 649
|
||||||
|
|
||||||
|
private ShaderInstance _facialHairShader;
|
||||||
|
private ShaderInstance _hairShader;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
var shaderProto = _prototypeManager.Index<ShaderPrototype>(HairShaderName);
|
||||||
|
|
||||||
|
_facialHairShader = shaderProto.InstanceUnique();
|
||||||
|
_hairShader = shaderProto.InstanceUnique();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Startup()
|
||||||
|
{
|
||||||
|
base.Startup();
|
||||||
|
|
||||||
|
if (Owner.TryGetComponent(out ISpriteComponent sprite))
|
||||||
|
{
|
||||||
|
sprite.LayerSetShader(HumanoidVisualLayers.Hair, _hairShader);
|
||||||
|
sprite.LayerSetShader(HumanoidVisualLayers.FacialHair, _facialHairShader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string FacialHairStyleName
|
||||||
|
{
|
||||||
|
get => base.FacialHairStyleName;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.FacialHairStyleName = value;
|
||||||
|
UpdateHairStyle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string HairStyleName
|
||||||
|
{
|
||||||
|
get => base.HairStyleName;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.HairStyleName = value;
|
||||||
|
UpdateHairStyle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Color HairColor
|
||||||
|
{
|
||||||
|
get => base.HairColor;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.HairColor = value;
|
||||||
|
UpdateHairStyle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Color FacialHairColor
|
||||||
|
{
|
||||||
|
get => base.FacialHairColor;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.FacialHairColor = value;
|
||||||
|
UpdateHairStyle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateHairStyle()
|
||||||
|
{
|
||||||
|
var sprite = Owner.GetComponent<SpriteComponent>();
|
||||||
|
|
||||||
|
_hairShader?.SetParameter(HairColorParameter, HairColor);
|
||||||
|
_facialHairShader?.SetParameter(HairColorParameter, FacialHairColor);
|
||||||
|
|
||||||
|
sprite.LayerSetState(HumanoidVisualLayers.Hair,
|
||||||
|
HairStyles.HairStylesMap[HairStyleName ?? HairStyles.DefaultHairStyle]);
|
||||||
|
sprite.LayerSetState(HumanoidVisualLayers.FacialHair,
|
||||||
|
HairStyles.FacialHairStylesMap[FacialHairStyleName ?? HairStyles.DefaultFacialHairStyle]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
using Content.Server.GameObjects.Components.Mobs;
|
||||||
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Shared.GameObjects.Components;
|
||||||
|
using Content.Shared.Preferences.Appearance;
|
||||||
|
using Robust.Server.GameObjects.Components.UserInterface;
|
||||||
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
[ComponentReference(typeof(IActivate))]
|
||||||
|
public class MagicMirrorComponent : SharedMagicMirrorComponent, IActivate
|
||||||
|
{
|
||||||
|
private BoundUserInterface _userInterface;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
||||||
|
.GetBoundUserInterface(MagicMirrorUiKey.Key);
|
||||||
|
_userInterface.OnReceiveMessage += OnUiReceiveMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj)
|
||||||
|
{
|
||||||
|
var hair = obj.Session.AttachedEntity.GetComponent<HairComponent>();
|
||||||
|
switch (obj.Message)
|
||||||
|
{
|
||||||
|
case HairSelectedMessage msg:
|
||||||
|
var map =
|
||||||
|
msg.IsFacialHair ? HairStyles.FacialHairStylesMap : HairStyles.HairStylesMap;
|
||||||
|
if (!map.ContainsKey(msg.HairName))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (msg.IsFacialHair)
|
||||||
|
{
|
||||||
|
hair.FacialHairStyleName = msg.HairName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hair.HairStyleName = msg.HairName;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case HairColorSelectedMessage msg:
|
||||||
|
if (msg.IsFacialHair)
|
||||||
|
{
|
||||||
|
hair.FacialHairColor = msg.HairColor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hair.HairColor = msg.HairColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Activate(ActivateEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
if (!eventArgs.User.TryGetComponent(out IActorComponent actor))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_userInterface.Open(actor.playerSession);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Content.Server/GameObjects/Components/Mobs/HairComponent.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using Content.Shared.GameObjects.Components.Mobs;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Mobs
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class HairComponent : SharedHairComponent
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
using System;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
|
namespace Content.Shared.GameObjects.Components.Mobs
|
||||||
|
{
|
||||||
|
public abstract class SharedHairComponent : Component
|
||||||
|
{
|
||||||
|
private string _facialHairStyleName;
|
||||||
|
private string _hairStyleName;
|
||||||
|
private Color _hairColor;
|
||||||
|
private Color _facialHairColor;
|
||||||
|
|
||||||
|
public sealed override string Name => "Hair";
|
||||||
|
public sealed override uint? NetID => ContentNetIDs.HAIR;
|
||||||
|
public sealed override Type StateType => typeof(HairComponentState);
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public virtual string HairStyleName
|
||||||
|
{
|
||||||
|
get => _hairStyleName;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_hairStyleName = value;
|
||||||
|
Dirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public virtual string FacialHairStyleName
|
||||||
|
{
|
||||||
|
get => _facialHairStyleName;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_facialHairStyleName = value;
|
||||||
|
Dirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public virtual Color HairColor
|
||||||
|
{
|
||||||
|
get => _hairColor;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_hairColor = value;
|
||||||
|
Dirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public virtual Color FacialHairColor
|
||||||
|
{
|
||||||
|
get => _facialHairColor;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_facialHairColor = value;
|
||||||
|
Dirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ComponentState GetComponentState()
|
||||||
|
{
|
||||||
|
return new HairComponentState(HairStyleName, FacialHairStyleName, HairColor, FacialHairColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
|
||||||
|
{
|
||||||
|
var cast = (HairComponentState) curState;
|
||||||
|
|
||||||
|
HairStyleName = cast.HairStyleName;
|
||||||
|
FacialHairStyleName = cast.FacialHairStyleName;
|
||||||
|
HairColor = cast.HairColor;
|
||||||
|
FacialHairColor = cast.FacialHairColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
private sealed class HairComponentState : ComponentState
|
||||||
|
{
|
||||||
|
public string HairStyleName { get; }
|
||||||
|
public string FacialHairStyleName { get; }
|
||||||
|
public Color HairColor { get; }
|
||||||
|
public Color FacialHairColor { get; }
|
||||||
|
|
||||||
|
public HairComponentState(string hairStyleName, string facialHairStyleName, Color hairColor, Color facialHairColor) : base(ContentNetIDs.HAIR)
|
||||||
|
{
|
||||||
|
HairStyleName = hairStyleName;
|
||||||
|
FacialHairStyleName = facialHairStyleName;
|
||||||
|
HairColor = hairColor;
|
||||||
|
FacialHairColor = facialHairColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.Components.UserInterface;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.GameObjects.Components
|
||||||
|
{
|
||||||
|
public class SharedMagicMirrorComponent : Component
|
||||||
|
{
|
||||||
|
public override string Name => "MagicMirror";
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum MagicMirrorUiKey
|
||||||
|
{
|
||||||
|
Key
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public class HairSelectedMessage : BoundUserInterfaceMessage
|
||||||
|
{
|
||||||
|
public readonly string HairName;
|
||||||
|
public readonly bool IsFacialHair;
|
||||||
|
|
||||||
|
public HairSelectedMessage(string name, bool isFacialHair)
|
||||||
|
{
|
||||||
|
HairName = name;
|
||||||
|
IsFacialHair = isFacialHair;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public class HairColorSelectedMessage : BoundUserInterfaceMessage
|
||||||
|
{
|
||||||
|
public readonly Color HairColor;
|
||||||
|
public readonly bool IsFacialHair;
|
||||||
|
|
||||||
|
public HairColorSelectedMessage(Color color, bool isFacialHair)
|
||||||
|
{
|
||||||
|
HairColor = color;
|
||||||
|
IsFacialHair = isFacialHair;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,5 +34,6 @@
|
|||||||
public const uint ITEMCOOLDOWN = 1029;
|
public const uint ITEMCOOLDOWN = 1029;
|
||||||
public const uint CARGO_ORDER_DATABASE = 1030;
|
public const uint CARGO_ORDER_DATABASE = 1030;
|
||||||
public const uint GALACTIC_MARKET = 1031;
|
public const uint GALACTIC_MARKET = 1031;
|
||||||
|
public const uint HAIR = 1032;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
192
Content.Shared/Preferences/Appearance/HairStyles.cs
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Content.Shared.Preferences.Appearance
|
||||||
|
{
|
||||||
|
public static class HairStyles
|
||||||
|
{
|
||||||
|
public const string DefaultHairStyle = "Bald";
|
||||||
|
public const string DefaultFacialHairStyle = "Shaved";
|
||||||
|
|
||||||
|
public static readonly Dictionary<string, string> HairStylesMap = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{"Bald", "bald"},
|
||||||
|
{"Afro", "afro"},
|
||||||
|
{"Big Afro", "bigafro"},
|
||||||
|
{"Afro 2", "afro2"},
|
||||||
|
{"Asymmetrical Bob", "asymmbob"},
|
||||||
|
{"Balding Hair", "balding"},
|
||||||
|
{"Bedhead", "bedhead"},
|
||||||
|
{"Bedhead 2", "bedheadv2"},
|
||||||
|
{"Bedhead 3", "bedheadv3"},
|
||||||
|
{"Beehive", "beehive"},
|
||||||
|
{"Beehive 2", "beehive2"},
|
||||||
|
{"Birdnest", "birdnest"},
|
||||||
|
{"Birdnest 2", "birdnest2"},
|
||||||
|
{"Mercenary", "blackswordsman"},
|
||||||
|
{"Bob", "bobcut"},
|
||||||
|
{"Bobcurl", "bobcurl"},
|
||||||
|
{"Bowl 1", "bowlcut1"},
|
||||||
|
{"Bowl 2", "bowlcut2"},
|
||||||
|
{"Floorlength Braid", "braid"},
|
||||||
|
{"Long Braid", "hbraid"},
|
||||||
|
{"Business Hair", "business"},
|
||||||
|
{"Business Hair 2", "business2"},
|
||||||
|
{"Business Hair 3", "business3"},
|
||||||
|
{"Business Hair 4", "business4"},
|
||||||
|
{"Bun", "bun"},
|
||||||
|
{"Casual Bun", "bunalt"},
|
||||||
|
{"Bun 2", "bun2"},
|
||||||
|
{"Bun 3", "bun3"},
|
||||||
|
{"Buzzcut", "buzzcut"},
|
||||||
|
{"Chop", "chop"},
|
||||||
|
{"CIA", "cia"},
|
||||||
|
{"Combover", "combover"},
|
||||||
|
{"Coffee House", "coffeehouse"},
|
||||||
|
{"Crewcut", "crewcut"},
|
||||||
|
{"Chrono", "toriyama"},
|
||||||
|
{"Curls", "curls"},
|
||||||
|
{"Cut Hair", "cuthair"},
|
||||||
|
{"Dandy Pompadour", "dandypompadour"},
|
||||||
|
{"Devil Lock", "devilock"},
|
||||||
|
{"Double-Bun", "doublebun"},
|
||||||
|
{"Dreadlocks", "dreads"},
|
||||||
|
{"80's", "80s"},
|
||||||
|
{"Emo", "emo"},
|
||||||
|
{"Flow Hair", "flowhair"},
|
||||||
|
{"The Family Man", "thefamilyman"},
|
||||||
|
{"Father", "father"},
|
||||||
|
{"Feather", "feather"},
|
||||||
|
{"Cut Hair Alt", "femc"},
|
||||||
|
{"Flaired Hair", "flair"},
|
||||||
|
{"Emo Fringe", "emofringe"},
|
||||||
|
{"Fringetail", "fringetail"},
|
||||||
|
{"Gelled Back", "gelled"},
|
||||||
|
{"Gentle", "gentle"},
|
||||||
|
{"Half-banged Hair", "halfbang"},
|
||||||
|
{"Half-banged Hair Alt", "halfbang_alt"},
|
||||||
|
{"Half-Shaved", "halfshaved"},
|
||||||
|
{"Half-Shaved Emo", "halfshaved_emo"},
|
||||||
|
{"Hamaski Hair", "hamasaki"},
|
||||||
|
{"Combed Hair", "hbangs"},
|
||||||
|
{"Combed Hair Alt", "hbangs_alt"},
|
||||||
|
{"High Ponytail", "highponytail"},
|
||||||
|
{"Hime Cut", "himecut"},
|
||||||
|
{"Hime Cut Alt", "himecut_alt"},
|
||||||
|
{"Hitop", "hitop"},
|
||||||
|
{"Adam Jensen Hair", "jensen"},
|
||||||
|
{"Joestar", "joestar"},
|
||||||
|
{"Pigtails", "kagami"},
|
||||||
|
{"Kare", "kare"},
|
||||||
|
{"Kusanagi Hair", "kusanagi"},
|
||||||
|
{"Ladylike", "ladylike"},
|
||||||
|
{"Ladylike alt", "ladylike2"},
|
||||||
|
{"Long Emo", "emolong"},
|
||||||
|
{"Long Hair", "vlong"},
|
||||||
|
{"Long Hair Alt", "longeralt2"},
|
||||||
|
{"Very Long Hair", "longest"},
|
||||||
|
{"Longer Fringe", "vlongfringe"},
|
||||||
|
{"Long Fringe", "longfringe"},
|
||||||
|
{"Overeye Long", "longovereye"},
|
||||||
|
{"Man Bun", "manbun"},
|
||||||
|
{"Drillruru", "drillruru"},
|
||||||
|
{"Medium Braid", "shortbraid"},
|
||||||
|
{"Medium Braid Alt", "mediumbraid"},
|
||||||
|
{"Messy Bun", "messybun"},
|
||||||
|
{"Modern", "modern"},
|
||||||
|
{"Mohawk", "mohawk"},
|
||||||
|
{"Mulder", "mulder"},
|
||||||
|
{"Nia", "nia"},
|
||||||
|
{"Nitori", "nitori"},
|
||||||
|
{"Odango", "odango"},
|
||||||
|
{"Ombre", "ombre"},
|
||||||
|
{"Oxton", "oxton"},
|
||||||
|
{"Parted", "parted"},
|
||||||
|
{"Pixie", "pixie"},
|
||||||
|
{"Pompadour", "pompadour"},
|
||||||
|
{"Ponytail 1", "ponytail"},
|
||||||
|
{"Ponytail 2", "ponytail2"},
|
||||||
|
{"Ponytail 3", "ponytail3"},
|
||||||
|
{"Ponytail 4", "ponytail4"},
|
||||||
|
{"Ponytail 5", "ponytail5"},
|
||||||
|
{"Ponytail 6", "ponytail6"},
|
||||||
|
{"Ponytail 7", "ponytail7"},
|
||||||
|
{"Poofy", "poofy"},
|
||||||
|
{"Poofy Alt", "poofy2"},
|
||||||
|
{"Quiff", "quiff"},
|
||||||
|
{"Ramona", "ramona"},
|
||||||
|
{"Reverse Mohawk", "reversemohawk"},
|
||||||
|
{"Ronin", "ronin"},
|
||||||
|
{"Rows", "rows1"},
|
||||||
|
{"Rows Alt", "rows2"},
|
||||||
|
{"Rows Bun", "rows3"},
|
||||||
|
{"Flat Top", "sargeant"},
|
||||||
|
{"Scully", "scully"},
|
||||||
|
{"Shaved Mohawk", "shavedmohawk"},
|
||||||
|
{"Shaved Part", "shavedpart"},
|
||||||
|
{"Short Hair", "short"},
|
||||||
|
{"Short Hair 2", "short2"},
|
||||||
|
{"Short Hair 3", "short3"},
|
||||||
|
{"Short Bangs", "shortbangs"},
|
||||||
|
{"Overeye Short", "shortovereye"},
|
||||||
|
{"Shoulder-length Hair", "shoulderlen"},
|
||||||
|
{"Sidepart Hair", "sidepart"},
|
||||||
|
{"Side Ponytail", "stail"},
|
||||||
|
{"One Shoulder", "oneshoulder"},
|
||||||
|
{"Tress Shoulder", "tressshoulder"},
|
||||||
|
{"Side Ponytail 2", "ponytailf"},
|
||||||
|
{"Side Swipe", "sideswipe"},
|
||||||
|
{"Skinhead", "skinhead"},
|
||||||
|
{"Messy Hair", "smessy"},
|
||||||
|
{"Sleeze", "sleeze"},
|
||||||
|
{"Spiky", "spikey"},
|
||||||
|
{"Stylo", "stylo"},
|
||||||
|
{"Spiky Ponytail", "spikyponytail"},
|
||||||
|
{"Top Knot", "topknot"},
|
||||||
|
{"Thinning", "thinning"},
|
||||||
|
{"Thinning Rear", "thinningrear"},
|
||||||
|
{"Thinning Front", "thinningfront"},
|
||||||
|
{"Undercut", "undercut"},
|
||||||
|
{"Unkept", "unkept"},
|
||||||
|
{"Updo", "updo"},
|
||||||
|
{"Vegeta", "toriyama2"},
|
||||||
|
{"Overeye Very Short", "veryshortovereye"},
|
||||||
|
{"Overeye Very Short, Alternate", "veryshortovereyealternate"},
|
||||||
|
{"Volaju", "volaju"},
|
||||||
|
{"Wisp", "wisp"},
|
||||||
|
{"Zieglertail", "ziegler"},
|
||||||
|
{"Zone Braid", "zone"},
|
||||||
|
};
|
||||||
|
|
||||||
|
public static readonly Dictionary<string, string> FacialHairStylesMap = new Dictionary<string, string>()
|
||||||
|
{
|
||||||
|
{"Shaved", "shaved"},
|
||||||
|
{"Watson Mustache", "watson"},
|
||||||
|
{"Hulk Hogan Mustache", "hogan"},
|
||||||
|
{"Van Dyke Mustache", "vandyke"},
|
||||||
|
{"Square Mustache", "chaplin"},
|
||||||
|
{"Selleck Mustache", "selleck"},
|
||||||
|
{"Neckbeard", "neckbeard"},
|
||||||
|
{"Full Beard", "fullbeard"},
|
||||||
|
{"Long Beard", "longbeard"},
|
||||||
|
{"Very Long Beard", "wise"},
|
||||||
|
{"Elvis Sideburns", "elvis"},
|
||||||
|
{"Abraham Lincoln Beard", "abe"},
|
||||||
|
{"Chinstrap", "chin"},
|
||||||
|
{"Hipster Beard", "hip"},
|
||||||
|
{"Goatee", "gt"},
|
||||||
|
{"Adam Jensen Beard", "jensen"},
|
||||||
|
{"Volaju", "volaju"},
|
||||||
|
{"Dwarf Beard", "dwarf"},
|
||||||
|
{"3 O'clock Shadow", "3oclock"},
|
||||||
|
{"3 O'clock Shadow and Moustache", "3oclockmoustache"},
|
||||||
|
{"5 O'clock Shadow", "5oclock"},
|
||||||
|
{"5 O'clock Shadow and Moustache", "5oclockmoustache"},
|
||||||
|
{"7 O'clock Shadow", "7oclock"},
|
||||||
|
{"7 O'clock Shadow and Moustache", "7oclockmoustache"},
|
||||||
|
{"Mutton Chops", "mutton"},
|
||||||
|
{"Mutton Chops and Moustache", "muttonmu"},
|
||||||
|
{"Walrus Moustache", "walrus"},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Preferences.Appearance
|
||||||
|
{
|
||||||
|
public enum HumanoidVisualLayers
|
||||||
|
{
|
||||||
|
Hair,
|
||||||
|
FacialHair,
|
||||||
|
}
|
||||||
|
}
|
||||||
26
Resources/Prototypes/Entities/buildings/mirror.yml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
- type: entity
|
||||||
|
id: mirror
|
||||||
|
name: Mirror
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Buildings/mirror.rsi
|
||||||
|
state: mirror
|
||||||
|
- type: Icon
|
||||||
|
sprite: Buildings/mirror.rsi
|
||||||
|
state: mirror
|
||||||
|
- type: Collidable
|
||||||
|
shapes:
|
||||||
|
- !type:PhysShapeAabb
|
||||||
|
mask: 19
|
||||||
|
layer: 16
|
||||||
|
- type: Clickable
|
||||||
|
- type: Physics
|
||||||
|
mass: 25
|
||||||
|
Anchored: true
|
||||||
|
- type: SnapGrid
|
||||||
|
offset: Center
|
||||||
|
- type: MagicMirror
|
||||||
|
- type: UserInterface
|
||||||
|
interfaces:
|
||||||
|
- key: enum.MagicMirrorUiKey.Key
|
||||||
|
type: MagicMirrorBoundUserInterface
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
- type: Thirst
|
- type: Thirst
|
||||||
# Organs
|
# Organs
|
||||||
- type: Stomach
|
- type: Stomach
|
||||||
|
|
||||||
- type: Inventory
|
- type: Inventory
|
||||||
- type: Constructor
|
- type: Constructor
|
||||||
- type: Clickable
|
- type: Clickable
|
||||||
@@ -23,6 +23,12 @@
|
|||||||
layers:
|
layers:
|
||||||
- sprite: Mob/human.rsi
|
- sprite: Mob/human.rsi
|
||||||
state: male
|
state: male
|
||||||
|
- map: ["enum.HumanoidVisualLayers.Hair"]
|
||||||
|
state: bald
|
||||||
|
sprite: Mob/human_hair.rsi
|
||||||
|
- map: ["enum.HumanoidVisualLayers.FacialHair"]
|
||||||
|
state: shaved
|
||||||
|
sprite: Mob/human_facial_hair.rsi
|
||||||
- map: ["enum.Slots.INNERCLOTHING"]
|
- map: ["enum.Slots.INNERCLOTHING"]
|
||||||
- map: ["enum.Slots.IDCARD"]
|
- map: ["enum.Slots.IDCARD"]
|
||||||
- map: ["enum.Slots.SHOES"]
|
- map: ["enum.Slots.SHOES"]
|
||||||
@@ -47,7 +53,7 @@
|
|||||||
- type: Collidable
|
- type: Collidable
|
||||||
shapes:
|
shapes:
|
||||||
- !type:PhysShapeAabb
|
- !type:PhysShapeAabb
|
||||||
bounds: "-0.5,-0.25,-0.05,0.25"
|
bounds: "-0.5,-0.25,-0.05,0.25"
|
||||||
mask: 19
|
mask: 19
|
||||||
layer: 2
|
layer: 2
|
||||||
|
|
||||||
@@ -75,4 +81,4 @@
|
|||||||
- type: Examiner
|
- type: Examiner
|
||||||
- type: CharacterInfo
|
- type: CharacterInfo
|
||||||
- type: FootstepSound
|
- type: FootstepSound
|
||||||
|
- type: Hair
|
||||||
|
|||||||
6
Resources/Prototypes/Shaders/hair.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
- type: shader
|
||||||
|
id: hair
|
||||||
|
kind: source
|
||||||
|
path: "/Shaders/hair.swsl"
|
||||||
|
params:
|
||||||
|
hairColor: "#000000"
|
||||||
8
Resources/Shaders/hair.swsl
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
// Additively blends the hair color onto the hair sprite.
|
||||||
|
|
||||||
|
uniform vec4 hairColor;
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
COLOR = texture(TEXTURE, UV);
|
||||||
|
COLOR.rgb += hairColor.rgb;
|
||||||
|
}
|
||||||
1
Resources/Textures/Buildings/mirror.rsi/meta.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"version": 1, "size": {"x": 32, "y": 32}, "states": [{"name": "mirror", "directions": 1, "delays": [[1.0]]}, {"name": "mirror_broke", "directions": 1, "delays": [[1.0]]}]}
|
||||||
BIN
Resources/Textures/Buildings/mirror.rsi/mirror.png
Normal file
|
After Width: | Height: | Size: 279 B |
BIN
Resources/Textures/Buildings/mirror.rsi/mirror_broke.png
Normal file
|
After Width: | Height: | Size: 424 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/3oclock.png
Normal file
|
After Width: | Height: | Size: 175 B |
|
After Width: | Height: | Size: 187 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/5oclock.png
Normal file
|
After Width: | Height: | Size: 174 B |
|
After Width: | Height: | Size: 186 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/7oclock.png
Normal file
|
After Width: | Height: | Size: 178 B |
|
After Width: | Height: | Size: 193 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/abe.png
Normal file
|
After Width: | Height: | Size: 178 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/chaplin.png
Normal file
|
After Width: | Height: | Size: 110 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/chin.png
Normal file
|
After Width: | Height: | Size: 130 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/dwarf.png
Normal file
|
After Width: | Height: | Size: 272 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/elvis.png
Normal file
|
After Width: | Height: | Size: 144 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/fullbeard.png
Normal file
|
After Width: | Height: | Size: 197 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/gt.png
Normal file
|
After Width: | Height: | Size: 170 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/hip.png
Normal file
|
After Width: | Height: | Size: 146 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/hogan.png
Normal file
|
After Width: | Height: | Size: 158 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/jensen.png
Normal file
|
After Width: | Height: | Size: 164 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/longbeard.png
Normal file
|
After Width: | Height: | Size: 226 B |
1
Resources/Textures/Mob/human_facial_hair.rsi/meta.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"version": 1, "size": {"x": 32, "y": 32}, "states": [{"name": "3oclock", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "3oclockmoustache", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "5oclock", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "5oclockmoustache", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "7oclock", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "7oclockmoustache", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "abe", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "chaplin", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "chin", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "dwarf", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "elvis", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "fullbeard", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "gt", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "hip", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "hogan", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "jensen", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "longbeard", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "mutton", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "muttonmu", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "neckbeard", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "selleck", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "shaved", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "vandyke", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "volaju", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "walrus", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "watson", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "wise", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}]}
|
||||||
BIN
Resources/Textures/Mob/human_facial_hair.rsi/mutton.png
Normal file
|
After Width: | Height: | Size: 217 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/muttonmu.png
Normal file
|
After Width: | Height: | Size: 212 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/neckbeard.png
Normal file
|
After Width: | Height: | Size: 164 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/selleck.png
Normal file
|
After Width: | Height: | Size: 125 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/shaved.png
Normal file
|
After Width: | Height: | Size: 96 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/vandyke.png
Normal file
|
After Width: | Height: | Size: 146 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/volaju.png
Normal file
|
After Width: | Height: | Size: 179 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/walrus.png
Normal file
|
After Width: | Height: | Size: 160 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/watson.png
Normal file
|
After Width: | Height: | Size: 124 B |
BIN
Resources/Textures/Mob/human_facial_hair.rsi/wise.png
Normal file
|
After Width: | Height: | Size: 231 B |
BIN
Resources/Textures/Mob/human_hair.rsi/.png
Normal file
|
After Width: | Height: | Size: 153 B |
BIN
Resources/Textures/Mob/human_hair.rsi/80s.png
Normal file
|
After Width: | Height: | Size: 484 B |
BIN
Resources/Textures/Mob/human_hair.rsi/afro.png
Normal file
|
After Width: | Height: | Size: 527 B |
BIN
Resources/Textures/Mob/human_hair.rsi/afro2.png
Normal file
|
After Width: | Height: | Size: 306 B |
BIN
Resources/Textures/Mob/human_hair.rsi/asymmbob.png
Normal file
|
After Width: | Height: | Size: 519 B |
BIN
Resources/Textures/Mob/human_hair.rsi/bald.png
Normal file
|
After Width: | Height: | Size: 96 B |
BIN
Resources/Textures/Mob/human_hair.rsi/balding.png
Normal file
|
After Width: | Height: | Size: 146 B |
BIN
Resources/Textures/Mob/human_hair.rsi/bedhead.png
Normal file
|
After Width: | Height: | Size: 541 B |
BIN
Resources/Textures/Mob/human_hair.rsi/bedheadv2.png
Normal file
|
After Width: | Height: | Size: 648 B |
BIN
Resources/Textures/Mob/human_hair.rsi/bedheadv3.png
Normal file
|
After Width: | Height: | Size: 421 B |
BIN
Resources/Textures/Mob/human_hair.rsi/beehive.png
Normal file
|
After Width: | Height: | Size: 540 B |
BIN
Resources/Textures/Mob/human_hair.rsi/beehive2.png
Normal file
|
After Width: | Height: | Size: 487 B |
BIN
Resources/Textures/Mob/human_hair.rsi/bigafro.png
Normal file
|
After Width: | Height: | Size: 832 B |
BIN
Resources/Textures/Mob/human_hair.rsi/birdnest.png
Normal file
|
After Width: | Height: | Size: 284 B |
BIN
Resources/Textures/Mob/human_hair.rsi/birdnest2.png
Normal file
|
After Width: | Height: | Size: 283 B |
BIN
Resources/Textures/Mob/human_hair.rsi/blackswordsman.png
Normal file
|
After Width: | Height: | Size: 440 B |
BIN
Resources/Textures/Mob/human_hair.rsi/bobcurl.png
Normal file
|
After Width: | Height: | Size: 396 B |
BIN
Resources/Textures/Mob/human_hair.rsi/bobcut.png
Normal file
|
After Width: | Height: | Size: 278 B |
BIN
Resources/Textures/Mob/human_hair.rsi/bowlcut1.png
Normal file
|
After Width: | Height: | Size: 171 B |
BIN
Resources/Textures/Mob/human_hair.rsi/bowlcut2.png
Normal file
|
After Width: | Height: | Size: 301 B |
BIN
Resources/Textures/Mob/human_hair.rsi/braid.png
Normal file
|
After Width: | Height: | Size: 995 B |
BIN
Resources/Textures/Mob/human_hair.rsi/bun.png
Normal file
|
After Width: | Height: | Size: 594 B |
BIN
Resources/Textures/Mob/human_hair.rsi/bun2.png
Normal file
|
After Width: | Height: | Size: 567 B |
BIN
Resources/Textures/Mob/human_hair.rsi/bun3.png
Normal file
|
After Width: | Height: | Size: 530 B |
BIN
Resources/Textures/Mob/human_hair.rsi/bunalt.png
Normal file
|
After Width: | Height: | Size: 400 B |
BIN
Resources/Textures/Mob/human_hair.rsi/business.png
Normal file
|
After Width: | Height: | Size: 375 B |
BIN
Resources/Textures/Mob/human_hair.rsi/business2.png
Normal file
|
After Width: | Height: | Size: 560 B |
BIN
Resources/Textures/Mob/human_hair.rsi/business3.png
Normal file
|
After Width: | Height: | Size: 530 B |
BIN
Resources/Textures/Mob/human_hair.rsi/business4.png
Normal file
|
After Width: | Height: | Size: 491 B |
BIN
Resources/Textures/Mob/human_hair.rsi/buzzcut.png
Normal file
|
After Width: | Height: | Size: 239 B |
BIN
Resources/Textures/Mob/human_hair.rsi/chop.png
Normal file
|
After Width: | Height: | Size: 400 B |
BIN
Resources/Textures/Mob/human_hair.rsi/cia.png
Normal file
|
After Width: | Height: | Size: 530 B |
BIN
Resources/Textures/Mob/human_hair.rsi/coffeehouse.png
Normal file
|
After Width: | Height: | Size: 379 B |
BIN
Resources/Textures/Mob/human_hair.rsi/combover.png
Normal file
|
After Width: | Height: | Size: 278 B |
BIN
Resources/Textures/Mob/human_hair.rsi/crewcut.png
Normal file
|
After Width: | Height: | Size: 216 B |
BIN
Resources/Textures/Mob/human_hair.rsi/curls.png
Normal file
|
After Width: | Height: | Size: 522 B |
BIN
Resources/Textures/Mob/human_hair.rsi/cuthair.png
Normal file
|
After Width: | Height: | Size: 349 B |
BIN
Resources/Textures/Mob/human_hair.rsi/dandypompadour.png
Normal file
|
After Width: | Height: | Size: 415 B |
BIN
Resources/Textures/Mob/human_hair.rsi/devilock.png
Normal file
|
After Width: | Height: | Size: 306 B |
BIN
Resources/Textures/Mob/human_hair.rsi/doublebun.png
Normal file
|
After Width: | Height: | Size: 447 B |
BIN
Resources/Textures/Mob/human_hair.rsi/dreads.png
Normal file
|
After Width: | Height: | Size: 551 B |
BIN
Resources/Textures/Mob/human_hair.rsi/drillruru.png
Normal file
|
After Width: | Height: | Size: 643 B |
BIN
Resources/Textures/Mob/human_hair.rsi/emo.png
Normal file
|
After Width: | Height: | Size: 380 B |
BIN
Resources/Textures/Mob/human_hair.rsi/emofringe.png
Normal file
|
After Width: | Height: | Size: 404 B |
BIN
Resources/Textures/Mob/human_hair.rsi/emolong.png
Normal file
|
After Width: | Height: | Size: 481 B |
BIN
Resources/Textures/Mob/human_hair.rsi/father.png
Normal file
|
After Width: | Height: | Size: 295 B |
BIN
Resources/Textures/Mob/human_hair.rsi/feather.png
Normal file
|
After Width: | Height: | Size: 438 B |
BIN
Resources/Textures/Mob/human_hair.rsi/femc.png
Normal file
|
After Width: | Height: | Size: 456 B |
BIN
Resources/Textures/Mob/human_hair.rsi/flair.png
Normal file
|
After Width: | Height: | Size: 451 B |
BIN
Resources/Textures/Mob/human_hair.rsi/flowhair.png
Normal file
|
After Width: | Height: | Size: 329 B |
BIN
Resources/Textures/Mob/human_hair.rsi/fringetail.png
Normal file
|
After Width: | Height: | Size: 382 B |
BIN
Resources/Textures/Mob/human_hair.rsi/gelled.png
Normal file
|
After Width: | Height: | Size: 232 B |
BIN
Resources/Textures/Mob/human_hair.rsi/gentle.png
Normal file
|
After Width: | Height: | Size: 363 B |
BIN
Resources/Textures/Mob/human_hair.rsi/halfbang.png
Normal file
|
After Width: | Height: | Size: 323 B |
BIN
Resources/Textures/Mob/human_hair.rsi/halfbang_alt.png
Normal file
|
After Width: | Height: | Size: 365 B |
BIN
Resources/Textures/Mob/human_hair.rsi/halfshaved.png
Normal file
|
After Width: | Height: | Size: 409 B |