Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix broken layer hiding on clothes with multiple equipment slots #34080

Open
wants to merge 20 commits into
base: master
Choose a base branch
from

Conversation

paige404
Copy link

@paige404 paige404 commented Dec 26, 2024

About the PR

Adjusted ClothingSystem logic to confirm that a slot to be hidden by a HideLayerComponent matches the slot that an item is equipped in. Added more precise layer selection for the HideLayerClothingComponent, so that different layers may be hidden depending on which slot the item is equipped in. Adjusted the HumanAppearanceComponent to track which slot(s) are hiding each hidden layer (permanently hidden layers are unaffected by this change).

Before PR: ClothingSystem compared the sum combination of slots an item can be equipped in to the slot the HideLayerComponent's slot. This would always be false for clothing with more than one equip slot.

After PR: ClothingSystem specifically checks for a match between the item's current equipped slot and the HideLayerComponent's slot.

Why / Balance

Addresses issue #33965

Technical details

This should be slightly more performant in ToggleVisibleLayers--at the very least it should shift off some CPU cycles in exchange for a small amount of added memory. Specifically, nested loops over the character's inventory slots have been removed in favor of maintaining what had been small HashSets as small Dictionaries instead.

Care has been taken to ensure that no existing items break on this change. Items can use the new functionality added to HideLayerClothingComponent, but it isn't mandatory unless that item will be equippable in multiple clothing slots.

Media

Requirements

Breaking changes

Changelog

@github-actions github-actions bot added S: Untriaged Status: Indicates an item has not been triaged and doesn't have appropriate labels. size/XS Denotes a PR that changes 0-9 lines. labels Dec 26, 2024
@beck-thompson beck-thompson added T: Bugfix Type: Bugs and/or bugfixes P2: Raised Priority: Item has a raised priority, indicating it might get increased maintainer attention. D2: Medium Difficulty: A good amount of codebase knowledge required. S: Needs Review Status: Requires additional reviews before being fully accepted A: Art Area: Art with no implications for other areas. T: Visual Change Type: Deals with changes to art, sprites or other visuals in the game. and removed S: Untriaged Status: Indicates an item has not been triaged and doesn't have appropriate labels. labels Dec 27, 2024
…Component to allow more

precise layer hide behavior and more CPU efficient layer toggling.
@github-actions github-actions bot added size/S Denotes a PR that changes 10-99 lines. and removed size/XS Denotes a PR that changes 0-9 lines. labels Dec 31, 2024
@paige404 paige404 requested a review from ElectroJr December 31, 2024 23:49
@paige404 paige404 marked this pull request as draft January 1, 2025 03:13
…n layer (e.g. gas mask and welding mask)

Add documentation
Change gas masks to use the new HideLayerClothingComponent structure as an example of its usage
@github-actions github-actions bot added size/M Denotes a PR that changes 100-999 lines. and removed size/S Denotes a PR that changes 10-99 lines. labels Jan 7, 2025
@paige404 paige404 marked this pull request as ready for review January 7, 2025 21:43
@paige404
Copy link
Author

paige404 commented Jan 7, 2025

It required some bigger refactors than I'd intended, but this solves the problems and removes some excessive looping over the full inventory in ToggleVisibleLayers as a bonus.

I have noticed one strange behavior, though, which is somewhat inconsistent: occasionally, when equipping and then removing multiple layer-hiding pieces, the layer will stay hidden for an extra moment. Just long enough to be noticeable, but not long enough to be a serious issue.

For instance, equipping a bandana or a gas mask, then equipping a welding mask on top, then removing both. Sometimes, there will be a brief delay--less than a second--before the snout appears again. I think it has something to do with client and server mismatch, but I'm not sure where that's occurring. It's also possible that it's just a bottleneck issue on the part of my 10 year old machine running both client and server simultaneously.

Nevermind I fixed it.

@paige404
Copy link
Author

paige404 commented Jan 7, 2025

Also, I don't mind going through and converting all of the items using HideLayerClothingComponent over to the new setup. Compatibility is there so it isn't an issue either way, but getting them onto the new one is a good way to encourage future items to also use the new one.

Copy link
Member

@ElectroJr ElectroJr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than ClothingComponent.EquippedInSlot gteting cleared too early, it mostly seems fine. Though there are a few other changes I want to make to just clean up the system a bit, do you mind if I push some changes to your branch? Otherwise I can also just open a separate PR later

Content.Shared/Clothing/EntitySystems/ClothingSystem.cs Outdated Show resolved Hide resolved
Content.Shared/Clothing/EntitySystems/ClothingSystem.cs Outdated Show resolved Hide resolved
@paige404
Copy link
Author

paige404 commented Jan 9, 2025

Other than ClothingComponent.EquippedInSlot gteting cleared too early, it mostly seems fine. Though there are a few other changes I want to make to just clean up the system a bit, do you mind if I push some changes to your branch? Otherwise I can also just open a separate PR later

I don't mind at all! Better to have it clean the first time and fewer PRs IMO

any non-permanent visibility toggle with `SlotFlags.None` isn't supported with how its set up. And similarly, the slot flags argument does nothing if permanent = true. So IMO it makes more sense to infer it from a nullable arg.
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
@ElectroJr ElectroJr requested a review from Jezithyr as a code owner January 9, 2025 08:16
I'm just guessing at what this was meant to do
@ElectroJr
Copy link
Member

ElectroJr commented Jan 9, 2025

I've pushed some changes, including:

  • Splitting the layer hiding logic out of ClothingSystem and into a separate HideLayerClothingSystem.
  • Allowing an item to hide the same single layer from more than one slot.
  • Changing HumanoidAppearanceSystem.SetLayerVisibility to make the permanent option mutually exclusive with specifying a SlotFlag.
    • Specifically, I just removed the argument and made the slot flag argument nullable.
    • If its null it implies its not due to any clothing and thus "permanent".
    • Before it was possible to accidentally use permanent = false with flags = SlotFlags.None, which wouldn't have worked.
  • Reworking parts of MaskSystem, mainly to fix some networking & prediction bugs
    • It wasn't actually marking the component as dirty when changing IsToggled, leading to prediction issues.
    • There's parts here that I still don't really understand, and there weren't any comments. I've just tried to keep the functionality mostly unchanged, though I have renamed some fields like MaskComponent.IsEnabled to IsToggleable, because I think that's what it was meant to do??

Copy link
Author

@paige404 paige404 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgive me the liberty of reviewing your code in your review of my code, but there is one bug to fix here. I don't mind fixing it though, if you want.

Content.Shared/Clothing/Components/ClothingComponent.cs Outdated Show resolved Hide resolved
Content.Shared/Humanoid/SharedHumanoidAppearanceSystem.cs Outdated Show resolved Hide resolved
Copy link
Member

@ElectroJr ElectroJr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgive me the liberty of reviewing your code in your review of my code, but there is one bug to fix here. I don't mind fixing it though, if you want.

No worries, thanks for reviewing my changes. Assuming its the one you pointed out I just fixed it, but obviously feel free to push any changes you want to make or revert any I made, it's still your PR

Content.Shared/Clothing/Components/ClothingComponent.cs Outdated Show resolved Hide resolved
Content.Shared/Humanoid/SharedHumanoidAppearanceSystem.cs Outdated Show resolved Hide resolved
@paige404
Copy link
Author

paige404 commented Jan 11, 2025

... I found another bug, but I have no idea what's causing it. Folding a bandana to wear on the head, the bandana doesn't render when worn.

If you spawn a folded bandana and put it on your head, it renders appropriately. If you unfold that bandana and wear it on your face, that renders too. If you then refold the bandana and put it on your head, the bandana no longer renders on the sprite.

I'll dig into this some more, but this is not ready to ship.

Edit: I am completely stumped.

@paige404 paige404 requested a review from ElectroJr January 11, 2025 22:09
@ElectroJr
Copy link
Member

If you spawn a folded bandana and put it on your head, it renders appropriately. If you unfold that bandana and wear it on your face, that renders too. If you then refold the bandana and put it on your head, the bandana no longer renders on the sprite.

The cause was that toggling a mask sets a prefix for the clothing RSI state. Previously foldable clothing was being given special treatment in the mask system without any comments or explanation, and was seemingly not setting its rsi state specifically if the mask was being toggled due to folding, which I accidentally removed in an earlier commit.

I've fixed it now by making bandanas use the existing FoldableClothingComponent.FoldedEquippedPrefix instead of having some unintuitive hidden interaction with mask system. I've also fixed another bug in foldable clothing where it could just modify hidden layers while equipped. Every time I look at a new clothing system I find more spaghetti & weird interactions.

@paige404
Copy link
Author

I can find no bugs. LGTM.

@paige404
Copy link
Author

Oh hell. Merge conflicts. @ElectroJr it's in the code you changed. Could I ask you to fix it?

@github-actions github-actions bot added the S: Merge Conflict Status: Needs to resolve merge conflicts before it can be accepted label Jan 31, 2025
Copy link
Contributor

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@github-actions github-actions bot removed the S: Merge Conflict Status: Needs to resolve merge conflicts before it can be accepted label Feb 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A: Art Area: Art with no implications for other areas. D2: Medium Difficulty: A good amount of codebase knowledge required. P2: Raised Priority: Item has a raised priority, indicating it might get increased maintainer attention. S: Needs Review Status: Requires additional reviews before being fully accepted size/M Denotes a PR that changes 100-999 lines. T: Bugfix Type: Bugs and/or bugfixes T: Visual Change Type: Deals with changes to art, sprites or other visuals in the game.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants