Skip to content

Commit

Permalink
World Icons (#2279)
Browse files Browse the repository at this point in the history
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may
not be viewable. -->
<!-- You can view Contributing.MD for a detailed description of the pull
request process. -->

## About The Pull Request
Ports world icons from Mojave 13.
This is an element that allows for tiny, size-accurate versions of
object sprites in a roundabout way.

~~Drafted since spritainers want more coverage before merging~~
UNDRAFTED by request of a spritainer. God weeps


### //MAKING A SUPER BASIC WORLD ICON IMPLEMENTATION GUIDE: FOR REAL. NO
VIRUS. 100% ORGANIC//

- Place the Element in an Init below The Item In Question

`/obj/item/Initialize()`
`	. = ..()`
`	AddElement(/datum/element/world_icon, null, icon, 'icon')`

- Fill in info. Put the ORIGINAL ICON in the addelement's `'icon'` slot
(yeah, this element layers the "original" sprite on top of the worldicon
one, using it as the default. It just be like that sometimes)

`/obj/item/kitchen/knife/combat/Initialize()`
`	. = ..()`
` AddElement(/datum/element/world_icon, null, icon,
'icons/obj/kitchen.dmi')`
	
- Put the directory to your NEW, WORLD ICON in the item's normal icon
var
	`icon = 'icons/obj/world/melee.dmi'`	

The world icon and icon adjustment vars on obj/item should allow for
implementation in places where an object's Icon has to frequently
change.

<!-- Describe The Pull Request. Please be sure every change is
documented or this can delay review and even discourage maintainers from
merging your PR! -->

## Why It's Good For The Game
Just a little guy
<!-- Please add a short description of why you think these changes would
benefit the game. If you can't justify it in words, it might not be
worth adding. -->

## Changelog

:cl:
add: World icon element.
add: World icons for combat knives.
/:cl:

<!-- Both :cl:'s are required for the changelog to work! You can put
your name to the right of the first :cl: if you want to overwrite your
GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the
icon ingame) and delete the unneeded ones. Despite some of the tags,
changelogs should generally represent how a player might be affected by
the changes rather than a summary of the PR's contents. -->

---------

Signed-off-by: Sun-Soaked <[email protected]>
Co-authored-by: Sun-Soaked <[email protected]>
Co-authored-by: FalloutFalcon <[email protected]>
  • Loading branch information
3 people authored May 31, 2024
1 parent 8fa9d08 commit 084eae0
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 2 deletions.
2 changes: 1 addition & 1 deletion code/datums/components/forensics.dm
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,4 @@
return
if(isitem(parent))
var/obj/item/I = parent
I.AddElement(/datum/element/decal/blood, initial(I.icon) || I.icon, initial(I.icon_state) || I.icon_state, _color = get_blood_dna_color(blood_DNA))
I.AddElement(/datum/element/decal/blood, I.icon, I.icon_state, _color = get_blood_dna_color(blood_DNA))
10 changes: 10 additions & 0 deletions code/datums/elements/decals/blood.dm
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@

. = ..()
RegisterSignal(target, COMSIG_ATOM_GET_EXAMINE_NAME, PROC_REF(get_examine_name), TRUE)
RegisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED), PROC_REF(redraw), TRUE)

/datum/element/decal/blood/Detach(atom/source, force)
UnregisterSignal(source, COMSIG_ATOM_GET_EXAMINE_NAME)
UnregisterSignal(source, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED))
return ..()

/datum/element/decal/blood/generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha, source)
Expand All @@ -30,3 +32,11 @@
override[EXAMINE_POSITION_ARTICLE] = A.gender == PLURAL? "some" : "a"
override[EXAMINE_POSITION_BEFORE] = " blood-stained "
return COMPONENT_EXNAME_CHANGED

///this is probably quite bad, let me know if you have a better solution for this -S
/datum/element/decal/blood/proc/redraw(datum/source, mob/user)
SIGNAL_HANDLER

var/atom/bloodsource = source
Detach(source)
bloodsource.AddElement(/datum/element/decal/blood, bloodsource.icon, bloodsource.icon_state, _color = get_blood_dna_color(bloodsource.return_blood_DNA()))
121 changes: 121 additions & 0 deletions code/datums/elements/world_icon.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/////////////////////////////////////////////////////////////
////////// WORLD ICON ELEMENT DIRECTORY //////////
/////////////////////////////////////////////////////////////
//PORTED FROM MOJAVE SUN//

// Slap onto something to give it a world icon that differs from the inventory one (allows for realistically sized objects and all that) //
// To fix 25/06/2021 : Blood Decals, Mutable Overlays and other baked in bitch ass overlays that need to be remade when the icon changes //
// Fixed 07/05/2022: Now you can deal with the above by handling everything with attached_proc instead
// Fixed 12/04/2023: Icon states, Needs major tuning up by someone who can properly make it work

/datum/element/world_icon
id_arg_index = 2
element_flags = ELEMENT_BESPOKE | ELEMENT_DETACH
//If we want COMPLEX world icon behavior, this proc will handle icon updating when the item is NOT in the inventory.
//I just assumed that the default update_icon is for inventory sprites because ss13 basically focuses on how the sprites
//look on your hand, not how they realistically look in the world.
var/attached_proc
/// Only used if attached_proc doesn't exist, simply changes the icon of target to this when it's in the inventory
var/inventory_icon
/// Only used if attached_proc doesn't exist, simply changes the icon of target to this when it's NOT in the inventory
var/world_icon
/// Only used when inventory state icon is different from original
var/inventory_icon_state
/// Only used when world state icon is different from original, pretty much just the original "icon_state" but if you for some reason need to flip the standard icon states for this element around you can use this
var/world_icon_state

/datum/element/world_icon/Attach(obj/item/target, attached_proc, world_icon, inventory_icon, world_icon_state, inventory_icon_state)
. = ..()
if(!istype(target))
return ELEMENT_INCOMPATIBLE

src.attached_proc = attached_proc
src.world_icon = world_icon
src.world_icon_state = world_icon_state
src.inventory_icon = inventory_icon
src.inventory_icon_state = inventory_icon_state
RegisterSignal(target, COMSIG_ATOM_UPDATE_ICON, PROC_REF(update_icon))
RegisterSignal(target, COMSIG_ATOM_UPDATE_ICON_STATE, PROC_REF(update_icon_state))
RegisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_STORAGE_ENTERED, COMSIG_ITEM_DROPPED, COMSIG_STORAGE_EXITED), PROC_REF(inventory_updated))
target.update_appearance(UPDATE_ICON)
target.update_appearance(UPDATE_ICON_STATE)

/datum/element/world_icon/Detach(obj/item/source)
. = ..()
UnregisterSignal(source, COMSIG_ATOM_UPDATE_ICON)
UnregisterSignal(source, COMSIG_ATOM_UPDATE_ICON_STATE, PROC_REF(update_icon_state))
UnregisterSignal(source, list(COMSIG_ITEM_EQUIPPED, COMSIG_STORAGE_ENTERED, COMSIG_ITEM_DROPPED, COMSIG_STORAGE_EXITED))
source.update_appearance(UPDATE_ICON)
source.update_appearance(UPDATE_ICON_STATE)

/datum/element/world_icon/proc/update_icon(obj/item/source, updates)
SIGNAL_HANDLER

if((source.item_flags & IN_INVENTORY) || (source.loc && SEND_SIGNAL(source.loc, COMSIG_CONTAINS_STORAGE)))
if(attached_proc)
return
return default_inventory_icon(source)

if(attached_proc)
return call(source, attached_proc)(updates)
else
return default_world_icon(source)

/datum/element/world_icon/proc/update_icon_state(obj/item/source, updates)
SIGNAL_HANDLER

