From 6b5cded8c2a3947baee2b04b6948340c3cb7a84e Mon Sep 17 00:00:00 2001 From: 20kdc Date: Thu, 24 Dec 2020 13:42:40 +0000 Subject: [PATCH] Clothing and pronoun fields (#2689) * Clothing & Gender fields: Add to database [MODIFIED TO NOT DEPEND ON SAPHIRE-DB-REFACTOR] Sorry about this, Saphire. * Clothing & Gender fields: Add UI [FALLBACK II] * Clothing & Gender fields: Actually apply gender * Clothing & Gender fields: Import innerclothingskirt field from my previous attempt Couldn't import actual prototypes because of a change to IDs * Clothing & Gender fields: Add innerclothingskirt field to everything * Clothing & Gender fields: Jumpskirts now work * Clothing & Gender fields: Gender field will follow sex field if it's not different (UX improvement) [FALLBACK II] * Clothing & Gender fields: Gender -> Pronouns to reduce confusion. Also, fix profile summary. Properly. [FALLBACK II] * Clothing & Pronoun fields: Refactor so that profile equipment adjustments are performed in StartingGearPrototype. --- .../HumanoidProfileEditor.Random.cs | 2 + .../UserInterface/HumanoidProfileEditor.cs | 107 +++- .../LobbyCharacterPreviewPanel.cs | 15 +- Content.IntegrationTests/DummyGameTicker.cs | 3 +- ...1203093409_ClothingAndPronouns.Designer.cs | 570 ++++++++++++++++++ .../20201203093409_ClothingAndPronouns.cs | 35 ++ .../PostgresServerDbContextModelSnapshot.cs | 299 +++++---- ...1203093351_ClothingAndPronouns.Designer.cs | 537 +++++++++++++++++ .../20201203093351_ClothingAndPronouns.cs | 35 ++ .../SqliteServerDbContextModelSnapshot.cs | 295 +++++---- Content.Server.Database/Model.cs | 2 + Content.Server/Database/ServerDbBase.cs | 20 +- .../Movement/AiControllerComponent.cs | 4 +- Content.Server/GameTicking/GameTicker.cs | 35 +- .../Interfaces/GameTicking/IGameTicker.cs | 3 +- .../Mobs/SharedHumanoidAppearanceComponent.cs | 24 +- .../Preferences/ClothingPreference.cs | 11 + .../Preferences/HumanoidCharacterProfile.cs | 125 ++-- Content.Shared/Preferences/Sex.cs | 3 +- Content.Shared/Roles/StartingGearPrototype.cs | 35 +- .../Server/Preferences/ServerDbSqliteTests.cs | 4 + .../Roles/Jobs/Cargo/cargo_technician.yml | 2 + .../Roles/Jobs/Cargo/quartermaster.yml | 2 + .../Roles/Jobs/Civilian/assistant.yml | 2 + .../Roles/Jobs/Civilian/bartender.yml | 2 + .../Roles/Jobs/Civilian/botanist.yml | 2 + .../Roles/Jobs/Civilian/chaplain.yml | 3 +- .../Prototypes/Roles/Jobs/Civilian/chef.yml | 2 + .../Roles/Jobs/Civilian/janitor.yml | 2 + .../Prototypes/Roles/Jobs/Civilian/mime.yml | 2 + .../Roles/Jobs/Command/head_of_personnel.yml | 2 + .../Roles/Jobs/Engineering/chief_engineer.yml | 2 + .../Jobs/Engineering/station_engineer.yml | 2 + .../Jobs/Medical/chief_medical_officer.yml | 2 + .../Roles/Jobs/Medical/medical_doctor.yml | 2 + .../Roles/Jobs/Science/research_director.yml | 2 + .../Roles/Jobs/Science/scientist.yml | 2 + .../Roles/Jobs/Security/head_of_security.yml | 2 + .../Roles/Jobs/Security/security_officer.yml | 2 + .../Prototypes/Roles/Jobs/Security/warden.yml | 2 + 40 files changed, 1866 insertions(+), 337 deletions(-) create mode 100644 Content.Server.Database/Migrations/Postgres/20201203093409_ClothingAndPronouns.Designer.cs create mode 100644 Content.Server.Database/Migrations/Postgres/20201203093409_ClothingAndPronouns.cs create mode 100644 Content.Server.Database/Migrations/Sqlite/20201203093351_ClothingAndPronouns.Designer.cs create mode 100644 Content.Server.Database/Migrations/Sqlite/20201203093351_ClothingAndPronouns.cs create mode 100644 Content.Shared/Preferences/ClothingPreference.cs diff --git a/Content.Client/UserInterface/HumanoidProfileEditor.Random.cs b/Content.Client/UserInterface/HumanoidProfileEditor.Random.cs index 65f039fd08..761e88d751 100644 --- a/Content.Client/UserInterface/HumanoidProfileEditor.Random.cs +++ b/Content.Client/UserInterface/HumanoidProfileEditor.Random.cs @@ -17,6 +17,8 @@ namespace Content.Client.UserInterface { Profile = HumanoidCharacterProfile.Random(); UpdateSexControls(); + UpdateGenderControls(); + UpdateClothingControls(); UpdateAgeEdit(); UpdateNameEdit(); UpdateHairPickers(); diff --git a/Content.Client/UserInterface/HumanoidProfileEditor.cs b/Content.Client/UserInterface/HumanoidProfileEditor.cs index 3ab41fa719..4c38b7cbee 100644 --- a/Content.Client/UserInterface/HumanoidProfileEditor.cs +++ b/Content.Client/UserInterface/HumanoidProfileEditor.cs @@ -17,6 +17,7 @@ using Robust.Shared.Map; using Robust.Shared.Maths; using Robust.Shared.Prototypes; using Robust.Shared.Utility; +using Robust.Shared.Localization.Macros; using System; using System.Collections.Generic; using System.Linq; @@ -40,7 +41,8 @@ namespace Content.Client.UserInterface private readonly Button _saveButton; private readonly Button _sexFemaleButton; private readonly Button _sexMaleButton; - private readonly Button _sexClassifiedButton; + private readonly OptionButton _genderButton; + private readonly OptionButton _clothingButton; private readonly HairStylePicker _hairPicker; private readonly FacialHairStylePicker _facialHairPicker; @@ -165,27 +167,34 @@ namespace Content.Client.UserInterface Text = Loc.GetString("Male"), Group = sexButtonGroup }; - _sexMaleButton.OnPressed += args => { SetSex(Sex.Male); }; + _sexMaleButton.OnPressed += args => + { + SetSex(Sex.Male); + if (Profile.Gender == Gender.Female) + { + SetGender(Gender.Male); + UpdateGenderControls(); + } + }; _sexFemaleButton = new Button { Text = Loc.GetString("Female"), Group = sexButtonGroup }; - _sexFemaleButton.OnPressed += args => { SetSex(Sex.Female); }; - - _sexClassifiedButton = new Button + _sexFemaleButton.OnPressed += args => { - /* DUR WHAT IF I PUT ATTACK HELICOPTER HERE DUR HUR AHUHRUHWUIDHAEILUBFOWEL(*&RFH#W*(OBFD&*/ - Text = Loc.GetString("Classified"), - Group = sexButtonGroup + SetSex(Sex.Female); + if (Profile.Gender == Gender.Male) + { + SetGender(Gender.Female); + UpdateGenderControls(); + } }; - _sexClassifiedButton.OnPressed += args => { SetSex(Sex.Classified); }; hBox.AddChild(sexLabel); hBox.AddChild(_sexMaleButton); hBox.AddChild(_sexFemaleButton); - hBox.AddChild(_sexClassifiedButton); panel.AddChild(hBox); sexAndAgeRow.AddChild(panel); } @@ -213,6 +222,34 @@ namespace Content.Client.UserInterface #endregion Age + #region Gender + + { + var panel = HighlightedContainer(); + var hBox = new HBoxContainer(); + var genderLabel = new Label { Text = Loc.GetString("Pronouns:") }; + + _genderButton = new OptionButton(); + + _genderButton.AddItem(Loc.GetString("He / Him"), (int) Gender.Male); + _genderButton.AddItem(Loc.GetString("She / Her"), (int) Gender.Female); + _genderButton.AddItem(Loc.GetString("They / Them"), (int) Gender.Epicene); + _genderButton.AddItem(Loc.GetString("It / It"), (int) Gender.Neuter); + + _genderButton.OnItemSelected += args => + { + _genderButton.SelectId(args.Id); + SetGender((Gender) args.Id); + }; + + hBox.AddChild(genderLabel); + hBox.AddChild(_genderButton); + panel.AddChild(hBox); + sexAndAgeRow.AddChild(panel); + } + + #endregion Gender + #region Hair { @@ -270,6 +307,32 @@ namespace Content.Client.UserInterface } #endregion Hair + + #region Clothing + + { + var panel = HighlightedContainer(); + var hBox = new HBoxContainer(); + var clothingLabel = new Label { Text = Loc.GetString("Clothing:") }; + + _clothingButton = new OptionButton(); + + _clothingButton.AddItem(Loc.GetString("Jumpsuit"), (int) ClothingPreference.Jumpsuit); + _clothingButton.AddItem(Loc.GetString("Jumpskirt"), (int) ClothingPreference.Jumpskirt); + + _clothingButton.OnItemSelected += args => + { + _clothingButton.SelectId(args.Id); + SetClothing((ClothingPreference) args.Id); + }; + + hBox.AddChild(clothingLabel); + hBox.AddChild(_clothingButton); + panel.AddChild(hBox); + appearanceVBox.AddChild(panel); + } + + #endregion Clothing } #endregion @@ -588,12 +651,24 @@ namespace Content.Client.UserInterface IsDirty = true; } + private void SetGender(Gender newGender) + { + Profile = Profile?.WithGender(newGender); + IsDirty = true; + } + private void SetName(string newName) { Profile = Profile?.WithName(newName); IsDirty = true; } + private void SetClothing(ClothingPreference newClothing) + { + Profile = Profile?.WithClothingPreference(newClothing); + IsDirty = true; + } + public void Save() { IsDirty = false; @@ -638,6 +713,16 @@ namespace Content.Client.UserInterface _sexFemaleButton.Pressed = true; } + private void UpdateGenderControls() + { + _genderButton.SelectId((int) Profile.Gender); + } + + private void UpdateClothingControls() + { + _clothingButton.SelectId((int) Profile.Clothing); + } + private void UpdateHairPickers() { _hairPicker.SetData( @@ -667,6 +752,8 @@ namespace Content.Client.UserInterface if (Profile is null) return; UpdateNameEdit(); UpdateSexControls(); + UpdateGenderControls(); + UpdateClothingControls(); UpdateAgeEdit(); UpdateHairPickers(); UpdateSaveButton(); diff --git a/Content.Client/UserInterface/LobbyCharacterPreviewPanel.cs b/Content.Client/UserInterface/LobbyCharacterPreviewPanel.cs index f0ffd50b59..21552467f9 100644 --- a/Content.Client/UserInterface/LobbyCharacterPreviewPanel.cs +++ b/Content.Client/UserInterface/LobbyCharacterPreviewPanel.cs @@ -6,6 +6,7 @@ using Content.Shared; using Content.Shared.GameTicking; using Content.Shared.Preferences; using Content.Shared.Roles; +using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines; using Robust.Client.Interfaces.GameObjects.Components; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; @@ -140,13 +141,15 @@ namespace Content.Client.UserInterface inventory.ClearAllSlotVisuals(); - foreach (var (slot, itemType) in gear.Equipment) + foreach (var slot in AllSlots) { - var item = entityMan.SpawnEntity(itemType, MapCoordinates.Nullspace); - - inventory.SetSlotVisuals(slot, item); - - item.Delete(); + var itemType = gear.GetGear(slot, profile); + if (itemType != "") + { + var item = entityMan.SpawnEntity(itemType, MapCoordinates.Nullspace); + inventory.SetSlotVisuals(slot, item); + item.Delete(); + } } } } diff --git a/Content.IntegrationTests/DummyGameTicker.cs b/Content.IntegrationTests/DummyGameTicker.cs index 0f1a706a4d..9a98794513 100644 --- a/Content.IntegrationTests/DummyGameTicker.cs +++ b/Content.IntegrationTests/DummyGameTicker.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using Content.Server.GameTicking; using Content.Server.Interfaces.GameTicking; using Content.Shared.Roles; +using Content.Shared.Preferences; using Content.Server.Mobs; using Robust.Server.Interfaces.Player; using Robust.Server.Interfaces.Console; @@ -76,7 +77,7 @@ namespace Content.IntegrationTests public EntityCoordinates GetJobSpawnPoint(string jobId) => EntityCoordinates.Invalid; public EntityCoordinates GetObserverSpawnPoint() => EntityCoordinates.Invalid; - public void EquipStartingGear(IEntity entity, StartingGearPrototype startingGear) + public void EquipStartingGear(IEntity entity, StartingGearPrototype startingGear, HumanoidCharacterProfile profile) { } diff --git a/Content.Server.Database/Migrations/Postgres/20201203093409_ClothingAndPronouns.Designer.cs b/Content.Server.Database/Migrations/Postgres/20201203093409_ClothingAndPronouns.Designer.cs new file mode 100644 index 0000000000..9fd3c7c83d --- /dev/null +++ b/Content.Server.Database/Migrations/Postgres/20201203093409_ClothingAndPronouns.Designer.cs @@ -0,0 +1,570 @@ +// +using System; +using System.Net; +using Content.Server.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Content.Server.Database.Migrations.Postgres +{ + [DbContext(typeof(PostgresServerDbContext))] + [Migration("20201203093409_ClothingAndPronouns")] + partial class ClothingAndPronouns + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .UseIdentityByDefaultColumns() + .HasAnnotation("Relational:MaxIdentifierLength", 63) + .HasAnnotation("ProductVersion", "5.0.0"); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.Property("AdminRankId") + .HasColumnType("integer") + .HasColumnName("admin_rank_id"); + + b.Property("Title") + .HasColumnType("text") + .HasColumnName("title"); + + b.HasKey("UserId"); + + b.HasIndex("AdminRankId"); + + b.ToTable("admin"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminFlag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("admin_flag_id") + .UseIdentityByDefaultColumn(); + + b.Property("AdminId") + .HasColumnType("uuid") + .HasColumnName("admin_id"); + + b.Property("Flag") + .IsRequired() + .HasColumnType("text") + .HasColumnName("flag"); + + b.Property("Negative") + .HasColumnType("boolean") + .HasColumnName("negative"); + + b.HasKey("Id"); + + b.HasIndex("AdminId"); + + b.HasIndex("Flag", "AdminId") + .IsUnique(); + + b.ToTable("admin_flag"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRank", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("admin_rank_id") + .UseIdentityByDefaultColumn(); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id"); + + b.ToTable("admin_rank"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRankFlag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("admin_rank_flag_id") + .UseIdentityByDefaultColumn(); + + b.Property("AdminRankId") + .HasColumnType("integer") + .HasColumnName("admin_rank_id"); + + b.Property("Flag") + .IsRequired() + .HasColumnType("text") + .HasColumnName("flag"); + + b.HasKey("Id"); + + b.HasIndex("AdminRankId"); + + b.HasIndex("Flag", "AdminRankId") + .IsUnique(); + + b.ToTable("admin_rank_flag"); + }); + + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("antag_id") + .UseIdentityByDefaultColumn(); + + b.Property("AntagName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("antag_name"); + + b.Property("ProfileId") + .HasColumnType("integer") + .HasColumnName("profile_id"); + + b.HasKey("Id"); + + b.HasIndex("ProfileId", "AntagName") + .IsUnique(); + + b.ToTable("antag"); + }); + + modelBuilder.Entity("Content.Server.Database.AssignedUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("assigned_user_id_id") + .UseIdentityByDefaultColumn(); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("user_name"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.HasIndex("UserName") + .IsUnique(); + + b.ToTable("assigned_user_id"); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("job_id") + .UseIdentityByDefaultColumn(); + + b.Property("JobName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("job_name"); + + b.Property("Priority") + .HasColumnType("integer") + .HasColumnName("priority"); + + b.Property("ProfileId") + .HasColumnType("integer") + .HasColumnName("profile_id"); + + b.HasKey("Id"); + + b.HasIndex("ProfileId"); + + b.ToTable("job"); + }); + + modelBuilder.Entity("Content.Server.Database.PostgresConnectionLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("connection_log_id") + .UseIdentityByDefaultColumn(); + + b.Property("Address") + .IsRequired() + .HasColumnType("inet") + .HasColumnName("address"); + + b.Property("Time") + .HasColumnType("timestamp with time zone") + .HasColumnName("time"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("user_name"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("connection_log"); + + b.HasCheckConstraint("AddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= address"); + }); + + modelBuilder.Entity("Content.Server.Database.PostgresPlayer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("player_id") + .UseIdentityByDefaultColumn(); + + b.Property("FirstSeenTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("first_seen_time"); + + b.Property("LastSeenAddress") + .IsRequired() + .HasColumnType("inet") + .HasColumnName("last_seen_address"); + + b.Property("LastSeenTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_seen_time"); + + b.Property("LastSeenUserName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("last_seen_user_name"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("LastSeenUserName"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("player"); + + b.HasCheckConstraint("LastSeenAddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= last_seen_address"); + }); + + modelBuilder.Entity("Content.Server.Database.PostgresServerBan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("server_ban_id") + .UseIdentityByDefaultColumn(); + + b.Property?>("Address") + .HasColumnType("inet") + .HasColumnName("address"); + + b.Property("BanTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("ban_time"); + + b.Property("BanningAdmin") + .HasColumnType("uuid") + .HasColumnName("banning_admin"); + + b.Property("ExpirationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiration_time"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("text") + .HasColumnName("reason"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("Address"); + + b.HasIndex("UserId"); + + b.ToTable("server_ban"); + + b.HasCheckConstraint("AddressNotIPv6MappedIPv4", "NOT inet '::ffff:0.0.0.0/96' >>= address"); + + b.HasCheckConstraint("HaveEitherAddressOrUserId", "address IS NOT NULL OR user_id IS NOT NULL"); + }); + + modelBuilder.Entity("Content.Server.Database.PostgresServerUnban", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("unban_id") + .UseIdentityByDefaultColumn(); + + b.Property("BanId") + .HasColumnType("integer") + .HasColumnName("ban_id"); + + b.Property("UnbanTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("unban_time"); + + b.Property("UnbanningAdmin") + .HasColumnType("uuid") + .HasColumnName("unbanning_admin"); + + b.HasKey("Id"); + + b.HasIndex("BanId") + .IsUnique(); + + b.ToTable("server_unban"); + }); + + modelBuilder.Entity("Content.Server.Database.Preference", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("preference_id") + .UseIdentityByDefaultColumn(); + + b.Property("SelectedCharacterSlot") + .HasColumnType("integer") + .HasColumnName("selected_character_slot"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("preference"); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("profile_id") + .UseIdentityByDefaultColumn(); + + b.Property("Age") + .HasColumnType("integer") + .HasColumnName("age"); + + b.Property("CharacterName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("char_name"); + + b.Property("Clothing") + .IsRequired() + .HasColumnType("text") + .HasColumnName("clothing"); + + b.Property("EyeColor") + .IsRequired() + .HasColumnType("text") + .HasColumnName("eye_color"); + + b.Property("FacialHairColor") + .IsRequired() + .HasColumnType("text") + .HasColumnName("facial_hair_color"); + + b.Property("FacialHairName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("facial_hair_name"); + + b.Property("Gender") + .IsRequired() + .HasColumnType("text") + .HasColumnName("gender"); + + b.Property("HairColor") + .IsRequired() + .HasColumnType("text") + .HasColumnName("hair_color"); + + b.Property("HairName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("hair_name"); + + b.Property("PreferenceId") + .HasColumnType("integer") + .HasColumnName("preference_id"); + + b.Property("PreferenceUnavailable") + .HasColumnType("integer") + .HasColumnName("pref_unavailable"); + + b.Property("Sex") + .IsRequired() + .HasColumnType("text") + .HasColumnName("sex"); + + b.Property("SkinColor") + .IsRequired() + .HasColumnType("text") + .HasColumnName("skin_color"); + + b.Property("Slot") + .HasColumnType("integer") + .HasColumnName("slot"); + + b.HasKey("Id"); + + b.HasIndex("PreferenceId"); + + b.HasIndex("Slot", "PreferenceId") + .IsUnique(); + + b.ToTable("profile"); + }); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.HasOne("Content.Server.Database.AdminRank", "AdminRank") + .WithMany("Admins") + .HasForeignKey("AdminRankId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("AdminRank"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminFlag", b => + { + b.HasOne("Content.Server.Database.Admin", "Admin") + .WithMany("Flags") + .HasForeignKey("AdminId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Admin"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRankFlag", b => + { + b.HasOne("Content.Server.Database.AdminRank", "Rank") + .WithMany("Flags") + .HasForeignKey("AdminRankId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Rank"); + }); + + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.HasOne("Content.Server.Database.Profile", "Profile") + .WithMany("Antags") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.HasOne("Content.Server.Database.Profile", "Profile") + .WithMany("Jobs") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("Content.Server.Database.PostgresServerUnban", b => + { + b.HasOne("Content.Server.Database.PostgresServerBan", "Ban") + .WithOne("Unban") + .HasForeignKey("Content.Server.Database.PostgresServerUnban", "BanId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Ban"); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.HasOne("Content.Server.Database.Preference", "Preference") + .WithMany("Profiles") + .HasForeignKey("PreferenceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Preference"); + }); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.Navigation("Flags"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRank", b => + { + b.Navigation("Admins"); + + b.Navigation("Flags"); + }); + + modelBuilder.Entity("Content.Server.Database.PostgresServerBan", b => + { + b.Navigation("Unban"); + }); + + modelBuilder.Entity("Content.Server.Database.Preference", b => + { + b.Navigation("Profiles"); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.Navigation("Antags"); + + b.Navigation("Jobs"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Content.Server.Database/Migrations/Postgres/20201203093409_ClothingAndPronouns.cs b/Content.Server.Database/Migrations/Postgres/20201203093409_ClothingAndPronouns.cs new file mode 100644 index 0000000000..ec7318fc4b --- /dev/null +++ b/Content.Server.Database/Migrations/Postgres/20201203093409_ClothingAndPronouns.cs @@ -0,0 +1,35 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Content.Server.Database.Migrations.Postgres +{ + public partial class ClothingAndPronouns : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "clothing", + table: "profile", + type: "text", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "gender", + table: "profile", + type: "text", + nullable: false, + defaultValue: ""); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "clothing", + table: "profile"); + + migrationBuilder.DropColumn( + name: "gender", + table: "profile"); + } + } +} diff --git a/Content.Server.Database/Migrations/Postgres/PostgresServerDbContextModelSnapshot.cs b/Content.Server.Database/Migrations/Postgres/PostgresServerDbContextModelSnapshot.cs index 16f84e3e27..589940e4a6 100644 --- a/Content.Server.Database/Migrations/Postgres/PostgresServerDbContextModelSnapshot.cs +++ b/Content.Server.Database/Migrations/Postgres/PostgresServerDbContextModelSnapshot.cs @@ -16,24 +16,24 @@ namespace Content.Server.Database.Migrations.Postgres { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) - .HasAnnotation("ProductVersion", "3.1.4") - .HasAnnotation("Relational:MaxIdentifierLength", 63); + .UseIdentityByDefaultColumns() + .HasAnnotation("Relational:MaxIdentifierLength", 63) + .HasAnnotation("ProductVersion", "5.0.0"); modelBuilder.Entity("Content.Server.Database.Admin", b => { b.Property("UserId") .ValueGeneratedOnAdd() - .HasColumnName("user_id") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasColumnName("user_id"); b.Property("AdminRankId") - .HasColumnName("admin_rank_id") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasColumnName("admin_rank_id"); b.Property("Title") - .HasColumnName("title") - .HasColumnType("text"); + .HasColumnType("text") + .HasColumnName("title"); b.HasKey("UserId"); @@ -46,22 +46,22 @@ namespace Content.Server.Database.Migrations.Postgres { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("admin_flag_id") .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnName("admin_flag_id") + .UseIdentityByDefaultColumn(); b.Property("AdminId") - .HasColumnName("admin_id") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasColumnName("admin_id"); b.Property("Flag") .IsRequired() - .HasColumnName("flag") - .HasColumnType("text"); + .HasColumnType("text") + .HasColumnName("flag"); b.Property("Negative") - .HasColumnName("negative") - .HasColumnType("boolean"); + .HasColumnType("boolean") + .HasColumnName("negative"); b.HasKey("Id"); @@ -77,14 +77,14 @@ namespace Content.Server.Database.Migrations.Postgres { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("admin_rank_id") .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnName("admin_rank_id") + .UseIdentityByDefaultColumn(); b.Property("Name") .IsRequired() - .HasColumnName("name") - .HasColumnType("text"); + .HasColumnType("text") + .HasColumnName("name"); b.HasKey("Id"); @@ -95,18 +95,18 @@ namespace Content.Server.Database.Migrations.Postgres { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("admin_rank_flag_id") .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnName("admin_rank_flag_id") + .UseIdentityByDefaultColumn(); b.Property("AdminRankId") - .HasColumnName("admin_rank_id") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasColumnName("admin_rank_id"); b.Property("Flag") .IsRequired() - .HasColumnName("flag") - .HasColumnType("text"); + .HasColumnType("text") + .HasColumnName("flag"); b.HasKey("Id"); @@ -122,18 +122,18 @@ namespace Content.Server.Database.Migrations.Postgres { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("antag_id") .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnName("antag_id") + .UseIdentityByDefaultColumn(); b.Property("AntagName") .IsRequired() - .HasColumnName("antag_name") - .HasColumnType("text"); + .HasColumnType("text") + .HasColumnName("antag_name"); b.Property("ProfileId") - .HasColumnName("profile_id") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasColumnName("profile_id"); b.HasKey("Id"); @@ -147,18 +147,18 @@ namespace Content.Server.Database.Migrations.Postgres { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("assigned_user_id_id") .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnName("assigned_user_id_id") + .UseIdentityByDefaultColumn(); b.Property("UserId") - .HasColumnName("user_id") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasColumnName("user_id"); b.Property("UserName") .IsRequired() - .HasColumnName("user_name") - .HasColumnType("text"); + .HasColumnType("text") + .HasColumnName("user_name"); b.HasKey("Id"); @@ -175,22 +175,22 @@ namespace Content.Server.Database.Migrations.Postgres { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("job_id") .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnName("job_id") + .UseIdentityByDefaultColumn(); b.Property("JobName") .IsRequired() - .HasColumnName("job_name") - .HasColumnType("text"); + .HasColumnType("text") + .HasColumnName("job_name"); b.Property("Priority") - .HasColumnName("priority") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasColumnName("priority"); b.Property("ProfileId") - .HasColumnName("profile_id") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasColumnName("profile_id"); b.HasKey("Id"); @@ -203,27 +203,27 @@ namespace Content.Server.Database.Migrations.Postgres { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("connection_log_id") .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnName("connection_log_id") + .UseIdentityByDefaultColumn(); b.Property("Address") .IsRequired() - .HasColumnName("address") - .HasColumnType("inet"); + .HasColumnType("inet") + .HasColumnName("address"); b.Property("Time") - .HasColumnName("time") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasColumnName("time"); b.Property("UserId") - .HasColumnName("user_id") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasColumnName("user_id"); b.Property("UserName") .IsRequired() - .HasColumnName("user_name") - .HasColumnType("text"); + .HasColumnType("text") + .HasColumnName("user_name"); b.HasKey("Id"); @@ -238,31 +238,31 @@ namespace Content.Server.Database.Migrations.Postgres { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("player_id") .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnName("player_id") + .UseIdentityByDefaultColumn(); b.Property("FirstSeenTime") - .HasColumnName("first_seen_time") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasColumnName("first_seen_time"); b.Property("LastSeenAddress") .IsRequired() - .HasColumnName("last_seen_address") - .HasColumnType("inet"); + .HasColumnType("inet") + .HasColumnName("last_seen_address"); b.Property("LastSeenTime") - .HasColumnName("last_seen_time") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasColumnName("last_seen_time"); b.Property("LastSeenUserName") .IsRequired() - .HasColumnName("last_seen_user_name") - .HasColumnType("text"); + .HasColumnType("text") + .HasColumnName("last_seen_user_name"); b.Property("UserId") - .HasColumnName("user_id") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasColumnName("user_id"); b.HasKey("Id"); @@ -280,34 +280,34 @@ namespace Content.Server.Database.Migrations.Postgres { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("server_ban_id") .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnName("server_ban_id") + .UseIdentityByDefaultColumn(); b.Property?>("Address") - .HasColumnName("address") - .HasColumnType("inet"); + .HasColumnType("inet") + .HasColumnName("address"); b.Property("BanTime") - .HasColumnName("ban_time") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasColumnName("ban_time"); b.Property("BanningAdmin") - .HasColumnName("banning_admin") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasColumnName("banning_admin"); b.Property("ExpirationTime") - .HasColumnName("expiration_time") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasColumnName("expiration_time"); b.Property("Reason") .IsRequired() - .HasColumnName("reason") - .HasColumnType("text"); + .HasColumnType("text") + .HasColumnName("reason"); b.Property("UserId") - .HasColumnName("user_id") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasColumnName("user_id"); b.HasKey("Id"); @@ -326,21 +326,21 @@ namespace Content.Server.Database.Migrations.Postgres { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("unban_id") .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnName("unban_id") + .UseIdentityByDefaultColumn(); b.Property("BanId") - .HasColumnName("ban_id") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasColumnName("ban_id"); b.Property("UnbanTime") - .HasColumnName("unban_time") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasColumnName("unban_time"); b.Property("UnbanningAdmin") - .HasColumnName("unbanning_admin") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasColumnName("unbanning_admin"); b.HasKey("Id"); @@ -354,17 +354,17 @@ namespace Content.Server.Database.Migrations.Postgres { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("preference_id") .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnName("preference_id") + .UseIdentityByDefaultColumn(); b.Property("SelectedCharacterSlot") - .HasColumnName("selected_character_slot") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasColumnName("selected_character_slot"); b.Property("UserId") - .HasColumnName("user_id") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasColumnName("user_id"); b.HasKey("Id"); @@ -378,65 +378,75 @@ namespace Content.Server.Database.Migrations.Postgres { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("profile_id") .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnName("profile_id") + .UseIdentityByDefaultColumn(); b.Property("Age") - .HasColumnName("age") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasColumnName("age"); b.Property("CharacterName") .IsRequired() - .HasColumnName("char_name") - .HasColumnType("text"); + .HasColumnType("text") + .HasColumnName("char_name"); + + b.Property("Clothing") + .IsRequired() + .HasColumnType("text") + .HasColumnName("clothing"); b.Property("EyeColor") .IsRequired() - .HasColumnName("eye_color") - .HasColumnType("text"); + .HasColumnType("text") + .HasColumnName("eye_color"); b.Property("FacialHairColor") .IsRequired() - .HasColumnName("facial_hair_color") - .HasColumnType("text"); + .HasColumnType("text") + .HasColumnName("facial_hair_color"); b.Property("FacialHairName") .IsRequired() - .HasColumnName("facial_hair_name") - .HasColumnType("text"); + .HasColumnType("text") + .HasColumnName("facial_hair_name"); + + b.Property("Gender") + .IsRequired() + .HasColumnType("text") + .HasColumnName("gender"); b.Property("HairColor") .IsRequired() - .HasColumnName("hair_color") - .HasColumnType("text"); + .HasColumnType("text") + .HasColumnName("hair_color"); b.Property("HairName") .IsRequired() - .HasColumnName("hair_name") - .HasColumnType("text"); + .HasColumnType("text") + .HasColumnName("hair_name"); b.Property("PreferenceId") - .HasColumnName("preference_id") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasColumnName("preference_id"); b.Property("PreferenceUnavailable") - .HasColumnName("pref_unavailable") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasColumnName("pref_unavailable"); b.Property("Sex") .IsRequired() - .HasColumnName("sex") - .HasColumnType("text"); + .HasColumnType("text") + .HasColumnName("sex"); b.Property("SkinColor") .IsRequired() - .HasColumnName("skin_color") - .HasColumnType("text"); + .HasColumnType("text") + .HasColumnName("skin_color"); b.Property("Slot") - .HasColumnName("slot") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasColumnName("slot"); b.HasKey("Id"); @@ -454,6 +464,8 @@ namespace Content.Server.Database.Migrations.Postgres .WithMany("Admins") .HasForeignKey("AdminRankId") .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("AdminRank"); }); modelBuilder.Entity("Content.Server.Database.AdminFlag", b => @@ -463,6 +475,8 @@ namespace Content.Server.Database.Migrations.Postgres .HasForeignKey("AdminId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.Navigation("Admin"); }); modelBuilder.Entity("Content.Server.Database.AdminRankFlag", b => @@ -472,6 +486,8 @@ namespace Content.Server.Database.Migrations.Postgres .HasForeignKey("AdminRankId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.Navigation("Rank"); }); modelBuilder.Entity("Content.Server.Database.Antag", b => @@ -481,6 +497,8 @@ namespace Content.Server.Database.Migrations.Postgres .HasForeignKey("ProfileId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.Navigation("Profile"); }); modelBuilder.Entity("Content.Server.Database.Job", b => @@ -490,6 +508,8 @@ namespace Content.Server.Database.Migrations.Postgres .HasForeignKey("ProfileId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.Navigation("Profile"); }); modelBuilder.Entity("Content.Server.Database.PostgresServerUnban", b => @@ -499,6 +519,8 @@ namespace Content.Server.Database.Migrations.Postgres .HasForeignKey("Content.Server.Database.PostgresServerUnban", "BanId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.Navigation("Ban"); }); modelBuilder.Entity("Content.Server.Database.Profile", b => @@ -508,6 +530,37 @@ namespace Content.Server.Database.Migrations.Postgres .HasForeignKey("PreferenceId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.Navigation("Preference"); + }); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.Navigation("Flags"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRank", b => + { + b.Navigation("Admins"); + + b.Navigation("Flags"); + }); + + modelBuilder.Entity("Content.Server.Database.PostgresServerBan", b => + { + b.Navigation("Unban"); + }); + + modelBuilder.Entity("Content.Server.Database.Preference", b => + { + b.Navigation("Profiles"); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.Navigation("Antags"); + + b.Navigation("Jobs"); }); #pragma warning restore 612, 618 } diff --git a/Content.Server.Database/Migrations/Sqlite/20201203093351_ClothingAndPronouns.Designer.cs b/Content.Server.Database/Migrations/Sqlite/20201203093351_ClothingAndPronouns.Designer.cs new file mode 100644 index 0000000000..01243e826a --- /dev/null +++ b/Content.Server.Database/Migrations/Sqlite/20201203093351_ClothingAndPronouns.Designer.cs @@ -0,0 +1,537 @@ +// +using System; +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.Sqlite +{ + [DbContext(typeof(SqliteServerDbContext))] + [Migration("20201203093351_ClothingAndPronouns")] + partial class ClothingAndPronouns + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.0"); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.Property("AdminRankId") + .HasColumnType("INTEGER") + .HasColumnName("admin_rank_id"); + + b.Property("Title") + .HasColumnType("TEXT") + .HasColumnName("title"); + + b.HasKey("UserId"); + + b.HasIndex("AdminRankId"); + + b.ToTable("admin"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminFlag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("admin_flag_id"); + + b.Property("AdminId") + .HasColumnType("TEXT") + .HasColumnName("admin_id"); + + b.Property("Flag") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("flag"); + + b.Property("Negative") + .HasColumnType("INTEGER") + .HasColumnName("negative"); + + b.HasKey("Id"); + + b.HasIndex("AdminId"); + + b.HasIndex("Flag", "AdminId") + .IsUnique(); + + b.ToTable("admin_flag"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRank", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("admin_rank_id"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("name"); + + b.HasKey("Id"); + + b.ToTable("admin_rank"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRankFlag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("admin_rank_flag_id"); + + b.Property("AdminRankId") + .HasColumnType("INTEGER") + .HasColumnName("admin_rank_id"); + + b.Property("Flag") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("flag"); + + b.HasKey("Id"); + + b.HasIndex("AdminRankId"); + + b.HasIndex("Flag", "AdminRankId") + .IsUnique(); + + b.ToTable("admin_rank_flag"); + }); + + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("antag_id"); + + b.Property("AntagName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("antag_name"); + + b.Property("ProfileId") + .HasColumnType("INTEGER") + .HasColumnName("profile_id"); + + b.HasKey("Id"); + + b.HasIndex("ProfileId", "AntagName") + .IsUnique(); + + b.ToTable("antag"); + }); + + modelBuilder.Entity("Content.Server.Database.AssignedUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("assigned_user_id_id"); + + b.Property("UserId") + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("user_name"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.HasIndex("UserName") + .IsUnique(); + + b.ToTable("assigned_user_id"); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("job_id"); + + b.Property("JobName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("job_name"); + + b.Property("Priority") + .HasColumnType("INTEGER") + .HasColumnName("priority"); + + b.Property("ProfileId") + .HasColumnType("INTEGER") + .HasColumnName("profile_id"); + + b.HasKey("Id"); + + b.HasIndex("ProfileId"); + + b.ToTable("job"); + }); + + modelBuilder.Entity("Content.Server.Database.Preference", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("preference_id"); + + b.Property("SelectedCharacterSlot") + .HasColumnType("INTEGER") + .HasColumnName("selected_character_slot"); + + b.Property("UserId") + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("preference"); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("profile_id"); + + b.Property("Age") + .HasColumnType("INTEGER") + .HasColumnName("age"); + + b.Property("CharacterName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("char_name"); + + b.Property("Clothing") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("clothing"); + + b.Property("EyeColor") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("eye_color"); + + b.Property("FacialHairColor") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("facial_hair_color"); + + b.Property("FacialHairName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("facial_hair_name"); + + b.Property("Gender") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("gender"); + + b.Property("HairColor") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("hair_color"); + + b.Property("HairName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("hair_name"); + + b.Property("PreferenceId") + .HasColumnType("INTEGER") + .HasColumnName("preference_id"); + + b.Property("PreferenceUnavailable") + .HasColumnType("INTEGER") + .HasColumnName("pref_unavailable"); + + b.Property("Sex") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("sex"); + + b.Property("SkinColor") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("skin_color"); + + b.Property("Slot") + .HasColumnType("INTEGER") + .HasColumnName("slot"); + + b.HasKey("Id"); + + b.HasIndex("PreferenceId"); + + b.HasIndex("Slot", "PreferenceId") + .IsUnique(); + + b.ToTable("profile"); + }); + + modelBuilder.Entity("Content.Server.Database.SqliteConnectionLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("connection_log_id"); + + b.Property("Address") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("address"); + + b.Property("Time") + .HasColumnType("TEXT") + .HasColumnName("time"); + + b.Property("UserId") + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("user_name"); + + b.HasKey("Id"); + + b.ToTable("connection_log"); + }); + + modelBuilder.Entity("Content.Server.Database.SqlitePlayer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("player_id"); + + b.Property("FirstSeenTime") + .HasColumnType("TEXT") + .HasColumnName("first_seen_time"); + + b.Property("LastSeenAddress") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("last_seen_address"); + + b.Property("LastSeenTime") + .HasColumnType("TEXT") + .HasColumnName("last_seen_time"); + + b.Property("LastSeenUserName") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("last_seen_user_name"); + + b.Property("UserId") + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("LastSeenUserName"); + + b.ToTable("player"); + }); + + modelBuilder.Entity("Content.Server.Database.SqliteServerBan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("ban_id"); + + b.Property("Address") + .HasColumnType("TEXT") + .HasColumnName("address"); + + b.Property("BanTime") + .HasColumnType("TEXT") + .HasColumnName("ban_time"); + + b.Property("BanningAdmin") + .HasColumnType("TEXT") + .HasColumnName("banning_admin"); + + b.Property("ExpirationTime") + .HasColumnType("TEXT") + .HasColumnName("expiration_time"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("reason"); + + b.Property("UserId") + .HasColumnType("TEXT") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.ToTable("ban"); + }); + + modelBuilder.Entity("Content.Server.Database.SqliteServerUnban", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("unban_id"); + + b.Property("BanId") + .HasColumnType("INTEGER") + .HasColumnName("ban_id"); + + b.Property("UnbanTime") + .HasColumnType("TEXT") + .HasColumnName("unban_time"); + + b.Property("UnbanningAdmin") + .HasColumnType("TEXT") + .HasColumnName("unbanning_admin"); + + b.HasKey("Id"); + + b.HasIndex("BanId") + .IsUnique(); + + b.ToTable("unban"); + }); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.HasOne("Content.Server.Database.AdminRank", "AdminRank") + .WithMany("Admins") + .HasForeignKey("AdminRankId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("AdminRank"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminFlag", b => + { + b.HasOne("Content.Server.Database.Admin", "Admin") + .WithMany("Flags") + .HasForeignKey("AdminId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Admin"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRankFlag", b => + { + b.HasOne("Content.Server.Database.AdminRank", "Rank") + .WithMany("Flags") + .HasForeignKey("AdminRankId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Rank"); + }); + + modelBuilder.Entity("Content.Server.Database.Antag", b => + { + b.HasOne("Content.Server.Database.Profile", "Profile") + .WithMany("Antags") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.HasOne("Content.Server.Database.Profile", "Profile") + .WithMany("Jobs") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.HasOne("Content.Server.Database.Preference", "Preference") + .WithMany("Profiles") + .HasForeignKey("PreferenceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Preference"); + }); + + modelBuilder.Entity("Content.Server.Database.SqliteServerUnban", b => + { + b.HasOne("Content.Server.Database.SqliteServerBan", "Ban") + .WithOne("Unban") + .HasForeignKey("Content.Server.Database.SqliteServerUnban", "BanId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Ban"); + }); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.Navigation("Flags"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRank", b => + { + b.Navigation("Admins"); + + b.Navigation("Flags"); + }); + + modelBuilder.Entity("Content.Server.Database.Preference", b => + { + b.Navigation("Profiles"); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.Navigation("Antags"); + + b.Navigation("Jobs"); + }); + + modelBuilder.Entity("Content.Server.Database.SqliteServerBan", b => + { + b.Navigation("Unban"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Content.Server.Database/Migrations/Sqlite/20201203093351_ClothingAndPronouns.cs b/Content.Server.Database/Migrations/Sqlite/20201203093351_ClothingAndPronouns.cs new file mode 100644 index 0000000000..763b9623a8 --- /dev/null +++ b/Content.Server.Database/Migrations/Sqlite/20201203093351_ClothingAndPronouns.cs @@ -0,0 +1,35 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Content.Server.Database.Migrations.Sqlite +{ + public partial class ClothingAndPronouns : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "clothing", + table: "profile", + type: "TEXT", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "gender", + table: "profile", + type: "TEXT", + nullable: false, + defaultValue: ""); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "clothing", + table: "profile"); + + migrationBuilder.DropColumn( + name: "gender", + table: "profile"); + } + } +} diff --git a/Content.Server.Database/Migrations/Sqlite/SqliteServerDbContextModelSnapshot.cs b/Content.Server.Database/Migrations/Sqlite/SqliteServerDbContextModelSnapshot.cs index bf24a18637..f6c1eb5e3a 100644 --- a/Content.Server.Database/Migrations/Sqlite/SqliteServerDbContextModelSnapshot.cs +++ b/Content.Server.Database/Migrations/Sqlite/SqliteServerDbContextModelSnapshot.cs @@ -14,22 +14,22 @@ namespace Content.Server.Database.Migrations.Sqlite { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "3.1.4"); + .HasAnnotation("ProductVersion", "5.0.0"); modelBuilder.Entity("Content.Server.Database.Admin", b => { b.Property("UserId") .ValueGeneratedOnAdd() - .HasColumnName("user_id") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("user_id"); b.Property("AdminRankId") - .HasColumnName("admin_rank_id") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("admin_rank_id"); b.Property("Title") - .HasColumnName("title") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("title"); b.HasKey("UserId"); @@ -42,21 +42,21 @@ namespace Content.Server.Database.Migrations.Sqlite { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("admin_flag_id") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("admin_flag_id"); b.Property("AdminId") - .HasColumnName("admin_id") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("admin_id"); b.Property("Flag") .IsRequired() - .HasColumnName("flag") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("flag"); b.Property("Negative") - .HasColumnName("negative") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("negative"); b.HasKey("Id"); @@ -72,13 +72,13 @@ namespace Content.Server.Database.Migrations.Sqlite { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("admin_rank_id") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("admin_rank_id"); b.Property("Name") .IsRequired() - .HasColumnName("name") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("name"); b.HasKey("Id"); @@ -89,17 +89,17 @@ namespace Content.Server.Database.Migrations.Sqlite { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("admin_rank_flag_id") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("admin_rank_flag_id"); b.Property("AdminRankId") - .HasColumnName("admin_rank_id") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("admin_rank_id"); b.Property("Flag") .IsRequired() - .HasColumnName("flag") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("flag"); b.HasKey("Id"); @@ -115,17 +115,17 @@ namespace Content.Server.Database.Migrations.Sqlite { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("antag_id") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("antag_id"); b.Property("AntagName") .IsRequired() - .HasColumnName("antag_name") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("antag_name"); b.Property("ProfileId") - .HasColumnName("profile_id") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("profile_id"); b.HasKey("Id"); @@ -139,17 +139,17 @@ namespace Content.Server.Database.Migrations.Sqlite { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("assigned_user_id_id") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("assigned_user_id_id"); b.Property("UserId") - .HasColumnName("user_id") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("user_id"); b.Property("UserName") .IsRequired() - .HasColumnName("user_name") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("user_name"); b.HasKey("Id"); @@ -166,21 +166,21 @@ namespace Content.Server.Database.Migrations.Sqlite { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("job_id") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("job_id"); b.Property("JobName") .IsRequired() - .HasColumnName("job_name") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("job_name"); b.Property("Priority") - .HasColumnName("priority") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("priority"); b.Property("ProfileId") - .HasColumnName("profile_id") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("profile_id"); b.HasKey("Id"); @@ -193,16 +193,16 @@ namespace Content.Server.Database.Migrations.Sqlite { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("preference_id") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("preference_id"); b.Property("SelectedCharacterSlot") - .HasColumnName("selected_character_slot") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("selected_character_slot"); b.Property("UserId") - .HasColumnName("user_id") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("user_id"); b.HasKey("Id"); @@ -216,64 +216,74 @@ namespace Content.Server.Database.Migrations.Sqlite { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("profile_id") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("profile_id"); b.Property("Age") - .HasColumnName("age") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("age"); b.Property("CharacterName") .IsRequired() - .HasColumnName("char_name") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("char_name"); + + b.Property("Clothing") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("clothing"); b.Property("EyeColor") .IsRequired() - .HasColumnName("eye_color") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("eye_color"); b.Property("FacialHairColor") .IsRequired() - .HasColumnName("facial_hair_color") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("facial_hair_color"); b.Property("FacialHairName") .IsRequired() - .HasColumnName("facial_hair_name") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("facial_hair_name"); + + b.Property("Gender") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("gender"); b.Property("HairColor") .IsRequired() - .HasColumnName("hair_color") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("hair_color"); b.Property("HairName") .IsRequired() - .HasColumnName("hair_name") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("hair_name"); b.Property("PreferenceId") - .HasColumnName("preference_id") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("preference_id"); b.Property("PreferenceUnavailable") - .HasColumnName("pref_unavailable") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("pref_unavailable"); b.Property("Sex") .IsRequired() - .HasColumnName("sex") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("sex"); b.Property("SkinColor") .IsRequired() - .HasColumnName("skin_color") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("skin_color"); b.Property("Slot") - .HasColumnName("slot") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("slot"); b.HasKey("Id"); @@ -289,26 +299,26 @@ namespace Content.Server.Database.Migrations.Sqlite { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("connection_log_id") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("connection_log_id"); b.Property("Address") .IsRequired() - .HasColumnName("address") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("address"); b.Property("Time") - .HasColumnName("time") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("time"); b.Property("UserId") - .HasColumnName("user_id") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("user_id"); b.Property("UserName") .IsRequired() - .HasColumnName("user_name") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("user_name"); b.HasKey("Id"); @@ -319,30 +329,30 @@ namespace Content.Server.Database.Migrations.Sqlite { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("player_id") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("player_id"); b.Property("FirstSeenTime") - .HasColumnName("first_seen_time") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("first_seen_time"); b.Property("LastSeenAddress") .IsRequired() - .HasColumnName("last_seen_address") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("last_seen_address"); b.Property("LastSeenTime") - .HasColumnName("last_seen_time") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("last_seen_time"); b.Property("LastSeenUserName") .IsRequired() - .HasColumnName("last_seen_user_name") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("last_seen_user_name"); b.Property("UserId") - .HasColumnName("user_id") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("user_id"); b.HasKey("Id"); @@ -355,33 +365,33 @@ namespace Content.Server.Database.Migrations.Sqlite { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("ban_id") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("ban_id"); b.Property("Address") - .HasColumnName("address") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("address"); b.Property("BanTime") - .HasColumnName("ban_time") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("ban_time"); b.Property("BanningAdmin") - .HasColumnName("banning_admin") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("banning_admin"); b.Property("ExpirationTime") - .HasColumnName("expiration_time") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("expiration_time"); b.Property("Reason") .IsRequired() - .HasColumnName("reason") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("reason"); b.Property("UserId") - .HasColumnName("user_id") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("user_id"); b.HasKey("Id"); @@ -392,20 +402,20 @@ namespace Content.Server.Database.Migrations.Sqlite { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnName("unban_id") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("unban_id"); b.Property("BanId") - .HasColumnName("ban_id") - .HasColumnType("INTEGER"); + .HasColumnType("INTEGER") + .HasColumnName("ban_id"); b.Property("UnbanTime") - .HasColumnName("unban_time") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("unban_time"); b.Property("UnbanningAdmin") - .HasColumnName("unbanning_admin") - .HasColumnType("TEXT"); + .HasColumnType("TEXT") + .HasColumnName("unbanning_admin"); b.HasKey("Id"); @@ -421,6 +431,8 @@ namespace Content.Server.Database.Migrations.Sqlite .WithMany("Admins") .HasForeignKey("AdminRankId") .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("AdminRank"); }); modelBuilder.Entity("Content.Server.Database.AdminFlag", b => @@ -430,6 +442,8 @@ namespace Content.Server.Database.Migrations.Sqlite .HasForeignKey("AdminId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.Navigation("Admin"); }); modelBuilder.Entity("Content.Server.Database.AdminRankFlag", b => @@ -439,6 +453,8 @@ namespace Content.Server.Database.Migrations.Sqlite .HasForeignKey("AdminRankId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.Navigation("Rank"); }); modelBuilder.Entity("Content.Server.Database.Antag", b => @@ -448,6 +464,8 @@ namespace Content.Server.Database.Migrations.Sqlite .HasForeignKey("ProfileId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.Navigation("Profile"); }); modelBuilder.Entity("Content.Server.Database.Job", b => @@ -457,6 +475,8 @@ namespace Content.Server.Database.Migrations.Sqlite .HasForeignKey("ProfileId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.Navigation("Profile"); }); modelBuilder.Entity("Content.Server.Database.Profile", b => @@ -466,6 +486,8 @@ namespace Content.Server.Database.Migrations.Sqlite .HasForeignKey("PreferenceId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.Navigation("Preference"); }); modelBuilder.Entity("Content.Server.Database.SqliteServerUnban", b => @@ -475,6 +497,37 @@ namespace Content.Server.Database.Migrations.Sqlite .HasForeignKey("Content.Server.Database.SqliteServerUnban", "BanId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.Navigation("Ban"); + }); + + modelBuilder.Entity("Content.Server.Database.Admin", b => + { + b.Navigation("Flags"); + }); + + modelBuilder.Entity("Content.Server.Database.AdminRank", b => + { + b.Navigation("Admins"); + + b.Navigation("Flags"); + }); + + modelBuilder.Entity("Content.Server.Database.Preference", b => + { + b.Navigation("Profiles"); + }); + + modelBuilder.Entity("Content.Server.Database.Profile", b => + { + b.Navigation("Antags"); + + b.Navigation("Jobs"); + }); + + modelBuilder.Entity("Content.Server.Database.SqliteServerBan", b => + { + b.Navigation("Unban"); }); #pragma warning restore 612, 618 } diff --git a/Content.Server.Database/Model.cs b/Content.Server.Database/Model.cs index 2b2ac59a14..e5d365b602 100644 --- a/Content.Server.Database/Model.cs +++ b/Content.Server.Database/Model.cs @@ -91,12 +91,14 @@ namespace Content.Server.Database [Column("char_name")] public string CharacterName { get; set; } = null!; [Column("age")] public int Age { get; set; } [Column("sex")] public string Sex { get; set; } = null!; + [Column("gender")] public string Gender { get; set; } = null!; [Column("hair_name")] public string HairName { get; set; } = null!; [Column("hair_color")] public string HairColor { get; set; } = null!; [Column("facial_hair_name")] public string FacialHairName { get; set; } = null!; [Column("facial_hair_color")] public string FacialHairColor { get; set; } = null!; [Column("eye_color")] public string EyeColor { get; set; } = null!; [Column("skin_color")] public string SkinColor { get; set; } = null!; + [Column("clothing")] public string Clothing { get; set; } = null!; public List Jobs { get; } = new(); public List Antags { get; } = new(); diff --git a/Content.Server/Database/ServerDbBase.cs b/Content.Server/Database/ServerDbBase.cs index 0ee380040e..929532fc21 100644 --- a/Content.Server/Database/ServerDbBase.cs +++ b/Content.Server/Database/ServerDbBase.cs @@ -9,6 +9,7 @@ using Content.Shared.Preferences; using Microsoft.EntityFrameworkCore; using Robust.Shared.Maths; using Robust.Shared.Network; +using Robust.Shared.Localization.Macros; namespace Content.Server.Database { @@ -130,10 +131,24 @@ namespace Content.Server.Database { var jobs = profile.Jobs.ToDictionary(j => j.JobName, j => (JobPriority) j.Priority); var antags = profile.Antags.Select(a => a.AntagName); + + var sex = Sex.Male; + if (Enum.TryParse(profile.Sex, true, out var sexVal)) + sex = sexVal; + + var clothing = ClothingPreference.Jumpsuit; + if (Enum.TryParse(profile.Clothing, true, out var clothingVal)) + clothing = clothingVal; + + var gender = sex == Sex.Male ? Gender.Male : Gender.Female; + if (Enum.TryParse(profile.Gender, true, out var genderVal)) + gender = genderVal; + return new HumanoidCharacterProfile( profile.CharacterName, profile.Age, - profile.Sex == "Male" ? Sex.Male : Sex.Female, + sex, + gender, new HumanoidCharacterAppearance ( profile.HairName, @@ -143,6 +158,7 @@ namespace Content.Server.Database Color.FromHex(profile.EyeColor), Color.FromHex(profile.SkinColor) ), + clothing, jobs, (PreferenceUnavailableMode) profile.PreferenceUnavailable, antags.ToList() @@ -158,12 +174,14 @@ namespace Content.Server.Database CharacterName = humanoid.Name, Age = humanoid.Age, Sex = humanoid.Sex.ToString(), + Gender = humanoid.Gender.ToString(), HairName = appearance.HairStyleName, HairColor = appearance.HairColor.ToHex(), FacialHairName = appearance.FacialHairStyleName, FacialHairColor = appearance.FacialHairColor.ToHex(), EyeColor = appearance.EyeColor.ToHex(), SkinColor = appearance.SkinColor.ToHex(), + Clothing = humanoid.Clothing.ToString(), Slot = slot, PreferenceUnavailable = (DbPreferenceUnavailableMode) humanoid.PreferenceUnavailable }; diff --git a/Content.Server/GameObjects/Components/Movement/AiControllerComponent.cs b/Content.Server/GameObjects/Components/Movement/AiControllerComponent.cs index 38f8f9a0bc..7dad25f40a 100644 --- a/Content.Server/GameObjects/Components/Movement/AiControllerComponent.cs +++ b/Content.Server/GameObjects/Components/Movement/AiControllerComponent.cs @@ -4,6 +4,8 @@ using Content.Server.GameObjects.EntitySystems.AI; using Content.Server.Interfaces.GameTicking; using Content.Shared.GameObjects.Components.Movement; using Content.Shared.Roles; +using Content.Shared.Preferences; +using Robust.Server.AI; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Components; using Robust.Shared.GameObjects.Systems; @@ -68,7 +70,7 @@ namespace Content.Server.GameObjects.Components.Movement if (StartingGearPrototype != null) { var startingGear = _prototypeManager.Index(StartingGearPrototype); - _gameTicker.EquipStartingGear(Owner, startingGear); + _gameTicker.EquipStartingGear(Owner, startingGear, null); } } diff --git a/Content.Server/GameTicking/GameTicker.cs b/Content.Server/GameTicking/GameTicker.cs index 9d5d86ea61..f219fc7c56 100644 --- a/Content.Server/GameTicking/GameTicker.cs +++ b/Content.Server/GameTicking/GameTicker.cs @@ -577,26 +577,34 @@ namespace Content.Server.GameTicking return Paused; } - private IEntity _spawnPlayerMob(Job job, bool lateJoin = true) + private IEntity _spawnPlayerMob(Job job, HumanoidCharacterProfile profile, bool lateJoin = true) { EntityCoordinates coordinates = lateJoin ? GetLateJoinSpawnPoint() : GetJobSpawnPoint(job.Prototype.ID); var entity = _entityManager.SpawnEntity(PlayerPrototypeName, coordinates); var startingGear = _prototypeManager.Index(job.StartingGear); - EquipStartingGear(entity, startingGear); + EquipStartingGear(entity, startingGear, profile); + + if (profile != null) + { + entity.GetComponent().UpdateFromProfile(profile); + entity.Name = profile.Name; + } return entity; } - public void EquipStartingGear(IEntity entity, StartingGearPrototype startingGear) + public void EquipStartingGear(IEntity entity, StartingGearPrototype startingGear, HumanoidCharacterProfile profile) { if (entity.TryGetComponent(out InventoryComponent inventory)) { - var gear = startingGear.Equipment; - - foreach (var (slot, equipmentStr) in gear) + foreach (var slot in AllSlots) { - var equipmentEntity = _entityManager.SpawnEntity(equipmentStr, entity.Transform.Coordinates); - inventory.Equip(slot, equipmentEntity.GetComponent()); + var equipmentStr = startingGear.GetGear(slot, profile); + if (equipmentStr != "") + { + var equipmentEntity = _entityManager.SpawnEntity(equipmentStr, entity.Transform.Coordinates); + inventory.Equip(slot, equipmentEntity.GetComponent()); + } } } @@ -611,14 +619,6 @@ namespace Content.Server.GameTicking } } - private void ApplyCharacterProfile(IEntity entity, ICharacterProfile profile) - { - if (profile is null) - return; - entity.GetComponent().UpdateFromProfile(profile); - entity.Name = profile.Name; - } - private IEntity _spawnObserverMob() { var coordinates = GetObserverSpawnPoint(); @@ -888,9 +888,8 @@ namespace Content.Server.GameTicking var job = new Job(data.Mind, jobPrototype); data.Mind.AddRole(job); - var mob = _spawnPlayerMob(job, lateJoin); + var mob = _spawnPlayerMob(job, character, lateJoin); data.Mind.TransferTo(mob); - ApplyCharacterProfile(mob, character); if (session.UserId == new Guid("{e887eb93-f503-4b65-95b6-2f282c014192}")) { diff --git a/Content.Server/Interfaces/GameTicking/IGameTicker.cs b/Content.Server/Interfaces/GameTicking/IGameTicker.cs index 5651a26583..02073511f1 100644 --- a/Content.Server/Interfaces/GameTicking/IGameTicker.cs +++ b/Content.Server/Interfaces/GameTicking/IGameTicker.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using Content.Server.GameTicking; using Content.Server.Mobs; using Content.Shared.Roles; +using Content.Shared.Preferences; using Robust.Server.Interfaces.Player; using Robust.Server.Interfaces.Console; using Robust.Shared.Interfaces.GameObjects; @@ -51,7 +52,7 @@ namespace Content.Server.Interfaces.GameTicking EntityCoordinates GetJobSpawnPoint(string jobId); EntityCoordinates GetObserverSpawnPoint(); - void EquipStartingGear(IEntity entity, StartingGearPrototype startingGear); + void EquipStartingGear(IEntity entity, StartingGearPrototype startingGear, HumanoidCharacterProfile profile); // GameRule system. T AddGameRule() where T : GameRule, new(); diff --git a/Content.Shared/GameObjects/Components/Mobs/SharedHumanoidAppearanceComponent.cs b/Content.Shared/GameObjects/Components/Mobs/SharedHumanoidAppearanceComponent.cs index 6a35042324..38c985bb1e 100644 --- a/Content.Shared/GameObjects/Components/Mobs/SharedHumanoidAppearanceComponent.cs +++ b/Content.Shared/GameObjects/Components/Mobs/SharedHumanoidAppearanceComponent.cs @@ -11,6 +11,7 @@ namespace Content.Shared.GameObjects.Components.Mobs { private HumanoidCharacterAppearance _appearance; private Sex _sex; + private Gender _gender; public sealed override string Name => "HumanoidAppearance"; public sealed override uint? NetID => ContentNetIDs.HUMANOID_APPEARANCE; @@ -37,17 +38,20 @@ namespace Content.Shared.GameObjects.Components.Mobs } } - public Gender Gender => Sex switch + [ViewVariables(VVAccess.ReadWrite)] + public virtual Gender Gender { - Sex.Female => Gender.Female, - Sex.Male => Gender.Male, - Sex.Classified => Gender.Neuter, - _ => Gender.Epicene, - }; + get => _gender; + set + { + _gender = value; + Dirty(); + } + } public override ComponentState GetComponentState() { - return new HumanoidAppearanceComponentState(Appearance, Sex); + return new HumanoidAppearanceComponentState(Appearance, Sex, Gender); } public override void HandleComponentState(ComponentState curState, ComponentState nextState) @@ -59,6 +63,7 @@ namespace Content.Shared.GameObjects.Components.Mobs Appearance = cast.Appearance; Sex = cast.Sex; + Gender = cast.Gender; } public void UpdateFromProfile(ICharacterProfile profile) @@ -66,20 +71,23 @@ namespace Content.Shared.GameObjects.Components.Mobs var humanoid = (HumanoidCharacterProfile) profile; Appearance = (HumanoidCharacterAppearance) humanoid.CharacterAppearance; Sex = humanoid.Sex; + Gender = humanoid.Gender; } [Serializable] [NetSerializable] private sealed class HumanoidAppearanceComponentState : ComponentState { - public HumanoidAppearanceComponentState(HumanoidCharacterAppearance appearance, Sex sex) : base(ContentNetIDs.HUMANOID_APPEARANCE) + public HumanoidAppearanceComponentState(HumanoidCharacterAppearance appearance, Sex sex, Gender gender) : base(ContentNetIDs.HUMANOID_APPEARANCE) { Appearance = appearance; Sex = sex; + Gender = gender; } public HumanoidCharacterAppearance Appearance { get; } public Sex Sex { get; } + public Gender Gender { get; } } } } diff --git a/Content.Shared/Preferences/ClothingPreference.cs b/Content.Shared/Preferences/ClothingPreference.cs new file mode 100644 index 0000000000..24a4b206c7 --- /dev/null +++ b/Content.Shared/Preferences/ClothingPreference.cs @@ -0,0 +1,11 @@ +namespace Content.Shared.Preferences +{ + /// + /// The clothing preference for a profile. Stored in database! + /// + public enum ClothingPreference + { + Jumpsuit, + Jumpskirt + } +} diff --git a/Content.Shared/Preferences/HumanoidCharacterProfile.cs b/Content.Shared/Preferences/HumanoidCharacterProfile.cs index 371d30d429..53777695ea 100644 --- a/Content.Shared/Preferences/HumanoidCharacterProfile.cs +++ b/Content.Shared/Preferences/HumanoidCharacterProfile.cs @@ -10,11 +10,16 @@ using Robust.Shared.IoC; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Serialization; +using Robust.Shared.Localization.Macros; +using Robust.Shared.Localization; namespace Content.Shared.Preferences { + /// + /// Character profile. Looks immutable, but uses non-immutable semantics internally for serialization/code sanity purposes. + /// [Serializable, NetSerializable] - public class HumanoidCharacterProfile : ICharacterProfile + public class HumanoidCharacterProfile : ICharacterProfile, IGenderable { private readonly Dictionary _jobPriorities; private readonly List _antagPreferences; @@ -26,7 +31,9 @@ namespace Content.Shared.Preferences string name, int age, Sex sex, + Gender gender, HumanoidCharacterAppearance appearance, + ClothingPreference clothing, Dictionary jobPriorities, PreferenceUnavailableMode preferenceUnavailable, List antagPreferences) @@ -34,21 +41,41 @@ namespace Content.Shared.Preferences Name = name; Age = age; Sex = sex; + Gender = gender; Appearance = appearance; + Clothing = clothing; _jobPriorities = jobPriorities; PreferenceUnavailable = preferenceUnavailable; _antagPreferences = antagPreferences; } + /// Copy constructor but with overridable references (to prevent useless copies) + private HumanoidCharacterProfile( + HumanoidCharacterProfile other, + Dictionary jobPriorities, + List antagPreferences) + : this(other.Name, other.Age, other.Sex, other.Gender, other.Appearance, other.Clothing, + jobPriorities, other.PreferenceUnavailable, antagPreferences) + { + } + + /// Copy constructor + private HumanoidCharacterProfile(HumanoidCharacterProfile other) + : this(other, new Dictionary(other.JobPriorities), new List(other.AntagPreferences)) + { + } + public HumanoidCharacterProfile( string name, int age, Sex sex, + Gender gender, HumanoidCharacterAppearance appearance, + ClothingPreference clothing, IReadOnlyDictionary jobPriorities, PreferenceUnavailableMode preferenceUnavailable, IReadOnlyList antagPreferences) - : this(name, age, sex, appearance, new Dictionary(jobPriorities), + : this(name, age, sex, gender, appearance, clothing, new Dictionary(jobPriorities), preferenceUnavailable, new List(antagPreferences)) { } @@ -62,6 +89,7 @@ namespace Content.Shared.Preferences { var random = IoCManager.Resolve(); var sex = random.Prob(0.5f) ? Sex.Male : Sex.Female; + var gender = sex == Sex.Male ? Gender.Male : Gender.Female; var firstName = random.Pick(sex == Sex.Male ? Names.MaleFirstNames @@ -70,52 +98,57 @@ namespace Content.Shared.Preferences var name = $"{firstName} {lastName}"; var age = random.Next(MinimumAge, MaximumAge); - return new HumanoidCharacterProfile(name, age, sex, HumanoidCharacterAppearance.Random(sex), + return new HumanoidCharacterProfile(name, age, sex, gender, HumanoidCharacterAppearance.Random(sex), ClothingPreference.Jumpsuit, new Dictionary { {SharedGameTicker.OverflowJob, JobPriority.High} }, PreferenceUnavailableMode.StayInLobby, new List()); } - public string Name { get; } - public int Age { get; } - public Sex Sex { get; } + public string Name { get; private set; } + public int Age { get; private set; } + public Sex Sex { get; private set; } + public Gender Gender { get; private set; } public ICharacterAppearance CharacterAppearance => Appearance; - public HumanoidCharacterAppearance Appearance { get; } + public HumanoidCharacterAppearance Appearance { get; private set; } + public ClothingPreference Clothing { get; private set; } public IReadOnlyDictionary JobPriorities => _jobPriorities; public IReadOnlyList AntagPreferences => _antagPreferences; - public PreferenceUnavailableMode PreferenceUnavailable { get; } + public PreferenceUnavailableMode PreferenceUnavailable { get; private set; } public HumanoidCharacterProfile WithName(string name) { - return new(name, Age, Sex, Appearance, _jobPriorities, PreferenceUnavailable, _antagPreferences); + return new(this) { Name = name }; } public HumanoidCharacterProfile WithAge(int age) { - return new(Name, Math.Clamp(age, MinimumAge, MaximumAge), Sex, Appearance, _jobPriorities, PreferenceUnavailable, _antagPreferences); + return new(this) { Age = age }; } public HumanoidCharacterProfile WithSex(Sex sex) { - return new(Name, Age, sex, Appearance, _jobPriorities, PreferenceUnavailable, _antagPreferences); + return new(this) { Sex = sex }; + } + + public HumanoidCharacterProfile WithGender(Gender gender) + { + return new(this) { Gender = gender }; } public HumanoidCharacterProfile WithCharacterAppearance(HumanoidCharacterAppearance appearance) { - return new(Name, Age, Sex, appearance, _jobPriorities, PreferenceUnavailable, _antagPreferences); + return new(this) { Appearance = appearance }; + } + + public HumanoidCharacterProfile WithClothingPreference(ClothingPreference clothing) + { + return new(this) { Clothing = clothing }; } public HumanoidCharacterProfile WithJobPriorities(IEnumerable> jobPriorities) { - return new( - Name, - Age, - Sex, - Appearance, - new Dictionary(jobPriorities), - PreferenceUnavailable, - _antagPreferences); + return new(this, new Dictionary(jobPriorities), _antagPreferences); } public HumanoidCharacterProfile WithJobPriority(string jobId, JobPriority priority) @@ -129,25 +162,17 @@ namespace Content.Shared.Preferences { dictionary[jobId] = priority; } - - return new HumanoidCharacterProfile(Name, Age, Sex, Appearance, dictionary, PreferenceUnavailable, _antagPreferences); + return new(this, dictionary, _antagPreferences); } public HumanoidCharacterProfile WithPreferenceUnavailable(PreferenceUnavailableMode mode) { - return new(Name, Age, Sex, Appearance, _jobPriorities, mode, _antagPreferences); + return new(this) { PreferenceUnavailable = mode }; } public HumanoidCharacterProfile WithAntagPreferences(IEnumerable antagPreferences) { - return new( - Name, - Age, - Sex, - Appearance, - _jobPriorities, - PreferenceUnavailable, - new List(antagPreferences)); + return new(this, _jobPriorities, new List(antagPreferences)); } public HumanoidCharacterProfile WithAntagPreference(string antagId, bool pref) @@ -167,7 +192,7 @@ namespace Content.Shared.Preferences list.Remove(antagId); } } - return new HumanoidCharacterProfile(Name, Age, Sex, Appearance, _jobPriorities, PreferenceUnavailable, list); + return new(this, _jobPriorities, list); } /// @@ -184,6 +209,14 @@ namespace Content.Shared.Preferences Sex.Female => Sex.Female, _ => Sex.Male // Invalid enum values. }; + var gender = profile.Gender switch + { + Gender.Epicene => Gender.Epicene, + Gender.Female => Gender.Female, + Gender.Male => Gender.Male, + Gender.Neuter => Gender.Neuter, + _ => Gender.Epicene // Invalid enum values. + }; string name; if (string.IsNullOrEmpty(profile.Name)) @@ -214,6 +247,13 @@ namespace Content.Shared.Preferences _ => PreferenceUnavailableMode.StayInLobby // Invalid enum values. }; + var clothing = profile.Clothing switch + { + ClothingPreference.Jumpsuit => ClothingPreference.Jumpsuit, + ClothingPreference.Jumpskirt => ClothingPreference.Jumpskirt, + _ => ClothingPreference.Jumpsuit // Invalid enum values. + }; + var priorities = new Dictionary(profile.JobPriorities .Where(p => prototypeManager.HasIndex(p.Key) && p.Value switch { @@ -228,11 +268,11 @@ namespace Content.Shared.Preferences .Where(prototypeManager.HasIndex) .ToList(); - return new HumanoidCharacterProfile(name, age, sex, appearance, priorities, prefsUnavailableMode, antags); + return new HumanoidCharacterProfile(name, age, sex, gender, appearance, clothing, priorities, prefsUnavailableMode, antags); } public string Summary => - $"{Name}, {Age} years old human. Their gender is {Sex.ToString().ToLower()}."; + Loc.GetString("{0}, {1} years old human. {2:Their} pronouns are {2:they}/{2:them}.", Name, Age, this); public bool MemberwiseEquals(ICharacterProfile maybeOther) { @@ -240,7 +280,9 @@ namespace Content.Shared.Preferences if (Name != other.Name) return false; if (Age != other.Age) return false; if (Sex != other.Sex) return false; + if (Gender != other.Gender) return false; if (PreferenceUnavailable != other.PreferenceUnavailable) return false; + if (Clothing != other.Clothing) return false; if (!_jobPriorities.SequenceEqual(other._jobPriorities)) return false; if (!_antagPreferences.SequenceEqual(other._antagPreferences)) return false; return Appearance.MemberwiseEquals(other.Appearance); @@ -254,13 +296,18 @@ namespace Content.Shared.Preferences public override int GetHashCode() { return HashCode.Combine( - Name, - Age, - Sex, + HashCode.Combine( + Name, + Age, + Sex, + Gender, + Appearance, + Clothing + ), PreferenceUnavailable, _jobPriorities, - _antagPreferences, - Appearance); + _antagPreferences + ); } } } diff --git a/Content.Shared/Preferences/Sex.cs b/Content.Shared/Preferences/Sex.cs index 155f280da6..85aea5e709 100644 --- a/Content.Shared/Preferences/Sex.cs +++ b/Content.Shared/Preferences/Sex.cs @@ -3,7 +3,6 @@ public enum Sex { Male, - Female, - Classified + Female } } diff --git a/Content.Shared/Roles/StartingGearPrototype.cs b/Content.Shared/Roles/StartingGearPrototype.cs index e8213cea74..ac27be7a56 100644 --- a/Content.Shared/Roles/StartingGearPrototype.cs +++ b/Content.Shared/Roles/StartingGearPrototype.cs @@ -1,3 +1,4 @@ +#nullable enable using System; using System.Collections.Generic; using System.Linq; @@ -5,6 +6,7 @@ using Robust.Shared.Prototypes; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; using YamlDotNet.RepresentationModel; +using Content.Shared.Preferences; using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines; namespace Content.Shared.Roles @@ -12,19 +14,22 @@ namespace Content.Shared.Roles [Prototype("startingGear")] public class StartingGearPrototype : IPrototype, IIndexedPrototype { - private string _id; - private Dictionary _equipment; + private string _id = default!; + private Dictionary _equipment = default!; + + /// + /// if empty, there is no skirt override - instead the uniform provided in equipment is added. + /// + private string _innerClothingSkirt = default!; public IReadOnlyDictionary Inhand => _inHand; /// /// hand index, item prototype /// - private Dictionary _inHand; + private Dictionary _inHand = default!; [ViewVariables] public string ID => _id; - [ViewVariables] public IReadOnlyDictionary Equipment => _equipment; - public void LoadFrom(YamlMappingNode mapping) { var serializer = YamlObjectSerializer.NewReader(mapping); @@ -44,6 +49,26 @@ namespace Content.Shared.Roles return slot; }, type => type.Value); + + serializer.DataField(ref _innerClothingSkirt, "innerclothingskirt", string.Empty); + } + + public string GetGear(Slots slot, HumanoidCharacterProfile? profile) + { + if (profile != null) + { + if ((slot == Slots.INNERCLOTHING) && (profile.Clothing == ClothingPreference.Jumpskirt) && (_innerClothingSkirt != "")) + return _innerClothingSkirt; + } + + if (_equipment.ContainsKey(slot)) + { + return _equipment[slot]; + } + else + { + return ""; + } } } } diff --git a/Content.Tests/Server/Preferences/ServerDbSqliteTests.cs b/Content.Tests/Server/Preferences/ServerDbSqliteTests.cs index 375f1881c4..2481c5cf88 100644 --- a/Content.Tests/Server/Preferences/ServerDbSqliteTests.cs +++ b/Content.Tests/Server/Preferences/ServerDbSqliteTests.cs @@ -12,6 +12,8 @@ using NUnit.Framework; using Robust.Shared.Maths; using Robust.Shared.Network; using Robust.UnitTesting; +using Robust.Shared.IoC; +using Robust.Shared.Localization.Macros; namespace Content.Tests.Server.Preferences { @@ -24,6 +26,7 @@ namespace Content.Tests.Server.Preferences "Charlie Charlieson", 21, Sex.Male, + Gender.Epicene, new HumanoidCharacterAppearance( "Afro", Color.Aqua, @@ -32,6 +35,7 @@ namespace Content.Tests.Server.Preferences Color.Azure, Color.Beige ), + ClothingPreference.Jumpskirt, new Dictionary { {SharedGameTicker.OverflowJob, JobPriority.High} diff --git a/Resources/Prototypes/Roles/Jobs/Cargo/cargo_technician.yml b/Resources/Prototypes/Roles/Jobs/Cargo/cargo_technician.yml index 5f9d492902..cfaaf58949 100644 --- a/Resources/Prototypes/Roles/Jobs/Cargo/cargo_technician.yml +++ b/Resources/Prototypes/Roles/Jobs/Cargo/cargo_technician.yml @@ -20,3 +20,5 @@ shoes: ClothingShoesColorBlack idcard: CargoPDA ears: ClothingHeadsetCargo + innerclothingskirt: ClothingUniformJumpskirtCargo + diff --git a/Resources/Prototypes/Roles/Jobs/Cargo/quartermaster.yml b/Resources/Prototypes/Roles/Jobs/Cargo/quartermaster.yml index 9c2ac826f0..e5dced21f9 100644 --- a/Resources/Prototypes/Roles/Jobs/Cargo/quartermaster.yml +++ b/Resources/Prototypes/Roles/Jobs/Cargo/quartermaster.yml @@ -21,3 +21,5 @@ shoes: ClothingShoesColorBrown idcard: QuartermasterPDA ears: ClothingHeadsetCargo + innerclothingskirt: ClothingUniformJumpskirtQM + diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/assistant.yml b/Resources/Prototypes/Roles/Jobs/Civilian/assistant.yml index 07a5162534..6249154a98 100644 --- a/Resources/Prototypes/Roles/Jobs/Civilian/assistant.yml +++ b/Resources/Prototypes/Roles/Jobs/Civilian/assistant.yml @@ -17,3 +17,5 @@ shoes: ClothingShoesColorBlack idcard: AssistantPDA ears: ClothingHeadsetService + innerclothingskirt: ClothingUniformJumpskirtColorGrey + diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/bartender.yml b/Resources/Prototypes/Roles/Jobs/Civilian/bartender.yml index 04d367ae25..761e2f7ccd 100644 --- a/Resources/Prototypes/Roles/Jobs/Civilian/bartender.yml +++ b/Resources/Prototypes/Roles/Jobs/Civilian/bartender.yml @@ -21,3 +21,5 @@ shoes: ClothingShoesColorBlack idcard: BartenderPDA ears: ClothingHeadsetService + innerclothingskirt: ClothingUniformJumpskirtBartender + diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/botanist.yml b/Resources/Prototypes/Roles/Jobs/Civilian/botanist.yml index 94c8d0ab37..59bdfd5db7 100644 --- a/Resources/Prototypes/Roles/Jobs/Civilian/botanist.yml +++ b/Resources/Prototypes/Roles/Jobs/Civilian/botanist.yml @@ -21,3 +21,5 @@ idcard: BotanistPDA ears: ClothingHeadsetService outerclothing: ClothingOuterApronBotanist + innerclothingskirt: ClothingUniformJumpskirtHydroponics + diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/chaplain.yml b/Resources/Prototypes/Roles/Jobs/Civilian/chaplain.yml index 3f4736aa89..844317afe2 100644 --- a/Resources/Prototypes/Roles/Jobs/Civilian/chaplain.yml +++ b/Resources/Prototypes/Roles/Jobs/Civilian/chaplain.yml @@ -9,7 +9,6 @@ # access: # - Chapel # - Maintenance - #- type: startingGear # id: ChaplainGear # equipment: @@ -18,3 +17,5 @@ # shoes: ClothingShoesColorBlack # idcard: ChaplainPDA # ears: ClothingHeadsetService +# innerclothingskirt: ClothingUniformJumpskirtChaplain + diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/chef.yml b/Resources/Prototypes/Roles/Jobs/Civilian/chef.yml index bc62b37288..c4e0fb978b 100644 --- a/Resources/Prototypes/Roles/Jobs/Civilian/chef.yml +++ b/Resources/Prototypes/Roles/Jobs/Civilian/chef.yml @@ -21,3 +21,5 @@ idcard: ChefPDA ears: ClothingHeadsetService outerclothing: ClothingOuterApronChef + innerclothingskirt: ClothingUniformJumpskirtChef + diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/janitor.yml b/Resources/Prototypes/Roles/Jobs/Civilian/janitor.yml index 5b5f6824d5..5cd9cdabd6 100644 --- a/Resources/Prototypes/Roles/Jobs/Civilian/janitor.yml +++ b/Resources/Prototypes/Roles/Jobs/Civilian/janitor.yml @@ -20,3 +20,5 @@ idcard: JanitorPDA ears: ClothingHeadsetService belt: ClothingBeltJanitorFilled + innerclothingskirt: ClothingUniformJumpskirtJanitor + diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/mime.yml b/Resources/Prototypes/Roles/Jobs/Civilian/mime.yml index c2053ca915..23317a6123 100644 --- a/Resources/Prototypes/Roles/Jobs/Civilian/mime.yml +++ b/Resources/Prototypes/Roles/Jobs/Civilian/mime.yml @@ -24,3 +24,5 @@ mask: ClothingMaskMime idcard: MimePDA ears: ClothingHeadsetService + innerclothingskirt: ClothingUniformJumpskirtMime + diff --git a/Resources/Prototypes/Roles/Jobs/Command/head_of_personnel.yml b/Resources/Prototypes/Roles/Jobs/Command/head_of_personnel.yml index ec51cd6a54..5558880f74 100644 --- a/Resources/Prototypes/Roles/Jobs/Command/head_of_personnel.yml +++ b/Resources/Prototypes/Roles/Jobs/Command/head_of_personnel.yml @@ -28,3 +28,5 @@ head: ClothingHeadHatHopcap idcard: HoPPDA ears: ClothingHeadsetAltCommand + innerclothingskirt: ClothingUniformJumpskirtHoP + diff --git a/Resources/Prototypes/Roles/Jobs/Engineering/chief_engineer.yml b/Resources/Prototypes/Roles/Jobs/Engineering/chief_engineer.yml index fea846c5a4..d029293184 100644 --- a/Resources/Prototypes/Roles/Jobs/Engineering/chief_engineer.yml +++ b/Resources/Prototypes/Roles/Jobs/Engineering/chief_engineer.yml @@ -25,3 +25,5 @@ idcard: CEPDA ears: ClothingHeadsetEngineering belt: ClothingBeltChiefEngineerFilled + innerclothingskirt: ClothingUniformJumpskirtChiefEngineer + diff --git a/Resources/Prototypes/Roles/Jobs/Engineering/station_engineer.yml b/Resources/Prototypes/Roles/Jobs/Engineering/station_engineer.yml index d99ed5d635..a7fa9b5d13 100644 --- a/Resources/Prototypes/Roles/Jobs/Engineering/station_engineer.yml +++ b/Resources/Prototypes/Roles/Jobs/Engineering/station_engineer.yml @@ -23,3 +23,5 @@ idcard: EngineerPDA belt: ClothingBeltUtilityFilled ears: ClothingHeadsetEngineering + innerclothingskirt: ClothingUniformJumpskirtEngineering + diff --git a/Resources/Prototypes/Roles/Jobs/Medical/chief_medical_officer.yml b/Resources/Prototypes/Roles/Jobs/Medical/chief_medical_officer.yml index 570a0c0c88..c29a91a31c 100644 --- a/Resources/Prototypes/Roles/Jobs/Medical/chief_medical_officer.yml +++ b/Resources/Prototypes/Roles/Jobs/Medical/chief_medical_officer.yml @@ -26,3 +26,5 @@ idcard: CMOPDA ears: ClothingHeadsetAltMedical belt: ClothingBeltMedical + innerclothingskirt: ClothingUniformJumpskirtCMO + diff --git a/Resources/Prototypes/Roles/Jobs/Medical/medical_doctor.yml b/Resources/Prototypes/Roles/Jobs/Medical/medical_doctor.yml index 55b09224aa..3e34d75574 100644 --- a/Resources/Prototypes/Roles/Jobs/Medical/medical_doctor.yml +++ b/Resources/Prototypes/Roles/Jobs/Medical/medical_doctor.yml @@ -21,3 +21,5 @@ idcard: MedicalPDA ears: ClothingHeadsetMedical belt: ClothingBeltMedical + innerclothingskirt: ClothingUniformJumpskirtMedicalDoctor + diff --git a/Resources/Prototypes/Roles/Jobs/Science/research_director.yml b/Resources/Prototypes/Roles/Jobs/Science/research_director.yml index 791d95ab78..32202b4a79 100644 --- a/Resources/Prototypes/Roles/Jobs/Science/research_director.yml +++ b/Resources/Prototypes/Roles/Jobs/Science/research_director.yml @@ -22,3 +22,5 @@ shoes: ClothingShoesColorBrown idcard: RnDPDA ears: ClothingHeadsetScience + innerclothingskirt: ClothingUniformJumpskirtResearchDirector + diff --git a/Resources/Prototypes/Roles/Jobs/Science/scientist.yml b/Resources/Prototypes/Roles/Jobs/Science/scientist.yml index dd32adf4fb..9d2c43eee9 100644 --- a/Resources/Prototypes/Roles/Jobs/Science/scientist.yml +++ b/Resources/Prototypes/Roles/Jobs/Science/scientist.yml @@ -20,3 +20,5 @@ outerclothing: ClothingOuterCoatLab idcard: SciencePDA ears: ClothingHeadsetScience + innerclothingskirt: ClothingUniformJumpskirtScientist + diff --git a/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml b/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml index dc7933d590..176222aa33 100644 --- a/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml +++ b/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml @@ -29,3 +29,5 @@ idcard: HoSPDA ears: ClothingHeadsetAltSecurity belt: ClothingBeltSecurityFilled + innerclothingskirt: ClothingUniformJumpskirtHoS + diff --git a/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml b/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml index 2cb0c2efdf..d9356cf6b3 100644 --- a/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml +++ b/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml @@ -24,3 +24,5 @@ idcard: SecurityPDA ears: ClothingHeadsetSecurity belt: ClothingBeltSecurityFilled + innerclothingskirt: ClothingUniformJumpskirtSec + diff --git a/Resources/Prototypes/Roles/Jobs/Security/warden.yml b/Resources/Prototypes/Roles/Jobs/Security/warden.yml index 5780ffd4d7..c9d250f9e0 100644 --- a/Resources/Prototypes/Roles/Jobs/Security/warden.yml +++ b/Resources/Prototypes/Roles/Jobs/Security/warden.yml @@ -25,3 +25,5 @@ idcard: WardenPDA ears: ClothingHeadsetSecurity belt: ClothingBeltSecurityFilled + innerclothingskirt: ClothingUniformJumpskirtWarden +