Skip to content

Dynamic Cosmetics Editor for Custom Models#6429

Open
Jameriquiah wants to merge 15 commits intoHarbourMasters:developfrom
Jameriquiah:dynamic-cosmetics-editor
Open

Dynamic Cosmetics Editor for Custom Models#6429
Jameriquiah wants to merge 15 commits intoHarbourMasters:developfrom
Jameriquiah:dynamic-cosmetics-editor

Conversation

@Jameriquiah
Copy link
Copy Markdown
Contributor

@Jameriquiah Jameriquiah commented Mar 28, 2026

port of HarbourMasters/2ship2harkinian#1617

same concept as over there, modders can set cosmetic entries and customize the name to whatever they want by adding a small tag into the primitive color line in the material xml

<SetPrimColor M="0" L="0" R="255" G="255" B="255" A="255" CosmeticEntry="Entry Name"/>

big difference here is i also added category support bc ships cosmetics editor is much bigger than 2ships, i can prolly add that over there too tho ig

so u would do

<SetPrimColor M="0" L="0" R="255" G="255" B="255" A="255" CosmeticCategory="Category Name" CosmeticEntry="Entry Name"/>

u can set cosmetic entries for anything in the game that u want to replace, so its not just limited to the player.

i will also add a way to automate this into fast64 soon to manual editing xml's wont be necessary

Build Artifacts

@Jameriquiah Jameriquiah changed the title dynamic cosmetics editor for custom models Dynamic Cosmetics Editor for Custom Models Mar 28, 2026
@Jepvid
Copy link
Copy Markdown
Contributor

Jepvid commented Mar 28, 2026

That is so much cleaner than what i had to do on my old pr

@serprex serprex requested a review from Malkierian March 28, 2026 16:48
@starbunny39
Copy link
Copy Markdown

I have tested the feature with my custom model, and can confirm that both this build and the feature successfully work on Linux.

Comment thread soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp Outdated
@Jameriquiah
Copy link
Copy Markdown
Contributor Author

would it be preferable to keep the custom entries where i have it now in the Link & Items tab or should i give it its own tab?

@Malkierian
Copy link
Copy Markdown
Contributor

Does the test mod on the 2ship PR work here as well, at least for showing the controls?

@Jameriquiah
Copy link
Copy Markdown
Contributor Author

Does the test mod on the 2ship PR work here as well, at least for showing the controls?

no, itll prolly crash soh tbh, i made a test mod for this one but forgot to upload it, one sec lol

@Jameriquiah
Copy link
Copy Markdown
Contributor Author

Jameriquiah commented Apr 1, 2026

saladcolortest.zip
i didnt go super crazy and add colors for like everything, just a couple to make sure it worked

@Jameriquiah
Copy link
Copy Markdown
Contributor Author

ok and bam, separate file now

Comment thread soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp Outdated
Comment thread soh/soh/Enhancements/cosmetics/DynamicCosmeticsEditor.cpp
@Jameriquiah Jameriquiah requested a review from Malkierian April 5, 2026 19:12
Comment thread soh/soh/Enhancements/cosmetics/DynamicCosmeticsEditor.cpp Outdated
Copy link
Copy Markdown
Contributor

@Malkierian Malkierian left a comment

Choose a reason for hiding this comment

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

I think this is good enough for a first-iteration. Since everything is in its own file anyway, it won't affect anything else, and iteration and streamlining of code can come later.

@Jameriquiah
Copy link
Copy Markdown
Contributor Author

sounds good! anything u need or want me to change just let me know and i can get on it :3

@Malkierian
Copy link
Copy Markdown
Contributor

My end goal was for you to replace usage of your CustomCosmeticEntry enum with the CosmeticEntry enum (and the associated COSMETIC_ENTRY macro) already in CosmeticsEditor.cpp, thus removing the need for those custom CVar creation functions.

@Malkierian
Copy link
Copy Markdown
Contributor

