Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

World Icons #2279

Merged
merged 15 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading