Skip to content

Commit

Permalink
Species Information in Guidebooks and Shortcut in Character Editor (#7)
Browse files Browse the repository at this point in the history
# Description

Wouldn't it be great if we had Species info in the Guidebook?
Wouldn't it be even better if this was available in the character
editor? Now there will be an info button next to the species selection
dropdown, complete with hover tooltip. Pressing the button opens the
relevant Guidebook page and also loads the other species pages, so the
player can click check them all without having to change species in the
character editor.

---

<details><summary><h1>Media</h2></summary>
<p>


![1](https://private-user-images.githubusercontent.com/35878406/310249378-5ef5a892-2290-445e-b347-7d81265a261d.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTA3MDI4MzMsIm5iZiI6MTcxMDcwMjUzMywicGF0aCI6Ii8zNTg3ODQwNi8zMTAyNDkzNzgtNWVmNWE4OTItMjI5MC00NDVlLWIzNDctN2Q4MTI2NWEyNjFkLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDAzMTclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwMzE3VDE5MDg1M1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTk3NDdhMDZjMzU2YjI0YWVmZjc3MjEwMmI4ODJiOGUzZTljNmU5ZGE1ODIxYjZkNjFkYjgxNDU5ZGY2ZTdhZGUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.A05R1DRjL1uDD3-XL0ztRR2zG2MDCHNoW5Pjs8nmW1w)


![2](https://private-user-images.githubusercontent.com/35878406/309905910-90953fbc-d264-4908-ad20-ace690a296c0.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTA3MDI4MzMsIm5iZiI6MTcxMDcwMjUzMywicGF0aCI6Ii8zNTg3ODQwNi8zMDk5MDU5MTAtOTA5NTNmYmMtZDI2NC00OTA4LWFkMjAtYWNlNjkwYTI5NmMwLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDAzMTclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwMzE3VDE5MDg1M1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTQxY2Y2NGYwZTdhZmQ0NWRhOWFiOWMwMDc0YTVmOGJjNzU0N2ZkMGM5NzY4NTZkNzJiYzk1ZjViNTc4ODYzNDgmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.t1gTj4gzm6Kon5N2Dlg-H4uOwIrDMSre3gnKhM4qU7A)


![3](https://private-user-images.githubusercontent.com/35878406/309905952-b52e9c05-141c-4078-9ec6-d34318c5d35b.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTA3MDI4MzMsIm5iZiI6MTcxMDcwMjUzMywicGF0aCI6Ii8zNTg3ODQwNi8zMDk5MDU5NTItYjUyZTljMDUtMTQxYy00MDc4LTllYzYtZDM0MzE4YzVkMzViLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDAzMTclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwMzE3VDE5MDg1M1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTVmNGZlMGU1Y2Q4Mjc3YWEyNjIxNjQ1YTg4MzQ3MzVhZTg3YTkzMjBmZDE1NzcwM2NlYjc1MTAyNWI3OGJlNTAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.XkaMdUDpi2uZxRqb4NtVf9JX45yE1sn2xRrsEELCDA8)

</p>
</details> 

# Changelog

:cl: Errant
- add: Added guidebooks for species
- add: Species in the character editor have a shortcut to their
guidebook entry

Co-authored-by: Errant <[email protected]>
  • Loading branch information
DEATHB4DEFEAT and Errant-4 authored Mar 23, 2024
1 parent b58ef28 commit ee276f7
Show file tree
Hide file tree
Showing 16 changed files with 279 additions and 17 deletions.
1 change: 1 addition & 0 deletions Content.Client/Preferences/UI/HumanoidProfileEditor.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
<BoxContainer HorizontalExpand="True">
<Label Text="{Loc 'humanoid-profile-editor-species-label'}" />
<Control HorizontalExpand="True"/>
<TextureButton Name="SpeciesInfoButton" Scale="0.3 0.3" VerticalAlignment="Center"></TextureButton>
<OptionButton Name="CSpeciesButton" HorizontalAlignment="Right" />
</BoxContainer>
<!-- Age -->
Expand Down
44 changes: 44 additions & 0 deletions Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System.Linq;
using System.Numerics;
using Content.Client.Guidebook;
using Content.Client.Humanoid;
using Content.Client.Lobby.UI;
using Content.Client.Message;
using Content.Client.Players.PlayTimeTracking;
using Content.Client.Stylesheets;
using Content.Client.UserInterface.Controls;
using Content.Client.UserInterface.Systems.Guidebook;
using Content.Shared.CCVar;
using Content.Shared.GameTicking;
using Content.Shared.Humanoid;
Expand Down Expand Up @@ -116,6 +118,8 @@ public HumanoidProfileEditor(IClientPreferencesManager preferencesManager, IProt
_configurationManager = configurationManager;
_markingManager = IoCManager.Resolve<MarkingManager>();

SpeciesInfoButton.ToolTip = Loc.GetString("humanoid-profile-editor-guidebook-button-tooltip");

#region Left

#region Randomize
Expand Down Expand Up @@ -523,10 +527,30 @@ public HumanoidProfileEditor(IClientPreferencesManager preferencesManager, IProt

preferencesManager.OnServerDataLoaded += LoadServerData;

SpeciesInfoButton.OnPressed += OnSpeciesInfoButtonPressed;

UpdateSpeciesGuidebookIcon();

IsDirty = false;
}

private void OnSpeciesInfoButtonPressed(BaseButton.ButtonEventArgs args)
{
var guidebookController = UserInterfaceManager.GetUIController<GuidebookUIController>();
var species = Profile?.Species ?? SharedHumanoidAppearanceSystem.DefaultSpecies;
var page = "Species";
if (_prototypeManager.HasIndex<GuideEntryPrototype>(species))
page = species;

if (_prototypeManager.TryIndex<GuideEntryPrototype>("Species", out var guideRoot))
{
var dict = new Dictionary<string, GuideEntry>();
dict.Add("Species", guideRoot);
//TODO: Don't close the guidebook if its already open, just go to the correct page
guidebookController.ToggleGuidebook(dict, includeChildren:true, selected: page);
}
}

private void ToggleClothes(BaseButton.ButtonEventArgs obj)
{
RebuildSpriteView();
Expand Down Expand Up @@ -822,6 +846,7 @@ private void SetSpecies(string newSpecies)
CMarkings.SetSpecies(newSpecies); // Repopulate the markings tab as well.
UpdateSexControls(); // update sex for new species
RebuildSpriteView(); // they might have different inv so we need a new dummy
UpdateSpeciesGuidebookIcon();
IsDirty = true;
_needUpdatePreview = true;
}
Expand Down Expand Up @@ -973,6 +998,25 @@ private void UpdateSkinColor()

}

public void UpdateSpeciesGuidebookIcon()
{
SpeciesInfoButton.StyleClasses.Clear();

var species = Profile?.Species;
if (species is null)
return;

if (!_prototypeManager.TryIndex<SpeciesPrototype>(species, out var speciesProto))
return;

// Don't display the info button if no guide entry is found
if (!_prototypeManager.HasIndex<GuideEntryPrototype>(species))
return;

var style = speciesProto.GuideBookIcon;
SpeciesInfoButton.StyleClasses.Add(style);
}

private void UpdateMarkings()
{
if (Profile == null)
Expand Down
8 changes: 8 additions & 0 deletions Content.Client/Stylesheets/StyleNano.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1392,6 +1392,14 @@ public StyleNano(IResourceCache resCache) : base(resCache)
.Prop(Control.StylePropertyModulateSelf, Color.FromHex("#753131")),
// ---

// Profile Editor
Element<TextureButton>().Class("SpeciesInfoDefault")
.Prop(TextureButton.StylePropertyTexture, resCache.GetTexture("/Textures/Interface/VerbIcons/information.svg.192dpi.png")),

Element<TextureButton>().Class("SpeciesInfoWarning")
.Prop(TextureButton.StylePropertyTexture, resCache.GetTexture("/Textures/Interface/info.svg.192dpi.png"))
.Prop(Control.StylePropertyModulateSelf, Color.FromHex("#eeee11")),

// The default look of paper in UIs. Pages can have components which override this
Element<PanelContainer>().Class("PaperDefaultBorder")
.Prop(PanelContainer.StylePropertyPanel, paperBackground),
Expand Down
40 changes: 23 additions & 17 deletions Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@ public sealed partial class SpeciesPrototype : IPrototype
/// <summary>
/// User visible name of the species.
/// </summary>
[DataField("name", required: true)]
[DataField(required: true)]
public string Name { get; private set; } = default!;

/// <summary>
/// Descriptor. Unused...? This is intended
/// for an eventual integration into IdentitySystem
/// (i.e., young human person, young lizard person, etc.)
/// </summary>
[DataField("descriptor")]
[DataField]
public string Descriptor { get; private set; } = "humanoid";

/// <summary>
/// Whether the species is available "at round start" (In the character editor)
/// </summary>
[DataField("roundStart", required: true)]
[DataField(required: true)]
public bool RoundStart { get; private set; } = false;

// The below two are to avoid fetching information about the species from the entity
Expand All @@ -47,14 +47,14 @@ public sealed partial class SpeciesPrototype : IPrototype
/// <summary>
/// Default skin tone for this species. This applies for non-human skin tones.
/// </summary>
[DataField("defaultSkinTone")]
[DataField]
public Color DefaultSkinTone { get; private set; } = Color.White;

/// <summary>
/// Default human skin tone for this species. This applies for human skin tones.
/// See <see cref="SkinColor.HumanSkinTone"/> for the valid range of skin tones.
/// </summary>
[DataField("defaultHumanSkinTone")]
[DataField]
public int DefaultHumanSkinTone { get; private set; } = 20;

/// <summary>
Expand All @@ -66,60 +66,66 @@ public sealed partial class SpeciesPrototype : IPrototype
/// <summary>
/// Humanoid species variant used by this entity.
/// </summary>
[DataField("prototype", required: true, customTypeSerializer:typeof(PrototypeIdSerializer<EntityPrototype>))]
[DataField(required: true, customTypeSerializer:typeof(PrototypeIdSerializer<EntityPrototype>))]
public string Prototype { get; private set; } = default!;

/// <summary>
/// Prototype used by the species for the dress-up doll in various menus.
/// </summary>
[DataField("dollPrototype", required: true, customTypeSerializer:typeof(PrototypeIdSerializer<EntityPrototype>))]
[DataField(required: true, customTypeSerializer:typeof(PrototypeIdSerializer<EntityPrototype>))]
public string DollPrototype { get; private set; } = default!;

/// <summary>
/// Method of skin coloration used by the species.
/// </summary>
[DataField("skinColoration", required: true)]
[DataField(required: true)]
public HumanoidSkinColor SkinColoration { get; private set; }

[DataField("maleFirstNames")]
[DataField]
public string MaleFirstNames { get; private set; } = "names_first_male";

[DataField("femaleFirstNames")]
[DataField]
public string FemaleFirstNames { get; private set; } = "names_first_female";

[DataField("lastNames")]
[DataField]
public string LastNames { get; private set; } = "names_last";

[DataField("naming")]
[DataField]
public SpeciesNaming Naming { get; private set; } = SpeciesNaming.FirstLast;

[DataField("sexes")]
[DataField]
public List<Sex> Sexes { get; private set; } = new() { Sex.Male, Sex.Female };

/// <summary>
/// Characters younger than this are too young to be hired by Nanotrasen.
/// </summary>
[DataField("minAge")]
[DataField]
public int MinAge = 18;

/// <summary>
/// Characters younger than this appear young.
/// </summary>
[DataField("youngAge")]
[DataField]
public int YoungAge = 30;

/// <summary>
/// Characters older than this appear old. Characters in between young and old age appear middle aged.
/// </summary>
[DataField("oldAge")]
[DataField]
public int OldAge = 60;

/// <summary>
/// Characters cannot be older than this. Only used for restrictions...
/// although imagine if ghosts could age people WYCI...
/// </summary>
[DataField("maxAge")]
[DataField]
public int MaxAge = 120;

/// <summary>
/// The Style used for the guidebook info link in the character profile editor
/// </summary>
[DataField]
public string GuideBookIcon = "SpeciesInfoDefault";
}

public enum SpeciesNaming : byte
Expand Down
1 change: 1 addition & 0 deletions Resources/Locale/en-US/guidebook/guides.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ guide-entry-security = Security
guide-entry-forensics = Forensics
guide-entry-defusal = Large Bomb Defusal
guide-entry-criminal-records = Criminal Records
guide-entry-species = Species
guide-entry-antagonists = Antagonists
guide-entry-nuclear-operatives = Nuclear Operatives
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ humanoid-profile-editor-preference-jumpskirt = Jumpskirt
humanoid-profile-editor-preference-backpack = Backpack
humanoid-profile-editor-preference-satchel = Satchel
humanoid-profile-editor-preference-duffelbag = Duffelbag
humanoid-profile-editor-guidebook-button-tooltip = Click for more info
# Spawn priority
humanoid-profile-editor-preference-spawn-priority-none = None
Expand Down
47 changes: 47 additions & 0 deletions Resources/Prototypes/Guidebook/species.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
- type: guideEntry
id: Species
name: guide-entry-species
text: "/ServerInfo/Guidebook/Mobs/Species.xml"
children:
- Arachnid
- Diona
- Dwarf
- Human
- Moth
- Reptilian
- SlimePerson

- type: guideEntry
id: Arachnid
name: species-name-arachnid
text: "/ServerInfo/Guidebook/Mobs/Arachnid.xml"

- type: guideEntry
id: Diona
name: species-name-diona
text: "/ServerInfo/Guidebook/Mobs/Diona.xml"

- type: guideEntry
id: Dwarf
name: species-name-dwarf
text: "/ServerInfo/Guidebook/Mobs/Dwarf.xml"

- type: guideEntry
id: Human
name: species-name-human
text: "/ServerInfo/Guidebook/Mobs/Human.xml"

- type: guideEntry
id: Moth
name: species-name-moth
text: "/ServerInfo/Guidebook/Mobs/Moth.xml"

- type: guideEntry
id: Reptilian
name: species-name-reptilian
text: "/ServerInfo/Guidebook/Mobs/Reptilian.xml"

- type: guideEntry
id: SlimePerson
name: species-name-slime
text: "/ServerInfo/Guidebook/Mobs/SlimePerson.xml"
1 change: 1 addition & 0 deletions Resources/Prototypes/Guidebook/ss14.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- Survival
- Chemicals
- Antagonists
- Species
- Writing
- Glossary

Expand Down
25 changes: 25 additions & 0 deletions Resources/ServerInfo/Guidebook/Mobs/Arachnid.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Document>
# Arachnids

<Box>
<GuideEntityEmbed Entity="MobArachnid" Caption=""/>
</Box>

They have two additional Pocket slots in their inventory. They can eat raw meat without any ill effects, but some foods like chocolate and onion poisons them.
They suffocate 50% faster, and their Blue Blood can't be metabolised from Iron, being based on Copper instead.

Their unarmed attacks deal Piercing damage instead of Blunt.

## Sericulture

<Box>
<GuideEntityEmbed Entity="MaterialWebSilk" Caption=""/>
<GuideEntityEmbed Entity="ClothingUniformJumpskirtWeb" Caption=""/>
<GuideEntityEmbed Entity="WebShield" Caption=""/>
<GuideEntityEmbed Entity="WallWeb" Caption=""/>
</Box>

Arachnids can create Websilk at the cost of getting more hungry. They (and only they) can craft bundles of websilk into various items from clothing and shields to entire walls.


</Document>
38 changes: 38 additions & 0 deletions Resources/ServerInfo/Guidebook/Mobs/Diona.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<Document>
# Diona

<Box>
<GuideEntityEmbed Entity="MobDiona" Caption=""/>
</Box>

They can't wear shoes, but are not slowed by Kudzu.
They get hungry and thirsty slower.
Their "blood" is normal water and can't be metabolised from Iron.
Being plants, Weed Killer poisons them, while Robust Harvest heals them (but not without risk when overused!)

They take [color=#1e90ff]30% less Blunt damage and 20% less Slash damage[/color];
but [color=#ffa500]50% more Heat damage, 20% more Shock damage, and they can easily
catch on fire when receiving enough Heat damage from *any* source.[/color]

## Make Like A Tree And Leave
<Box>
<GuideEntityEmbed Entity="FloraTree06" Caption=""/>
</Box>
Being exposed to too much Robust Harvest will cause a Diona to grow out of control, turning into an immobile tree (dropping all their equipment).
Cutting down the tree will "restore" the Diona to their mobile state.

## Diona Nymphs
<Box>
<GuideEntityEmbed Entity="MobDionaNymph" Caption=""/>
<GuideEntityEmbed Entity="MobDionaNymph" Caption=""/>
<GuideEntityEmbed Entity="MobDionaNymph" Caption=""/>
</Box>
After death, a Diona can voluntarily destroy their own body, releasing their "internal organs" as three Nymphs,
with the player taking control of the Brain Nymph.
It can talk but has no hands or inventory, and can't do much.

After 10 minutes, a Nymph can reform into a whole Diona. This will be a new randomised body with a random name,
and there will be little to no evidence beyond their word about who they were before.


</Document>
11 changes: 11 additions & 0 deletions Resources/ServerInfo/Guidebook/Mobs/Dwarf.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Document>
# Dwarves

<Box>
<GuideEntityEmbed Entity="MobDwarf" Caption=""/>
</Box>

Dwarves are similar to humans in most respect, but tolerate alcohol better and are healed by it.


</Document>
11 changes: 11 additions & 0 deletions Resources/ServerInfo/Guidebook/Mobs/Human.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Document>
# Humans

<Box>
<GuideEntityEmbed Entity="MobHumanDummy" Caption=""/>
</Box>

Depending on who you ask, humans are either unremarkable or the universal standard to which everything else is compared.
They have no special mechanics or notable attributes.

</Document>
Loading

0 comments on commit ee276f7

Please sign in to comment.