ID:2395028
 
(See the best response by Kaiochao.)
Is there any way to manipulate icon state names on an icon dynamically?

Like if an icon has an icon state named "XXX", is there a way to take that icon and change that state name to "YYY"?

Likewise... is there a way to remove an icon state from an icon dynamically?

Like if I have an icon with 2 states, "Walking" and "Flight" is there a way to trim out the player's "Flight" icon state from their icon?

For both of these I'm not looking for the "Oh just open the icon file up in dreammaker and delete/rename the state". I want to do this in code.
Best response
It doesn't look like there's a built-in proc to remove a state. Maybe post a feature request?

Of course, you can still make an icon with every state other than a particular state, like so:
icon
proc
// to_remove may be a single state or a list of states.
RemoveState(to_remove)
var icon/result = new
for(var/state in IconStates() - to_remove)
result.Insert(icon(src, state), state)
return result

So if you want to remove the "blah" state from some icon "Stuff.dmi", you could do this:
// Get the icon
var icon/stuff = icon('Stuff.dmi')

// Get the icon with the state removed
var icon/new_stuff = stuff.RemoveState("blah")

// Save it to a new file
fcopy(new_stuff, "New Stuff.dmi")

And with that, you can also make a ReplaceState() by adding the state with a different name from the original.
icon
proc
ReplaceState(to_replace, replace_with)
var icon/result = new
for(var/state in IconStates())
result.Insert(icon(src, state), state == to_replace ? replace_with : state)
return result

// You could even take an associative list of (to_replace = replace_with)
// for efficiently doing multiple replacements.
ReplaceStates(list/replacements)
var icon/result = new
for(var/state in IconStates())
result.Insert(icon(src, state),
replacements[state] != null ? replacements[state] : state)
return result
proc/export_custom()

var/icon/my_icon = icon(usr.icon)
var/icon/new_icon = new

for(var/state in my_icon.IconStates() - "ZZZ")
new_icon.Insert(icon(my_icon, state), state == "XXX" ? "YYY" : state)

new_icon.Crop(1,1,32,32)

usr << ftp(new_icon,"[usr.name] Custom Icon.dmi")

return


The code you suggested has worked nearly ideally for me.

I also had to include a crop into it to fix some minor issues but your code works great here except for 1 minor issue.

It strips out the unwanted icon state no problem. But when it creates the new icon with the renamed state, it strips out the Movement flag on the state.

I looked into the Insert() proc a bit and was able to get the movement flag back on the state like this...

Insert(new_icon,icon_state,dir,frame,moving,delay)


new_icon.Insert(icon(my_icon, state), state == "XXX" ? "YYY" : state,,,1)


But that only works obviously if the icon is suppose to be a movement state. Is there a way to return if a state is a movement state or not so I can assign them correctly?
In response to IceFire2050
Can't check stuff like that in DM unfortunately.

There is a library that uses a .dll to do that, though:

http://www.byond.com/developer/DarkCampainger/DMIIconInfo