Equip clothing to preview dummies in the lobby.

This commit is contained in:
Pieter-Jan Briers
2020-01-20 09:20:36 +01:00
parent 03bfb22559
commit 75aa9541e0
7 changed files with 166 additions and 24 deletions

View File

@@ -108,24 +108,44 @@ namespace Content.Client.GameObjects
private void _setSlot(Slots slot, IEntity entity)
{
if (_sprite != null && entity.TryGetComponent(out ClothingComponent clothing))
SetSlotVisuals(slot, entity);
InterfaceController?.AddToSlot(slot, entity);
}
internal void SetSlotVisuals(Slots slot, IEntity entity)
{
if (_sprite == null)
{
return;
}
if (entity != null && entity.TryGetComponent(out ClothingComponent clothing))
{
var flag = SlotMasks[slot];
var data = clothing.GetEquippedStateInfo(flag);
if (data == null)
{
_sprite.LayerSetVisible(slot, false);
}
else
if (data != null)
{
var (rsi, state) = data.Value;
_sprite.LayerSetVisible(slot, true);
_sprite.LayerSetRSI(slot, rsi);
_sprite.LayerSetState(slot, state);
return;
}
}
InterfaceController?.AddToSlot(slot, entity);
_sprite.LayerSetVisible(slot, false);
}
internal void ClearAllSlotVisuals()
{
foreach (var slot in InventoryInstance.SlotMasks)
{
if (slot != Slots.NONE)
{
_sprite.LayerSetVisible(slot, false);
}
}
}
private void _clearSlot(Slots slot)

View File

@@ -209,6 +209,10 @@ namespace Content.Client.UserInterface
_previewDummy = entityManager.SpawnEntityAt("HumanMob_Dummy",
new MapCoordinates(Vector2.Zero, MapId.Nullspace));
_previewDummy.GetComponent<HumanoidAppearanceComponent>().UpdateFromProfile(profile);
if (profile is HumanoidCharacterProfile humanoid)
{
LobbyCharacterPreviewPanel.GiveDummyJobClothes(_previewDummy, humanoid);
}
var isSelectedCharacter = profile == preferencesManager.Preferences.SelectedCharacter;
@@ -239,7 +243,7 @@ namespace Content.Client.UserInterface
{
Text = "Delete",
Visible = !isSelectedCharacter,
SizeFlagsHorizontal = SizeFlags.ShrinkEnd
SizeFlagsHorizontal = SizeFlags.ShrinkEnd | SizeFlags.Expand
};
deleteButton.OnPressed += args =>
{

View File

@@ -1,13 +1,20 @@
using Content.Client.GameObjects.Components.Mobs;
using System.Linq;
using Content.Client.GameObjects;
using Content.Client.GameObjects.Components.Mobs;
using Content.Client.Interfaces;
using Content.Shared;
using Content.Shared.GameObjects.Components.Inventory;
using Content.Shared.Jobs;
using Content.Shared.Preferences;
using Robust.Client.Interfaces.GameObjects.Components;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
namespace Content.Client.UserInterface
{
@@ -94,6 +101,33 @@ namespace Content.Client.UserInterface
_summaryLabel.Text = selectedCharacter.Summary;
var component = _previewDummy.GetComponent<HumanoidAppearanceComponent>();
component.UpdateFromProfile(selectedCharacter);
GiveDummyJobClothes(_previewDummy, selectedCharacter);
}
}
public static void GiveDummyJobClothes(IEntity dummy, HumanoidCharacterProfile profile)
{
var protoMan = IoCManager.Resolve<IPrototypeManager>();
var entityMan = IoCManager.Resolve<IEntityManager>();
var inventory = dummy.GetComponent<ClientInventoryComponent>();
var highPriorityJob = profile.JobPriorities.SingleOrDefault(p => p.Value == JobPriority.High).Key;
var job = protoMan.Index<JobPrototype>(highPriorityJob ?? SharedGameTicker.OverflowJob);
var gear = protoMan.Index<StartingGearPrototype>(job.StartingGear);
inventory.ClearAllSlotVisuals();
foreach (var (slot, itemType) in gear.Equipment)
{
var item = entityMan
.SpawnEntityAt(itemType, new MapCoordinates(Vector2.Zero, MapId.Nullspace));
inventory.SetSlotVisuals(slot, item);
item.Delete();
}
}
}

View File

