Basic implementation of jobs in the character profile.

This commit is contained in:
Pieter-Jan Briers
2020-01-19 09:34:33 +01:00
parent afef34a648
commit f86ad6175e
12 changed files with 543 additions and 127 deletions

View File

@@ -19,6 +19,7 @@ using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Network; using Robust.Shared.Interfaces.Network;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Localization; using Robust.Shared.Localization;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing; using Robust.Shared.Timing;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using Robust.Shared.ViewVariables; using Robust.Shared.ViewVariables;
@@ -40,6 +41,7 @@ namespace Content.Client.GameTicking
[Dependency] private IGameHud _gameHud; [Dependency] private IGameHud _gameHud;
[Dependency] private IEntityManager _entityManager; [Dependency] private IEntityManager _entityManager;
[Dependency] private IClientPreferencesManager _preferencesManager; [Dependency] private IClientPreferencesManager _preferencesManager;
[Dependency] private IPrototypeManager _prototypeManager;
#pragma warning restore 649 #pragma warning restore 649
[ViewVariables] private bool _areWeReady; [ViewVariables] private bool _areWeReady;
@@ -192,7 +194,7 @@ namespace Content.Client.GameTicking
_tickerState = TickerState.InLobby; _tickerState = TickerState.InLobby;
_characterSetup = new CharacterSetupGui(_entityManager, _localization, _resourceCache, _preferencesManager); _characterSetup = new CharacterSetupGui(_entityManager, _localization, _resourceCache, _preferencesManager, _prototypeManager);
LayoutContainer.SetAnchorPreset(_characterSetup, LayoutContainer.LayoutPreset.Wide); LayoutContainer.SetAnchorPreset(_characterSetup, LayoutContainer.LayoutPreset.Wide);
_characterSetup.CloseButton.OnPressed += args => _characterSetup.CloseButton.OnPressed += args =>
{ {

View File

@@ -11,6 +11,7 @@ using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Localization; using Robust.Shared.Localization;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Maths; using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
namespace Content.Client.UserInterface namespace Content.Client.UserInterface
{ {
@@ -26,7 +27,8 @@ namespace Content.Client.UserInterface
public CharacterSetupGui(IEntityManager entityManager, public CharacterSetupGui(IEntityManager entityManager,
ILocalizationManager localization, ILocalizationManager localization,
IResourceCache resourceCache, IResourceCache resourceCache,
IClientPreferencesManager preferencesManager) IClientPreferencesManager preferencesManager,
IPrototypeManager prototypeManager)
{ {
_entityManager = entityManager; _entityManager = entityManager;
_preferencesManager = preferencesManager; _preferencesManager = preferencesManager;
@@ -144,7 +146,7 @@ namespace Content.Client.UserInterface
PanelOverride = new StyleBoxFlat {BackgroundColor = NanoStyle.NanoGold}, PanelOverride = new StyleBoxFlat {BackgroundColor = NanoStyle.NanoGold},
CustomMinimumSize = (2, 0) CustomMinimumSize = (2, 0)
}); });
_humanoidProfileEditor = new HumanoidProfileEditor(localization, preferencesManager); _humanoidProfileEditor = new HumanoidProfileEditor(localization, preferencesManager, prototypeManager);
_humanoidProfileEditor.OnProfileChanged += newProfile => { UpdateUI(); }; _humanoidProfileEditor.OnProfileChanged += newProfile => { UpdateUI(); };
hBox.AddChild(_humanoidProfileEditor); hBox.AddChild(_humanoidProfileEditor);

View File

@@ -1,6 +1,9 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using Content.Client.GameObjects.Components; using Content.Client.GameObjects.Components;
using Content.Client.Interfaces; using Content.Client.Interfaces;
using Content.Shared.Jobs;
using Content.Shared.Preferences; using Content.Shared.Preferences;
using Content.Shared.Text; using Content.Shared.Text;
using Robust.Client.Graphics.Drawing; using Robust.Client.Graphics.Drawing;
@@ -10,6 +13,7 @@ using Robust.Shared.Interfaces.Random;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Localization; using Robust.Shared.Localization;
using Robust.Shared.Maths; using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
using Robust.Shared.Random; using Robust.Shared.Random;
namespace Content.Client.UserInterface namespace Content.Client.UserInterface
@@ -34,6 +38,7 @@ namespace Content.Client.UserInterface
private readonly Button _sexMaleButton; private readonly Button _sexMaleButton;
private readonly HairStylePicker _hairPicker; private readonly HairStylePicker _hairPicker;
private readonly FacialHairStylePicker _facialHairPicker; private readonly FacialHairStylePicker _facialHairPicker;
private readonly List<JobPrioritySelector> _jobPriorities;
private bool _isDirty; private bool _isDirty;
public int CharacterSlot; public int CharacterSlot;
@@ -47,7 +52,7 @@ namespace Content.Client.UserInterface
} }
public HumanoidProfileEditor(ILocalizationManager localization, public HumanoidProfileEditor(ILocalizationManager localization,
IClientPreferencesManager preferencesManager) IClientPreferencesManager preferencesManager, IPrototypeManager prototypeManager)
{ {
Profile = (HumanoidCharacterProfile) preferencesManager.Preferences.SelectedCharacter; Profile = (HumanoidCharacterProfile) preferencesManager.Preferences.SelectedCharacter;
CharacterSlot = preferencesManager.Preferences.SelectedCharacterIndex; CharacterSlot = preferencesManager.Preferences.SelectedCharacterIndex;
@@ -90,9 +95,6 @@ namespace Content.Client.UserInterface
#endregion Randomize #endregion Randomize
var middleColumn = new VBoxContainer();
leftColumn.AddChild(middleColumn);
#region Name #region Name
{ {
@@ -130,76 +132,190 @@ namespace Content.Client.UserInterface
hBox.AddChild(_nameEdit); hBox.AddChild(_nameEdit);
hBox.AddChild(nameRandomButton); hBox.AddChild(nameRandomButton);
panel.AddChild(hBox); panel.AddChild(hBox);
middleColumn.AddChild(panel); leftColumn.AddChild(panel);
} }
#endregion Name #endregion Name
var sexAndAgeRow = new HBoxContainer var tabContainer = new TabContainer {SizeFlagsVertical = SizeFlags.FillExpand};
{ vBox.AddChild(tabContainer);
SeparationOverride = 10
};
middleColumn.AddChild(sexAndAgeRow);
#region Sex #region Appearance
{ {
var panel = HighlightedContainer(); var appearanceVBox = new VBoxContainer();
var hBox = new HBoxContainer(); tabContainer.AddChild(appearanceVBox);
var sexLabel = new Label {Text = localization.GetString("Sex:")}; tabContainer.SetTabTitle(0, Loc.GetString("Appearance"));
var sexButtonGroup = new ButtonGroup(); var sexAndAgeRow = new HBoxContainer
{
SeparationOverride = 10
};
appearanceVBox.AddChild(sexAndAgeRow);
#region Sex
_sexMaleButton = new Button
{ {
Text = localization.GetString("Male"), var panel = HighlightedContainer();
Group = sexButtonGroup var hBox = new HBoxContainer();
}; var sexLabel = new Label {Text = localization.GetString("Sex:")};
_sexMaleButton.OnPressed += args =>
var sexButtonGroup = new ButtonGroup();
_sexMaleButton = new Button
{
Text = localization.GetString("Male"),
Group = sexButtonGroup
};
_sexMaleButton.OnPressed += args =>
{
Profile = Profile?.WithSex(Sex.Male);
IsDirty = true;
};
_sexFemaleButton = new Button
{
Text = localization.GetString("Female"),
Group = sexButtonGroup
};
_sexFemaleButton.OnPressed += args =>
{
Profile = Profile?.WithSex(Sex.Female);
IsDirty = true;
};
hBox.AddChild(sexLabel);
hBox.AddChild(_sexMaleButton);
hBox.AddChild(_sexFemaleButton);
panel.AddChild(hBox);
sexAndAgeRow.AddChild(panel);
}
#endregion Sex
#region Age
{ {
Profile = Profile?.WithSex(Sex.Male); var panel = HighlightedContainer();
IsDirty = true; var hBox = new HBoxContainer();
}; var ageLabel = new Label {Text = localization.GetString("Age:")};
_sexFemaleButton = new Button _ageEdit = new LineEdit {CustomMinimumSize = (40, 0)};
_ageEdit.OnTextChanged += args =>
{
if (!int.TryParse(args.Text, out var newAge))
return;
Profile = Profile?.WithAge(newAge);
IsDirty = true;
};
hBox.AddChild(ageLabel);
hBox.AddChild(_ageEdit);
panel.AddChild(hBox);
sexAndAgeRow.AddChild(panel);
}
#endregion Age
#region Hair
{ {
Text = localization.GetString("Female"), var panel = HighlightedContainer();
Group = sexButtonGroup panel.SizeFlagsHorizontal = SizeFlags.None;
}; var hairHBox = new HBoxContainer();
_sexFemaleButton.OnPressed += args =>
{ _hairPicker = new HairStylePicker();
Profile = Profile?.WithSex(Sex.Female); _hairPicker.Populate();
IsDirty = true;
}; _hairPicker.OnHairStylePicked += newStyle =>
hBox.AddChild(sexLabel); {
hBox.AddChild(_sexMaleButton); if (Profile is null)
hBox.AddChild(_sexFemaleButton); return;
panel.AddChild(hBox); Profile = Profile.WithCharacterAppearance(
sexAndAgeRow.AddChild(panel); Profile.Appearance.WithHairStyleName(newStyle));
IsDirty = true;
};
_hairPicker.OnHairColorPicked += newColor =>
{
if (Profile is null)
return;
Profile = Profile.WithCharacterAppearance(
Profile.Appearance.WithHairColor(newColor));
IsDirty = true;
};
_facialHairPicker = new FacialHairStylePicker();
_facialHairPicker.Populate();
_facialHairPicker.OnHairStylePicked += newStyle =>
{
if (Profile is null)
return;
Profile = Profile.WithCharacterAppearance(
Profile.Appearance.WithFacialHairStyleName(newStyle));
IsDirty = true;
};
_facialHairPicker.OnHairColorPicked += newColor =>
{
if (Profile is null)
return;
Profile = Profile.WithCharacterAppearance(
Profile.Appearance.WithFacialHairColor(newColor));
IsDirty = true;
};
hairHBox.AddChild(_hairPicker);
hairHBox.AddChild(_facialHairPicker);
panel.AddChild(hairHBox);
appearanceVBox.AddChild(panel);
}
#endregion Hair
} }
#endregion Sex #endregion
#region Age #region Jobs
{ {
var panel = HighlightedContainer(); var jobList = new VBoxContainer();
var hBox = new HBoxContainer();
var ageLabel = new Label {Text = localization.GetString("Age:")}; tabContainer.AddChild(new ScrollContainer
_ageEdit = new LineEdit {CustomMinimumSize = (40, 0)};
_ageEdit.OnTextChanged += args =>
{ {
if (!int.TryParse(args.Text, out var newAge)) Children = {jobList}
return; });
Profile = Profile?.WithAge(newAge);
IsDirty = true; tabContainer.SetTabTitle(1, Loc.GetString("Jobs"));
};
hBox.AddChild(ageLabel); _jobPriorities = new List<JobPrioritySelector>();
hBox.AddChild(_ageEdit);
panel.AddChild(hBox); foreach (var job in prototypeManager.EnumeratePrototypes<JobPrototype>().OrderBy(j => j.Name))
sexAndAgeRow.AddChild(panel); {
var selector = new JobPrioritySelector(job);
jobList.AddChild(selector);
_jobPriorities.Add(selector);
selector.PriorityChanged += priority =>
{
Profile = Profile.WithJobPriority(job.ID, priority);
IsDirty = true;
if (priority == JobPriority.High)
{
// Lower any other high priorities to medium.
foreach (var jobSelector in _jobPriorities)
{
if (jobSelector != selector && jobSelector.Priority == JobPriority.High)
{
jobSelector.Priority = JobPriority.Medium;
}
}
}
};
}
} }
#endregion Age #endregion
var rightColumn = new VBoxContainer(); var rightColumn = new VBoxContainer();
middleContainer.AddChild(rightColumn); middleContainer.AddChild(rightColumn);
@@ -250,65 +366,9 @@ namespace Content.Client.UserInterface
#endregion Save #endregion Save
#region Hair
{
var panel = HighlightedContainer();
panel.SizeFlagsHorizontal = SizeFlags.None;
var hairHBox = new HBoxContainer();
_hairPicker = new HairStylePicker();
_hairPicker.Populate();
_hairPicker.OnHairStylePicked += newStyle =>
{
if (Profile is null)
return;
Profile = Profile.WithCharacterAppearance(
Profile.Appearance.WithHairStyleName(newStyle));
IsDirty = true;
};
_hairPicker.OnHairColorPicked += newColor =>
{
if (Profile is null)
return;
Profile = Profile.WithCharacterAppearance(
Profile.Appearance.WithHairColor(newColor));
IsDirty = true;
};
_facialHairPicker = new FacialHairStylePicker();
_facialHairPicker.Populate();
_facialHairPicker.OnHairStylePicked += newStyle =>
{
if (Profile is null)
return;
Profile = Profile.WithCharacterAppearance(
Profile.Appearance.WithFacialHairStyleName(newStyle));
IsDirty = true;
};
_facialHairPicker.OnHairColorPicked += newColor =>
{
if (Profile is null)
return;
Profile = Profile.WithCharacterAppearance(
Profile.Appearance.WithFacialHairColor(newColor));
IsDirty = true;
};
hairHBox.AddChild(_hairPicker);
hairHBox.AddChild(_facialHairPicker);
panel.AddChild(hairHBox);
vBox.AddChild(panel);
}
#endregion Hair
UpdateControls(); UpdateControls();
IsDirty = false;
} }
private bool IsDirty private bool IsDirty
@@ -360,6 +420,58 @@ namespace Content.Client.UserInterface
_ageEdit.Text = Profile?.Age.ToString(); _ageEdit.Text = Profile?.Age.ToString();
UpdateHairPickers(); UpdateHairPickers();
UpdateSaveButton(); UpdateSaveButton();
UpdateJobPriorities();
}
private void UpdateJobPriorities()
{
foreach (var prioritySelector in _jobPriorities)
{
var jobId = prioritySelector.Job.ID;
var priority = Profile.JobPriorities.GetValueOrDefault(jobId, JobPriority.Never);
prioritySelector.Priority = priority;
}
}
private class JobPrioritySelector : Control
{
public JobPrototype Job { get; }
private readonly OptionButton _optionButton;
public JobPriority Priority
{
get => (JobPriority) _optionButton.SelectedId;
set => _optionButton.SelectId((int) value);
}
public event Action<JobPriority> PriorityChanged;
public JobPrioritySelector(JobPrototype job)
{
Job = job;
_optionButton = new OptionButton();
_optionButton.AddItem(Loc.GetString("High"), (int) JobPriority.High);
_optionButton.AddItem(Loc.GetString("Medium"), (int) JobPriority.Medium);
_optionButton.AddItem(Loc.GetString("Low"), (int) JobPriority.Low);
_optionButton.AddItem(Loc.GetString("Never"), (int) JobPriority.Never);
_optionButton.OnItemSelected += args =>
{
_optionButton.SelectId(args.Id);
PriorityChanged?.Invoke(Priority);
};
AddChild(new HBoxContainer
{
Children =
{
new Label {Text = job.Name, CustomMinimumSize = (175, 0)},
_optionButton
}
});
}
} }
} }
} }

View File

@@ -0,0 +1,142 @@
// <auto-generated />
using Content.Server.Database;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace Content.Server.Database.Migrations
{
[DbContext(typeof(PreferencesDbContext))]
[Migration("20200118195640_jobs")]
partial class jobs
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.0");
modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b =>
{
b.Property<int>("HumanoidProfileId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("Age")
.HasColumnType("INTEGER");
b.Property<string>("CharacterName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("EyeColor")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("FacialHairColor")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("FacialHairName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("HairColor")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("HairName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("PrefsId")
.HasColumnType("INTEGER");
b.Property<string>("Sex")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("SkinColor")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("Slot")
.HasColumnType("INTEGER");
b.Property<string>("SlotName")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("HumanoidProfileId");
b.HasIndex("PrefsId");
b.ToTable("HumanoidProfile");
});
modelBuilder.Entity("Content.Server.Database.Job", b =>
{
b.Property<int>("JobId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("JobName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("Priority")
.HasColumnType("INTEGER");
b.Property<int>("ProfileHumanoidProfileId")
.HasColumnType("INTEGER");
b.HasKey("JobId");
b.HasIndex("ProfileHumanoidProfileId");
b.ToTable("Job");
});
modelBuilder.Entity("Content.Server.Database.Prefs", b =>
{
b.Property<int>("PrefsId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("SelectedCharacterSlot")
.HasColumnType("INTEGER");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("PrefsId");
b.HasIndex("Username")
.IsUnique();
b.ToTable("Preferences");
});
modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b =>
{
b.HasOne("Content.Server.Database.Prefs", "Prefs")
.WithMany("HumanoidProfiles")
.HasForeignKey("PrefsId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Content.Server.Database.Job", b =>
{
b.HasOne("Content.Server.Database.HumanoidProfile", "Profile")
.WithMany("Jobs")
.HasForeignKey("ProfileHumanoidProfileId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,42 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace Content.Server.Database.Migrations
{
public partial class jobs : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Job",
columns: table => new
{
JobId = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
ProfileHumanoidProfileId = table.Column<int>(nullable: false),
JobName = table.Column<string>(nullable: false),
Priority = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Job", x => x.JobId);
table.ForeignKey(
name: "FK_Job_HumanoidProfile_ProfileHumanoidProfileId",
column: x => x.ProfileHumanoidProfileId,
principalTable: "HumanoidProfile",
principalColumn: "HumanoidProfileId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Job_ProfileHumanoidProfileId",
table: "Job",
column: "ProfileHumanoidProfileId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Job");
}
}
}

View File

@@ -73,6 +73,29 @@ namespace Content.Server.Database.Migrations
b.ToTable("HumanoidProfile"); b.ToTable("HumanoidProfile");
}); });
modelBuilder.Entity("Content.Server.Database.Job", b =>
{
b.Property<int>("JobId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("JobName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("Priority")
.HasColumnType("INTEGER");
b.Property<int>("ProfileHumanoidProfileId")
.HasColumnType("INTEGER");
b.HasKey("JobId");
b.HasIndex("ProfileHumanoidProfileId");
b.ToTable("Job");
});
modelBuilder.Entity("Content.Server.Database.Prefs", b => modelBuilder.Entity("Content.Server.Database.Prefs", b =>
{ {
b.Property<int>("PrefsId") b.Property<int>("PrefsId")
@@ -102,6 +125,15 @@ namespace Content.Server.Database.Migrations
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
}); });
modelBuilder.Entity("Content.Server.Database.Job", b =>
{
b.HasOne("Content.Server.Database.HumanoidProfile", "Profile")
.WithMany("Jobs")
.HasForeignKey("ProfileHumanoidProfileId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618 #pragma warning restore 612, 618
} }
} }

View File

@@ -47,8 +47,27 @@ namespace Content.Server.Database
public string FacialHairColor { get; set; } = null!; public string FacialHairColor { get; set; } = null!;
public string EyeColor { get; set; } = null!; public string EyeColor { get; set; } = null!;
public string SkinColor { get; set; } = null!; public string SkinColor { get; set; } = null!;
public List<Job> Jobs { get; } = new List<Job>();
public int PrefsId { get; set; } public int PrefsId { get; set; }
public Prefs Prefs { get; set; } = null!; public Prefs Prefs { get; set; } = null!;
} }
public class Job
{
public int JobId { get; set; }
public HumanoidProfile Profile { get; set; } = null!;
public string JobName { get; set; } = null!;
public DbJobPriority Priority { get; set; }
}
public enum DbJobPriority
{
// These enum values HAVE to match the ones in JobPriority in Shared.
Never = 0,
Low = 1,
Medium = 2,
High = 3
}
} }

View File

@@ -21,6 +21,7 @@ namespace Content.Server.Database
return _prefsCtx return _prefsCtx
.Preferences .Preferences
.Include(p => p.HumanoidProfiles) .Include(p => p.HumanoidProfiles)
.ThenInclude(h => h.Jobs)
.SingleOrDefault(p => p.Username == username); .SingleOrDefault(p => p.Username == username);
} }

View File

@@ -30,6 +30,8 @@ namespace Content.Server.Preferences
var profiles = new ICharacterProfile[_maxCharacterSlots]; var profiles = new ICharacterProfile[_maxCharacterSlots];
foreach (var profile in prefs.HumanoidProfiles) foreach (var profile in prefs.HumanoidProfiles)
{ {
var jobs = profile.Jobs.ToDictionary(j => j.JobName, j => (JobPriority) j.Priority);
profiles[profile.Slot] = new HumanoidCharacterProfile( profiles[profile.Slot] = new HumanoidCharacterProfile(
profile.CharacterName, profile.CharacterName,
profile.Age, profile.Age,
@@ -42,7 +44,8 @@ namespace Content.Server.Preferences
Color.FromHex(profile.FacialHairColor), Color.FromHex(profile.FacialHairColor),
Color.FromHex(profile.EyeColor), Color.FromHex(profile.EyeColor),
Color.FromHex(profile.SkinColor) Color.FromHex(profile.SkinColor)
) ),
jobs
); );
} }
@@ -73,7 +76,7 @@ namespace Content.Server.Preferences
// TODO: Handle other ICharacterProfile implementations properly // TODO: Handle other ICharacterProfile implementations properly
throw new NotImplementedException(); throw new NotImplementedException();
var appearance = (HumanoidCharacterAppearance) humanoid.CharacterAppearance; var appearance = (HumanoidCharacterAppearance) humanoid.CharacterAppearance;
_prefsDb.SaveCharacterSlot(username, new HumanoidProfile var entity = new HumanoidProfile
{ {
SlotName = humanoid.Name, SlotName = humanoid.Name,
CharacterName = humanoid.Name, CharacterName = humanoid.Name,
@@ -86,7 +89,13 @@ namespace Content.Server.Preferences
EyeColor = appearance.EyeColor.ToHex(), EyeColor = appearance.EyeColor.ToHex(),
SkinColor = appearance.SkinColor.ToHex(), SkinColor = appearance.SkinColor.ToHex(),
Slot = slot Slot = slot
}); };
entity.Jobs.AddRange(
humanoid.JobPriorities
.Where(j => j.Value != JobPriority.Never)
.Select(j => new Job {JobName = j.Key, Priority = (DbJobPriority) j.Value})
);
_prefsDb.SaveCharacterSlot(username, entity);
} }
private void DeleteCharacterSlot(string username, int slot) private void DeleteCharacterSlot(string username, int slot)

View File

@@ -1,4 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
namespace Content.Shared.Preferences namespace Content.Shared.Preferences
@@ -6,20 +8,34 @@ namespace Content.Shared.Preferences
[Serializable, NetSerializable] [Serializable, NetSerializable]
public class HumanoidCharacterProfile : ICharacterProfile public class HumanoidCharacterProfile : ICharacterProfile
{ {
public HumanoidCharacterProfile(string name, private readonly Dictionary<string, JobPriority> _jobPriorities;
private HumanoidCharacterProfile(string name,
int age, int age,
Sex sex, Sex sex,
HumanoidCharacterAppearance appearance) HumanoidCharacterAppearance appearance,
Dictionary<string, JobPriority> jobPriorities)
{ {
Name = name; Name = name;
Age = age; Age = age;
Sex = sex; Sex = sex;
Appearance = appearance; Appearance = appearance;
_jobPriorities = jobPriorities;
}
public HumanoidCharacterProfile(string name,
int age,
Sex sex,
HumanoidCharacterAppearance appearance,
IReadOnlyDictionary<string, JobPriority> jobPriorities)
: this(name, age, sex, appearance, new Dictionary<string, JobPriority>(jobPriorities))
{
} }
public static HumanoidCharacterProfile Default() public static HumanoidCharacterProfile Default()
{ {
return new HumanoidCharacterProfile("John Doe", 18, Sex.Male, HumanoidCharacterAppearance.Default()); return new HumanoidCharacterProfile("John Doe", 18, Sex.Male, HumanoidCharacterAppearance.Default(),
new Dictionary<string, JobPriority>());
} }
public string Name { get; } public string Name { get; }
@@ -27,28 +43,50 @@ namespace Content.Shared.Preferences
public Sex Sex { get; } public Sex Sex { get; }
public ICharacterAppearance CharacterAppearance => Appearance; public ICharacterAppearance CharacterAppearance => Appearance;
public HumanoidCharacterAppearance Appearance { get; } public HumanoidCharacterAppearance Appearance { get; }
public IReadOnlyDictionary<string, JobPriority> JobPriorities => _jobPriorities;
public HumanoidCharacterProfile WithName(string name) public HumanoidCharacterProfile WithName(string name)
{ {
return new HumanoidCharacterProfile(name, Age, Sex, Appearance); return new HumanoidCharacterProfile(name, Age, Sex, Appearance, _jobPriorities);
} }
public HumanoidCharacterProfile WithAge(int age) public HumanoidCharacterProfile WithAge(int age)
{ {
return new HumanoidCharacterProfile(Name, age, Sex, Appearance); return new HumanoidCharacterProfile(Name, age, Sex, Appearance, _jobPriorities);
} }
public HumanoidCharacterProfile WithSex(Sex sex) public HumanoidCharacterProfile WithSex(Sex sex)
{ {
return new HumanoidCharacterProfile(Name, Age, sex, Appearance); return new HumanoidCharacterProfile(Name, Age, sex, Appearance, _jobPriorities);
} }
public HumanoidCharacterProfile WithCharacterAppearance(HumanoidCharacterAppearance appearance) public HumanoidCharacterProfile WithCharacterAppearance(HumanoidCharacterAppearance appearance)
{ {
return new HumanoidCharacterProfile(Name, Age, Sex, appearance); return new HumanoidCharacterProfile(Name, Age, Sex, appearance, _jobPriorities);
} }
public string Summary => $"{Name}, {Age} years old {Sex.ToString().ToLower()} human.\nOccupation: to be implemented."; public HumanoidCharacterProfile WithJobPriorities(IReadOnlyDictionary<string, JobPriority> jobPriorities)
{
return new HumanoidCharacterProfile(Name, Age, Sex, Appearance, new Dictionary<string, JobPriority>(jobPriorities));
}
public HumanoidCharacterProfile WithJobPriority(string jobId, JobPriority priority)
{
var dictionary = new Dictionary<string, JobPriority>(_jobPriorities);
if (priority == JobPriority.Never)
{
dictionary.Remove(jobId);
}
else
{
dictionary[jobId] = priority;
}
return new HumanoidCharacterProfile(Name, Age, Sex, Appearance, dictionary);
}
public string Summary =>
$"{Name}, {Age} years old {Sex.ToString().ToLower()} human.";
public bool MemberwiseEquals(ICharacterProfile maybeOther) public bool MemberwiseEquals(ICharacterProfile maybeOther)
{ {
@@ -56,6 +94,7 @@ namespace Content.Shared.Preferences
if (Name != other.Name) return false; if (Name != other.Name) return false;
if (Age != other.Age) return false; if (Age != other.Age) return false;
if (Sex != other.Sex) return false; if (Sex != other.Sex) return false;
if (!_jobPriorities.SequenceEqual(other._jobPriorities)) return false;
return Appearance.MemberwiseEquals(other.Appearance); return Appearance.MemberwiseEquals(other.Appearance);
} }
} }

View File

@@ -0,0 +1,11 @@
namespace Content.Shared.Preferences
{
public enum JobPriority
{
// These enum values HAVE to match the ones in DbJobPriority in Server.Database.
Never = 0,
Low = 1,
Medium = 2,
High = 3
}
}

View File

@@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Content.Server.Preferences; using Content.Server.Preferences;
@@ -26,7 +27,11 @@ namespace Content.Tests.Server.Preferences
Color.Aquamarine, Color.Aquamarine,
Color.Azure, Color.Azure,
Color.Beige Color.Beige
) ),
new Dictionary<string, JobPriority>
{
{"Assistant", JobPriority.High}
}
); );
} }