Files
Bubberstation/code/game/atom/atom_appearance.dm
Bloop cb51a652a9 Adds automatic GAGS icon generation for mapping and the loadout menu (#90940)
## About The Pull Request

Revival of https://github.com/tgstation/tgstation/pull/86482, which is
even more doable now that we have rustg iconforge generation.

What this PR does:

- Sets up every single GAGS icon in the game to have their own preview
icon autogenerated during compile. This is configurable to not run
during live. The icons are created in `icons/map_icons/..`
- This also has the side effect of providing accurate GAGS icons for
things like the loadout menu. No more having to create your own
previews.


![FOuGL6ofxC](https://github.com/user-attachments/assets/e5414971-7f13-4883-9f7f-a8a212b46fe8)

<details><summary>Mappers rejoice!</summary>


![StrongDMM_1oeMSoRHXT](https://github.com/user-attachments/assets/83dcfe4c-31be-4953-98f3-dff90268bbc4)


![StrongDMM_uyqu3CggPn](https://github.com/user-attachments/assets/7896f99e-2656-40e1-a9da-3a513882365a)

</details>

<details><summary>Uses iconforge so it does not take up much time during
init</summary>


![dreamdaemon_u4Md3Dqwge](https://github.com/user-attachments/assets/17baaff8-5d5e-4a4d-ba8f-9dd548024155)

</details>

---

### Copied from https://github.com/tgstation/tgstation/pull/86482 as
this still applies:

Note for Spriters:

After you've assigned the correct values to vars, you must run the game
through init on your local machine and commit the changes to the map
icon dmi files. Unit tests should catch all cases of forgetting to
assign the correct vars, or not running through init.

Note for Server Operators:

In order to not generate these icons on live I've added a new config
entry which should be disabled on live called GENERATE_ASSETS_IN_INIT in
the config.txt


## Why It's Good For The Game

No more error icons in SDMM and loadout.

## Changelog

🆑
refactor: preview icons for greyscale items are now automatically
generated, meaning you can see GAGS as they actually appear ingame while
mapping or viewing the loadout menu.
/🆑

---------

Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
2025-05-24 15:21:02 -07:00

116 lines
3.3 KiB
Plaintext

/atom
///overlays managed by [update_overlays][/atom/proc/update_overlays] to prevent removing overlays that weren't added by the same proc. Single items are stored on their own, not in a list.
var/list/managed_overlays
/// The icon state that will be switched to during initialization.
/// Mostly intended for things that have a special map icon.
var/post_init_icon_state
/**
* Updates the appearence of the icon
*
* Mostly delegates to update_name, update_desc, and update_icon
*
* Arguments:
* - updates: A set of bitflags dictating what should be updated. Defaults to [ALL]
*/
/atom/proc/update_appearance(updates=ALL)
SHOULD_NOT_SLEEP(TRUE)
SHOULD_CALL_PARENT(TRUE)
. = NONE
updates &= ~SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_APPEARANCE, updates)
if(updates & UPDATE_NAME)
. |= update_name(updates)
if(updates & UPDATE_DESC)
. |= update_desc(updates)
if(updates & UPDATE_ICON)
. |= update_icon(updates)
/// Updates the name of the atom
/atom/proc/update_name(updates=ALL)
SHOULD_CALL_PARENT(TRUE)
return SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_NAME, updates)
/// Updates the description of the atom
/atom/proc/update_desc(updates=ALL)
SHOULD_CALL_PARENT(TRUE)
return SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_DESC, updates)
/// Updates the icon of the atom
/atom/proc/update_icon(updates=ALL)
SHOULD_CALL_PARENT(TRUE)
. = NONE
updates &= ~SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_ICON, updates)
if(updates & UPDATE_ICON_STATE)
update_icon_state()
. |= UPDATE_ICON_STATE
if(updates & UPDATE_OVERLAYS)
if(LAZYLEN(managed_vis_overlays))
SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays)
var/list/new_overlays = update_overlays(updates)
var/nulls = 0
for(var/i in 1 to length(new_overlays))
var/atom/maybe_not_an_atom = new_overlays[i]
if(isnull(maybe_not_an_atom))
nulls++
continue
if(istext(maybe_not_an_atom) || isicon(maybe_not_an_atom))
continue
new_overlays[i] = maybe_not_an_atom.appearance
if(nulls)
for(var/i in 1 to nulls)
new_overlays -= null
var/identical = FALSE
var/new_length = length(new_overlays)
if(!managed_overlays && !new_length)
identical = TRUE
else if(!islist(managed_overlays))
if(new_length == 1 && managed_overlays == new_overlays[1])
identical = TRUE
else if(length(managed_overlays) == new_length)
identical = TRUE
for(var/i in 1 to length(managed_overlays))
if(managed_overlays[i] != new_overlays[i])
identical = FALSE
break
if(!identical)
var/full_control = FALSE
if(managed_overlays)
full_control = length(overlays) == (islist(managed_overlays) ? length(managed_overlays) : 1)
if(full_control)
overlays = null
else
cut_overlay(managed_overlays)
switch(length(new_overlays))
if(0)
if(full_control)
POST_OVERLAY_CHANGE(src)
managed_overlays = null
if(1)
add_overlay(new_overlays)
managed_overlays = new_overlays[1]
else
add_overlay(new_overlays)
managed_overlays = new_overlays
. |= UPDATE_OVERLAYS
. |= SEND_SIGNAL(src, COMSIG_ATOM_UPDATED_ICON, updates, .)
/// Updates the icon state of the atom
/atom/proc/update_icon_state()
SHOULD_CALL_PARENT(TRUE)
return SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_ICON_STATE)
/// Updates the overlays of the atom
/atom/proc/update_overlays()
SHOULD_CALL_PARENT(TRUE)
. = list()
SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_OVERLAYS, .)