Coding Help Issue with sleeves

Orphea

Farmhand
I am moving this from the Discord server to the forum. I need help properly implementing this sleeves overlay—personal or private project/mod. I only know the farmer arms have red sleeves in the sprite sheet within the game’s files. Someone explained to me in the server way before that it’s the default color that helps signify which is part of the clothing item and will auto-adjust in color based on the shirt’s color. My want is, to make the sleeves’ color toggleable somehow and deviate from the shirt’s. I have provided pixel art edits below. Also, in the first sprite image, I encircled two… hand bits? Or, skin in general, is exposed and isn’t covered by the sleeves. How do I fix that? [SOLVED]

CielPhantomhive_skin_.gif
arrows.png
CielPhantomhive_fixedart.png
arrows.png
CielPhantomhive_color.png


The reason why I tagged this as Coding Help is because I want to know if it’s possible to code the toggleable color part for the sleeves. Maybe use RGB instead of HSL, I think Fashion Sense does that, but this is just an overlay mod and doesn’t require FS for me. Maybe Generic Mod Config Menu if I were to make the toggleable color through GMCM. I don’t know how difficult that is, I was hoping to be taught here instead, as someone who has 0% clue about C# or any language in coding, or any about Stardew Valley modding. I only based the config.json file off of an existing mod, but I think that’s not really “learning” at all for me. I want to know how and why, and whatnot.

Warning: small rant ahead. Lastly, the reason why I have moved this or cross-posted this from Discord to this here server is because… probably no one can help, or I’m somehow shadow-banned by people or something. I usually get ignored and/or they would just, y’know, skip past my messages and reply to someone who posted before or after mine. I bumped my issue once and it still happened, but I didn’t want to be annoying and bump again, so… here I am, I guess. Small rant over.

(P.S.: The second and third sprite images are mere pixel edits and aren’t implemented into the game, so I really do need help still with whatever’s going on with them.)
 
Last edited:

SomeoneEls

Farmer
It is possible to change the color of your sleeves with the existing methods! There is a method in the game, called ApplySleeveColor(), that does that!
Here is the method.


C#:
// Stardew Valley, Version=1.6.15.24356, Culture=neutral, PublicKeyToken=null
// StardewValley.FarmerRenderer
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

public void ApplySleeveColor(string texture_name, Color[] pixels, Farmer who)
{
    who.GetDisplayShirt(out var shirtTexture, out var shirtIndex);
    Color[] shirtData = new Color[shirtTexture.Bounds.Width * shirtTexture.Bounds.Height];
    shirtTexture.GetData(shirtData);
    int index = shirtIndex * 8 / 128 * 32 * shirtTexture.Bounds.Width + shirtIndex * 8 % 128 + shirtTexture.Width * 4;
    int dyeIndex = index + 128;
    if (!who.ShirtHasSleeves() || index >= shirtData.Length || (skin.Value == -12345 && who.shirtItem.Value == null))
    {
        Texture2D skinColors = farmerTextureManager.Load<Texture2D>("Characters\\Farmer\\skinColors");
        Color[] skinColorsData = new Color[skinColors.Width * skinColors.Height];
        int skinIndex = skin.Value;
        if (skinIndex < 0)
        {
            skinIndex = skinColors.Height - 1;
        }
        if (skinIndex > skinColors.Height - 1)
        {
            skinIndex = 0;
        }
        skinColors.GetData(skinColorsData);
        Color darkest = skinColorsData[skinIndex * 3 % (skinColors.Height * 3)];
        Color medium = skinColorsData[skinIndex * 3 % (skinColors.Height * 3) + 1];
        Color lightest = skinColorsData[skinIndex * 3 % (skinColors.Height * 3) + 2];
        if (skin.Value == -12345)
        {
            darkest = pixels[260 + baseTexture.Width * 2];
            medium = pixels[261 + baseTexture.Width * 2];
            lightest = pixels[262 + baseTexture.Width * 2];
        }
        if (_sickFrame)
        {
            darkest = pixels[260 + baseTexture.Width];
            medium = pixels[261 + baseTexture.Width];
            lightest = pixels[262 + baseTexture.Width];
        }
        _SwapColor(texture_name, pixels, 256, darkest);
        _SwapColor(texture_name, pixels, 257, medium);
        _SwapColor(texture_name, pixels, 258, lightest);
    }
    else
    {
        Color color = Utility.MakeCompletelyOpaque(who.GetShirtColor());
        Color shirtSleeveColor = shirtData[dyeIndex];
        Color clothesColor = color;
        if (shirtSleeveColor.A < byte.MaxValue)
        {
            shirtSleeveColor = shirtData[index];
            clothesColor = Color.White;
        }
        shirtSleeveColor = Utility.MultiplyColor(shirtSleeveColor, clothesColor);
        _SwapColor(texture_name, pixels, 256, shirtSleeveColor);
        shirtSleeveColor = shirtData[dyeIndex - shirtTexture.Width];
        if (shirtSleeveColor.A < byte.MaxValue)
        {
            shirtSleeveColor = shirtData[index - shirtTexture.Width];
            clothesColor = Color.White;
        }
        shirtSleeveColor = Utility.MultiplyColor(shirtSleeveColor, clothesColor);
        _SwapColor(texture_name, pixels, 257, shirtSleeveColor);
        shirtSleeveColor = shirtData[dyeIndex - shirtTexture.Width * 2];
        if (shirtSleeveColor.A < byte.MaxValue)
        {
            shirtSleeveColor = shirtData[index - shirtTexture.Width * 2];
            clothesColor = Color.White;
        }
        shirtSleeveColor = Utility.MultiplyColor(shirtSleeveColor, clothesColor);
        _SwapColor(texture_name, pixels, 258, shirtSleeveColor);
    }
}

And here is some lines of code that can change your sleeve color to whatever you want. It's runtime based so no changing the actual data of the shirt.
C#:
//assembly stuff for pixelData
var va = Assembly.GetAssembly(typeof(StardewValley.FarmerRenderer))
                 .GetType("StardewValley.FarmerRenderer")
                 .GetMember("baseTexture", BindingFlags.Instance |
                BindingFlags.NonPublic |
                BindingFlags.Public);
Texture2D baseTexture = (Texture2D)((System.Reflection.FieldInfo)va.GetValue(0)).GetValue(Game1.player.FarmerRenderer);
Microsoft.Xna.Framework.Color[] pixelData = new Microsoft.Xna.Framework.Color[baseTexture.Width * baseTexture.Height];

//SET BASE TEXTURE DATA
baseTexture.GetData(pixelData);

//Get Shirt texture and shirt index
Texture2D shirtTexture = null;
int shirtIndex = 0;
Game1.player.GetDisplayShirt(out shirtTexture, out shirtIndex);
Microsoft.Xna.Framework.Color[] shirtData = new Microsoft.Xna.Framework.Color[shirtTexture.Bounds.Width * shirtTexture.Bounds.Height];


//get and set shirt data
shirtTexture.GetData(shirtData);
int dyeIndex = (shirtIndex * 8 / 128 * 32 * shirtTexture.Bounds.Width + shirtIndex * 8 % 128 + shirtTexture.Width * 4) + 128;


///IMPORTANT STUFF IF YOU WANT TO CHANGE COLOR//
shirtData[dyeIndex] = new Microsoft.Xna.Framework.Color(0, 0, 0); //SET COLOR HERE (color for edges)
shirtData[dyeIndex].A = byte.MaxValue;
shirtData[dyeIndex - shirtTexture.Width] = shirtData[dyeIndex]; //secondary color?
shirtData[dyeIndex - shirtTexture.Width*2] = shirtData[dyeIndex]; //primary color?
///IGNORE THE REST OF THIS//

shirtTexture.SetData(shirtData);


//apply that sleeve color!
Game1.player.FarmerRenderer.ApplySleeveColor(Game1.player.FarmerRenderer.textureName.Value, pixelData, Game1.player);
baseTexture.SetData(pixelData);
So yeah! I havent tested it on that mod yet but it should work in base!

For this to be a whole mod, some ui is needed, but the heart of it, how the sleeves change, is done!
If anyone wants to use this code for a mod that does that, go for it!
If you just wanna make your sleeves a certain color, put this code in your "DayStarted" method and set the rgb values at the SET COLOR HERE section.
You can set the shirtData[dyeIndex - shirtTexture.Width] and shirtData[dyeIndex - shirtTexture.Width*2] to other colors if ya want too!
 

Attachments

SomeoneEls

Farmer
Also if part of the sleeve is actually treated as part of the shirt then youll have to do some custom editing for the pixel values of that certain shirt, which uh...
Yeah you would have to do that for every outlier. So think of a template for where the shirt is colored for each outlier.
Lotta work if theres a bunch. But possible.

This is probably the case for the hand bits too.
 

Orphea

Farmhand
It is possible to change the color of your sleeves with the existing methods! There is a method in the game, called ApplySleeveColor(), that does that!

So yeah! I havent tested it on that mod yet but it should work in base!

For this to be a whole mod, some ui is needed, but the heart of it, how the sleeves change, is done!
If anyone wants to use this code for a mod that does that, go for it!
If you just wanna make your sleeves a certain color, put this code in your "DayStarted" method and set the rgb values at the SET COLOR HERE section.
You can set the shirtData[dyeIndex - shirtTexture.Width] and shirtData[dyeIndex - shirtTexture.Width*2] to other colors if ya want too!
I’m going to read through these codes, but if I may ask, do you think you can walk me through them if I don’t get what this or that does?

Also if part of the sleeve is actually treated as part of the shirt then youll have to do some custom editing for the pixel values of that certain shirt, which uh...
Yeah you would have to do that for every outlier. So think of a template for where the shirt is colored for each outlier.
Lotta work if theres a bunch. But possible.

This is probably the case for the hand bits too.
So, here’s what I did and just found out. I was basing my mod off of another that is only overlaying a sprite sheet on top of the farmer sprite. But I decided to just do a replacer instead, which means I’m also editing the farmer body sheet now. It was part of my plan anyway, so why not do it now. I have successfully fixed the fingers sticking out of the sleeves, because they were part of the original arms part of the sprite sheet. I removed the original and replace it with the sleeves which did the trick. Like I said, I think it’s now my plan to also work on the body, so the body is also being replaced here.

In the sprite sheet, the sleeves are red by default, and I was informed very early on that it’s the default color for the sleeves that would depend on the farmer’s worn shirt’s color. I asked last night on Discord, to try again, if I wanted change the color manually, will it apply? Didn’t get an answer on that one, too. But this was before receiving a notif that you replied to this thread. And I’m thankful for it immensely. Looking forward for your further replies to this. Would it be okay if I send you the files I’m working on? See what’s up with it? You can also provide feedback or suggestions if there are better ways to go on about the mod.
 
Top