diff --git a/code/__DEFINES/_flags/obj_flags.dm b/code/__DEFINES/_flags/obj_flags.dm
index e48146a1d0..ac772c6e8e 100644
--- a/code/__DEFINES/_flags/obj_flags.dm
+++ b/code/__DEFINES/_flags/obj_flags.dm
@@ -15,6 +15,7 @@
#define BLOCK_Z_IN_UP (1<<12) // Should this object block z uprise from below?
#define SHOVABLE_ONTO (1<<13)//called on turf.shove_act() to consider whether an object should have a niche effect (defined in their own shove_act()) when someone is pushed onto it, or do a sanity CanPass() check.
#define EXAMINE_SKIP (1<<14) /// Makes the Examine proc not read out this item.
+#define IN_STORAGE (1<<15) //is this item in the storage item, such as backpack? used for tooltips
/// Integrity defines for clothing (not flags but close enough)
#define CLOTHING_PRISTINE 0 // We have no damage on the clothing
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index 781fa38b94..c8e5b72f26 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -71,6 +71,7 @@ GLOBAL_LIST_INIT(bitfields, list(
"DROPDEL" = DROPDEL,
"NOBLUDGEON" = NOBLUDGEON,
"ABSTRACT" = ABSTRACT,
+ "IN_STORAGE" = IN_STORAGE,
"ITEM_CAN_BLOCK" = ITEM_CAN_BLOCK,
"ITEM_CAN_PARRY" = ITEM_CAN_PARRY
),
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index bfbdce41fd..56db868a21 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -141,11 +141,29 @@
/atom/movable/screen/inventory/MouseEntered()
..()
add_overlays()
+ //Apply the outline affect
+ add_stored_outline()
/atom/movable/screen/inventory/MouseExited()
..()
cut_overlay(object_overlays)
object_overlays.Cut()
+ remove_stored_outline()
+
+/atom/movable/screen/inventory/proc/add_stored_outline()
+ if(hud?.mymob && slot_id)
+ var/obj/item/inv_item = hud.mymob.get_item_by_slot(slot_id)
+ if(inv_item)
+ if(hud?.mymob.incapacitated())
+ inv_item.apply_outline(COLOR_RED_GRAY)
+ else
+ inv_item.apply_outline()
+
+/atom/movable/screen/inventory/proc/remove_stored_outline()
+ if(hud?.mymob && slot_id)
+ var/obj/item/inv_item = hud.mymob.get_item_by_slot(slot_id)
+ if(inv_item)
+ inv_item.remove_outline()
/atom/movable/screen/inventory/update_icon_state()
if(!icon_empty)
diff --git a/code/datums/components/storage/concrete/_concrete.dm b/code/datums/components/storage/concrete/_concrete.dm
index 55c3e1d083..bb226bbfdf 100644
--- a/code/datums/components/storage/concrete/_concrete.dm
+++ b/code/datums/components/storage/concrete/_concrete.dm
@@ -135,6 +135,8 @@
var/obj/item/I = AM
var/mob/M = parent.loc
I.dropped(M)
+ I.item_flags &= ~IN_STORAGE
+ I.remove_outline()
if(new_location)
AM.forceMove(new_location) // exited comsig will handle removal reset.
//We don't want to call this if the item is being destroyed
@@ -180,6 +182,7 @@
I.forceMove(parent.drop_location())
return FALSE
I.on_enter_storage(master)
+ I.item_flags |= IN_STORAGE
refresh_mob_views()
I.mouse_opacity = MOUSE_OPACITY_OPAQUE //So you can click on the area around the item to equip it, instead of having to pixel hunt
if(M)
diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm
index 752fafe6bd..97d6748dc7 100644
--- a/code/datums/components/storage/storage.dm
+++ b/code/datums/components/storage/storage.dm
@@ -423,6 +423,9 @@
var/atom/A = parent
if(ismob(M)) //all the check for item manipulation are in other places, you can safely open any storages as anything and its not buggy, i checked
A.add_fingerprint(M)
+ if(istype(A, /obj/item))
+ var/obj/item/I = A
+ I.remove_outline() //Removes the outline when we drag
if(!over_object)
return FALSE
if(ismecha(M.loc)) // stops inventory actions in a mech
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index cd486ccf6b..af7b69516d 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -146,6 +146,9 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
var/list/grind_results //A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only
var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder!
+ //the outline filter on hover
+ var/outline_filter
+
/* Our block parry data. Should be set in init, or something if you are using it.
* This won't be accessed without ITEM_CAN_BLOCK or ITEM_CAN_PARRY so do not set it unless you have to to save memory.
* If you decide it's a good idea to leave this unset while turning the flags on, you will runtime. Enjoy.
@@ -175,6 +178,12 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
if(force_string)
item_flags |= FORCE_STRING_OVERRIDE
+ if(istype(loc, /obj/item/storage))
+ item_flags |= IN_STORAGE
+
+ if(istype(loc, /obj/item/robot_module))
+ item_flags |= IN_INVENTORY
+
if(!hitsound)
if(damtype == "fire")
hitsound = 'sound/items/welder.ogg'
@@ -373,6 +382,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
if(!allow_attack_hand_drop(user) || !user.temporarilyRemoveItemFromInventory(src))
return
+ remove_outline()
pickup(user)
add_fingerprint(user)
if(!user.put_in_active_hand(src, FALSE, FALSE))
@@ -443,6 +453,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
qdel(src)
item_flags &= ~IN_INVENTORY
SEND_SIGNAL(src, COMSIG_ITEM_DROPPED,user)
+ remove_outline()
// if(!silent)
// playsound(src, drop_sound, DROP_SOUND_VOLUME, ignore_walls = FALSE)
user?.update_equipment_speed_mods()
@@ -867,18 +878,49 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
openToolTip(user,src,params,title = name,content = "[desc]
Force: [force_string]",theme = "")
/obj/item/MouseEntered(location, control, params)
- if((item_flags & IN_INVENTORY) && usr.client.prefs.enable_tips && !QDELETED(src))
+ SEND_SIGNAL(src, COMSIG_ITEM_MOUSE_ENTER, location, control, params)
+ if((item_flags & IN_INVENTORY || item_flags & IN_STORAGE) && usr.client.prefs.enable_tips && !QDELETED(src) || isobserver(usr))
var/timedelay = usr.client.prefs.tip_delay/100
var/user = usr
tip_timer = addtimer(CALLBACK(src, .proc/openTip, location, control, params, user), timedelay, TIMER_STOPPABLE)//timer takes delay in deciseconds, but the pref is in milliseconds. dividing by 100 converts it.
+ var/mob/living/L = usr
+ if(istype(L) && L.incapacitated())
+ apply_outline(COLOR_RED_GRAY)
+ else
+ apply_outline()
+
+/obj/item/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params)
+ . = ..()
+ remove_outline()
/obj/item/MouseExited(location,control,params)
SEND_SIGNAL(src, COMSIG_ITEM_MOUSE_EXIT, location, control, params)
deltimer(tip_timer)//delete any in-progress timer if the mouse is moved off the item before it finishes
closeToolTip(usr)
+ remove_outline()
-/obj/item/MouseEntered(location,control,params)
- SEND_SIGNAL(src, COMSIG_ITEM_MOUSE_ENTER, location, control, params)
+/obj/item/proc/apply_outline(colour = null)
+ if(!(item_flags & IN_INVENTORY || item_flags & IN_STORAGE) || QDELETED(src))
+ return
+ if(usr.client)
+ if(!usr.client.prefs.outline_enabled)
+ return
+ if(!colour)
+ if(usr.client)
+ colour = usr.client.prefs.outline_color
+ if(!colour)
+ colour = COLOR_BLUE_GRAY
+ else
+ colour = COLOR_BLUE_GRAY
+ if(outline_filter)
+ filters -= outline_filter
+ outline_filter = filter(type="outline", size=1, color=colour)
+ filters += outline_filter
+
+/obj/item/proc/remove_outline()
+ if(outline_filter)
+ filters -= outline_filter
+ outline_filter = null
// Called when a mob tries to use the item as a tool.
// Handles most checks.
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 5bc0440b77..40640f1d5b 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -60,6 +60,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
//autocorrected this round, not that you'd need to check that.
var/UI_style = null
+ var/outline_enabled = TRUE
+ var/outline_color = COLOR_BLUE_GRAY
var/buttons_locked = FALSE
var/hotkeys = FALSE
@@ -774,6 +776,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "
"
dat += "General Settings" dat += "UI Style: [UI_style]" + dat += "Outline: [outline_enabled ? "Enabled" : "Disabled"] " + dat += "Outline Color: Change " dat += "tgui Monitors: [(tgui_lock) ? "Primary" : "All"] " dat += "tgui Style: [(tgui_fancy) ? "Fancy" : "No Frills"] " dat += "Show Runechat Chat Bubbles: [chat_on_map ? "Enabled" : "Disabled"] " @@ -2706,6 +2710,12 @@ GLOBAL_LIST_EMPTY(preferences_datums) buttons_locked = !buttons_locked if("tgui_fancy") tgui_fancy = !tgui_fancy + if("outline_enabled") + outline_enabled = !outline_enabled + if("outline_color") + var/pickedOutlineColor = input(user, "Choose your outline color.", "General Preference", outline_color) as color|null + if(pickedOutlineColor) + outline_color = pickedOutlineColor if("tgui_lock") tgui_lock = !tgui_lock if("winflash") diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index d4d13dc40f..4d62bb149d 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -45,6 +45,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car if(current_version < 46) //If you remove this, remove force_reset_keybindings() too. force_reset_keybindings_direct(TRUE) addtimer(CALLBACK(src, .proc/force_reset_keybindings), 30) //No mob available when this is run, timer allows user choice. + if(current_version < 30) + outline_enabled = TRUE + outline_color = COLOR_BLUE_GRAY /datum/preferences/proc/update_character(current_version, savefile/S) if(current_version < 19) @@ -377,6 +380,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["ooccolor"] >> ooccolor S["lastchangelog"] >> lastchangelog S["UI_style"] >> UI_style + S["outline_color"] >> outline_color + S["outline_enabled"] >> outline_enabled S["hotkeys"] >> hotkeys S["chat_on_map"] >> chat_on_map S["max_chat_length"] >> max_chat_length @@ -555,6 +560,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["ooccolor"], ooccolor) WRITE_FILE(S["lastchangelog"], lastchangelog) WRITE_FILE(S["UI_style"], UI_style) + WRITE_FILE(S["outline_enabled"], outline_enabled) + WRITE_FILE(S["outline_color"], outline_color) WRITE_FILE(S["hotkeys"], hotkeys) WRITE_FILE(S["chat_on_map"], chat_on_map) WRITE_FILE(S["max_chat_length"], max_chat_length) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index efb4512bca..5ba4769f99 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -238,6 +238,7 @@ if(istype(W)) if(equip_to_slot_if_possible(W, slot, FALSE, FALSE, FALSE, FALSE, TRUE)) + W.apply_outline() return TRUE if(!W) |