You don't have to use the table that the macro is used for in the Cosmetics Editor code, just the macro in your own storage structure. It should be possible to use it with a dynamic storage container.

@Jameriquiah
Copy link
Copy Markdown
Contributor Author

oh that was actually one of the few duped things that i dont think can be changed, i mean maybe? its entirely possible i just lack intelligence. i just couldnt figure out another way to do it that would also allow the colors to save between play sessions instead of just resetting to default everytime the game is restarted

@Malkierian
Copy link
Copy Markdown
Contributor

I think you were just too focused on the fact that the macro was used within a table initialization. The macro just returns a CosmeticEntry object that gets automatically added to the array at the index of its row count, that's all.

@Jameriquiah
Copy link
Copy Markdown
Contributor Author

ahh, makes sense

@Jameriquiah
Copy link
Copy Markdown
Contributor Author

alright im back home now, do u wanna just get this in as is? or is it cool if i make a few small changes?

@Malkierian
Copy link
Copy Markdown
Contributor

What kind of small changes?

@Jameriquiah
Copy link
Copy Markdown
Contributor Author

i can always pr them later if needed, but 1 i wanted to grayscale rgba textures when their color is changed so ugly color multiplication doesnt happen on textures with baked in color, and 2 allow entries that share a name with a vanilla static one to use it instead (not super high priority tbh)

@Jameriquiah
Copy link
Copy Markdown
Contributor Author

neither of these are super important tho so im totally fine holding off tbh

@Malkierian
Copy link
Copy Markdown
Contributor

I'd rather get this in first, then.

@Jameriquiah
Copy link
Copy Markdown
Contributor Author

alright thats fine :3

Comment thread soh/soh/Enhancements/cosmetics/DynamicCosmeticsEditor.cpp
}

static void SetCustomCosmeticColor(const CustomCosmeticEntry& entry, Color_RGBA8 color) {
const char* rainbowCvar = entry.option.rainbowCvar;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This probably isn't necessary, since there isn't a conversion of types from the CosmeticEntry member.


static void ResetCustomCosmeticColor(const CustomCosmeticEntry& entry) {
const char* rainbowCvar = entry.option.rainbowCvar;
const char* lockedCvar = entry.option.lockedCvar;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same as above for these. Doing this can also unnecessarily obfuscate sources.

Copy link
Copy Markdown
Contributor Author

@Jameriquiah Jameriquiah Apr 13, 2026

Choose a reason for hiding this comment

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

these ones in reset need to stay otherwise the reset button wont clear rainbow and locked like they should
although i could just try to get reset to just use ResetColor instead actually

}

static void DrawCustomCosmeticColorRow(const char* label, const char* cvar, Color_RGBA8 defaultColor,
const char* rainbowCvar, const char* lockedCvar, const char* changedCvar,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Perhaps this could be changed now to pass a reference to the CosmeticOption instead of all these individual arguments?

entryIndex = customCosmeticEntries.size();
entryIndicesByKey[key] = entryIndex;

CustomCosmeticEntry entry;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This part can still be converted to the COSMETIC_OPTION macro. All the string concatenation and such is handled in that macro.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

im not entirely sure if thats doable, im not able to feed it custom entry names at runtime with the macro

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Again I mention that the macro is different from the table.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

hmm my apologies i got confused

Comment thread soh/soh/Enhancements/cosmetics/DynamicCosmeticsEditor.cpp Outdated
Comment thread soh/soh/Enhancements/cosmetics/DynamicCosmeticsEditor.cpp Outdated
Copy link
Copy Markdown
Member

@PurpleHato PurpleHato left a comment

Choose a reason for hiding this comment

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

Definetely something we'll need to add to the modding process bible, but excited to see that happening, gg!

@Jameriquiah
Copy link
Copy Markdown
Contributor Author

indeed, its already in on the fast64 side, just need to write something short and sweet up for it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants