What i'm currently trying to do is write a coating system for food in our game (SS13 server), so people can dip things in batter and deepfry them. its a gloriously unhealthy quest.
For most normal foods, ive got the batter overlay working fine, but i'm having a problem with fruits and vegetables, which are a bit more complex.
First up, here's the code i'm using atm (called from within the food item)
var/icon/I = new /icon(icon, icon_state)
I.Blend(new /icon('icons/obj/food_custom.dmi', rgb(255,255,255)),ICON_ADD)
I.Blend(new /icon('icons/obj/food_custom.dmi', coating.icon_raw),ICON_MULTIPLY)
var/image/J = image(I)
J.alpha = batter_alpha
J.blend_mode = BLEND_OVERLAY
J.tag = "coating"
overlays += J
This takes the icon of the food, blends it with a plain white image to create a mask, and then masks that with the batter image, to get a cutout of batter shaped like the food. this works great mostly.
However, fruits and vegetables in SS13 are generated through a complex hydroponics system that allows for a variety of properties to change depending on genetics. In DM terms, they have no base icon, but are instead constructed from overlays. And even their overlays have overlays!
Ill post and dissect their code below in a moment. First an overview of what i need to do:
My aim here is to develop a means of fetching a complete representation of an object's visuals, ideally in an icon that i can use to blend with other things. This seems an inordinately complex task.
plant_icon = image('icons/obj/hydroponics_products.dmi',"blank")
var/image/fruit_base = image('icons/obj/hydroponics_products.dmi',"[seed.get_trait(TRAIT_PRODUCT_ICON)]-product")
fruit_base.color = "[seed.get_trait(TRAIT_PRODUCT_COLOUR)]"
plant_icon.overlays |= fruit_base
if("[seed.get_trait(TRAIT_PRODUCT_ICON)]-leaf" in icon_states('icons/obj/hydroponics_products.dmi'))
var/image/fruit_leaves = image('icons/obj/hydroponics_products.dmi',"[seed.get_trait(TRAIT_PRODUCT_ICON)]-leaf")
fruit_leaves.color = "[seed.get_trait(TRAIT_PLANT_COLOUR)]"
plant_icon.overlays |= fruit_leaves
plant_controller.plant_icon_cache[icon_key] = plant_icon
overlays |= plant_icon
This is code for a fruit.
It starts with generating an image, plant icon, and then two other images are added to it as overlays.
Creating a double nested overlay which is the entireity of a fruit's visuals.
The way i'm thinking of going at this would be to recurse through images in the overlays list, and overlays attached to those overlays, and try to blend them all down into one.
But i run into a major wall at the first hurdle. icon.blend cannot blend images, only other icons
What do i do about this? How do you blend images together?
There's another theoretical hurdle that i read in the documentation - overlays are converted into some internal format. so i'm wondering, do they even still exist as image objects?
And what about dealing with non-images used as overlays? I know its possible to use iconstates, other objects, icons, and images in the overlays list, and they all just work. how does all that function internally.
Do i have to iterate through the list, typecheck against all possibilities and apply different behaviour to each?
And my most important question. Is this really so hard to do?
Is there some built in/native function or var that i can use to just grab an object's visuals in one go? Does a client really handle all this complexity just to display an icon?