if((source.item_flags & IN_INVENTORY) || (source.loc && SEND_SIGNAL(source.loc, COMSIG_CONTAINS_STORAGE)))
if(attached_proc)
return
return default_inventory_icon_state(source)

if(attached_proc)
return call(source, attached_proc)(updates)
else
return default_world_icon_state(source)

/datum/element/world_icon/proc/inventory_updated(obj/item/source)
SIGNAL_HANDLER

source.update_appearance(UPDATE_ICON)
source.update_appearance(UPDATE_ICON_STATE)

/datum/element/world_icon/proc/default_inventory_icon(obj/item/source)
SIGNAL_HANDLER

source.icon = inventory_icon

/datum/element/world_icon/proc/default_world_icon(obj/item/source)
SIGNAL_HANDLER

source.icon = world_icon

/datum/element/world_icon/proc/default_inventory_icon_state(obj/item/source)
SIGNAL_HANDLER

if(!inventory_icon_state)
source.icon_state = source.icon_state
return

INVOKE_ASYNC(src, PROC_REF(check_inventory_state), source)

/datum/element/world_icon/proc/default_world_icon_state(obj/item/source)
SIGNAL_HANDLER

if(!world_icon_state)
source.icon_state = source.icon_state
return

INVOKE_ASYNC(src, PROC_REF(check_world_icon_state), source)

/datum/element/world_icon/proc/check_inventory_state(obj/item/source)
SIGNAL_HANDLER

inventory_icon_state = source.inventory_state
source.icon_state = inventory_icon_state

/datum/element/world_icon/proc/check_world_icon_state(obj/item/source)
SIGNAL_HANDLER

world_icon_state = source.world_state
source.icon_state = world_icon_state
6 changes: 5 additions & 1 deletion code/game/objects/items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,10 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb

var/canMouseDown = FALSE

//for setting world icons on the go
var/inventory_state
var/world_state

/obj/item/Initialize()

if(attack_verb)
Expand Down Expand Up @@ -518,12 +522,12 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
/obj/item/proc/equipped(mob/user, slot, initial = FALSE)
SHOULD_CALL_PARENT(1)
visual_equipped(user, slot, initial)
SEND_SIGNAL(src, COMSIG_ITEM_EQUIPPED, user, slot)
for(var/X in actions)
var/datum/action/A = X
if(item_action_slot_check(slot, user)) //some items only give their actions buttons when in a specific slot.
A.Grant(user)
item_flags |= IN_INVENTORY
SEND_SIGNAL(src, COMSIG_ITEM_EQUIPPED, user, slot)
if(!initial)
if(equip_sound && (slot_flags & slot))
playsound(src, equip_sound, EQUIP_SOUND_VOLUME, TRUE, ignore_walls = FALSE)
Expand Down
5 changes: 5 additions & 0 deletions code/game/objects/items/kitchen.dm
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@

/obj/item/kitchen/knife/combat
name = "combat knife"
icon = 'icons/obj/world/melee.dmi'
icon_state = "combatknife"
item_state = "combatknife"
desc = "A military combat utility survival knife."
Expand All @@ -188,6 +189,10 @@
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "cut")
bayonet = TRUE

/obj/item/kitchen/knife/combat/Initialize()
. = ..()
AddElement(/datum/element/world_icon, null, icon, 'icons/obj/kitchen.dmi')

/obj/item/kitchen/knife/combat/survival
name = "survival knife"
icon_state = "survivalknife"
Expand Down
Binary file added icons/obj/world/melee.dmi
Binary file not shown.
1 change: 1 addition & 0 deletions shiptest.dme
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,7 @@
#include "code\datums\elements\update_icon_blocker.dm"
#include "code\datums\elements\update_icon_updates_onmob.dm"
#include "code\datums\elements\waddling.dm"
#include "code\datums\elements\world_icon.dm"
#include "code\datums\elements\decals\_decals.dm"
#include "code\datums\elements\decals\blood.dm"
#include "code\datums\helper_datums\events.dm"
Expand Down

0 comments on commit 084eae0

Please sign in to comment.