@@ -265,14 +265,8 @@ namespace Content.Server.GameTicking
{
var gear = _prototypeManager.Index<StartingGearPrototype>(job.StartingGear).Equipment;
foreach (var (slotStr, equipmentStr) in gear)
foreach (var (slot, equipmentStr) in gear)
{
if (!Enum.TryParse(slotStr.ToUpper(), out EquipmentSlotDefines.Slots slot))
{
Logger.Error("{0} is an invalid equipment slot.", slotStr);
continue;
}
var equipmentEntity = _entityManager.SpawnEntity(equipmentStr, entity.Transform.GridPosition);
inventory.Equip(slot, equipmentEntity.GetComponent<ClothingComponent>());
}

View File

@@ -6,13 +6,28 @@ namespace Content.Shared.GameObjects.Components.Inventory
{
public static class EquipmentSlotDefines
{
public static IReadOnlyCollection<Slots> AllSlots { get; }
static EquipmentSlotDefines()
{
var output = new Slots[(int)Slots.LAST - (int)Slots.HEAD];
// The index stuff is to jump over NONE.
for (var i = 0; i < output.Length; i++)
{
output[i] = (Slots)(i+1);
}
AllSlots = output;
}
/// <summary>
/// Uniquely identifies a single slot in an inventory.
/// </summary>
[Serializable, NetSerializable]
public enum Slots
{
NONE,
NONE = 0,
HEAD,
EYES,
EARS,
@@ -29,7 +44,12 @@ namespace Content.Shared.GameObjects.Components.Inventory
POCKET3,
POCKET4,
EXOSUITSLOT1,
EXOSUITSLOT2
EXOSUITSLOT2,
/// <summary>
/// Not a real slot.
/// </summary>
LAST
}
/// <summary>

View File

@@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
using YamlDotNet.RepresentationModel;
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
namespace Content.Shared.Jobs
{
@@ -11,20 +13,30 @@ namespace Content.Shared.Jobs
public class StartingGearPrototype : IPrototype, IIndexedPrototype
{
private string _id;
private Dictionary<string, string> _equipment;
private Dictionary<Slots, string> _equipment;
[ViewVariables]
public string ID => _id;
[ViewVariables] public string ID => _id;
[ViewVariables]
public Dictionary<string, string> Equipment => _equipment;
[ViewVariables] public IReadOnlyDictionary<Slots, string> Equipment => _equipment;
public void LoadFrom(YamlMappingNode mapping)
{
var serializer = YamlObjectSerializer.NewReader(mapping);
serializer.DataField(ref _id, "id", string.Empty);
serializer.DataField(ref _equipment, "equipment", new Dictionary<string, string>());
var equipment = serializer.ReadDataField<Dictionary<string, string>>("equipment");
_equipment = equipment.ToDictionary(slotStr =>
{
var (key, _) = slotStr;
if (!Enum.TryParse(key, true, out Slots slot))
{
throw new Exception($"{key} is an invalid equipment slot.");
}
return slot;
}, type => type.Value);
}
}
}

View File

@@ -0,0 +1,58 @@
using System;
using System.Linq;
using Content.Shared.GameObjects.Components.Inventory;
using NUnit.Framework;
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
namespace Content.Tests.Shared
{
[TestFixture]
[Parallelizable(ParallelScope.All)]
[TestOf(typeof(EquipmentSlotDefines))]
public class EquipmentSlotDefinesTest
{
/// <summary>
/// Test that all slots are contained in <see cref="AllSlots" />
/// </summary>
[Test]
public void TestAllSlotsContainsAll()
{
foreach (var slotObj in Enum.GetValues(typeof(Slots)))
{
var slot = (Slots) slotObj;
if (slot == Slots.NONE || slot == Slots.LAST)
{
// Not real slots, skip these.
continue;
}
Assert.That(AllSlots.Contains(slot));
}
}
/// <summary>
/// Test that every slot has an entry in <see cref="SlotNames" />.
/// </summary>
[Test]
public void TestSlotNamesContainsAll()
{
foreach (var slot in AllSlots)
{
Assert.That(SlotNames, Contains.Key(slot));
}
}
/// <summary>
/// Test that every slot has an entry in <see cref="SlotMasks" />.
/// </summary>
[Test]
public void TestSlotMasksContainsAll()
{
foreach (var slot in AllSlots)
{
Assert.That(SlotMasks, Contains.Key(slot));
}
}
}
}