Port of Hover Inventory and Body Zone Hover Indicators.

The body zone selector now indicates which body part you are about to select when hovered over, and the hover inventory indicator basically shows where you are trying to put an item, and then shows an item ghost in red or green, giving visual feedback as to if that item will go in the slot or not.

Gifs of this in action:
![https://i.imgur.com/MTi7Kpn.gif](https://i.imgur.com/MTi7Kpn.gif) 
Body Selection parts.

![https://i.imgur.com/KbLqWKy.gif](https://i.imgur.com/KbLqWKy.gif) 
Inventory Icon Overlays!

Credit goes to @ShadowLarkens for original port to Paradise and assistance with port to Virgo. Downstream port of https://github.com/VOREStation/VOREStation/pull/7748

- A note on `code/game/objects/items/weapons/storage/internal.dm`, VSCode automatically corrected the line endings, hence the massive filediff. The only practical changes are the addition of `disable_warning = 0`
This commit is contained in:
Rykka
2020-05-10 08:24:40 -04:00
parent 8476073790
commit 5c5ac378a4
10 changed files with 201 additions and 131 deletions

View File

@@ -28,6 +28,7 @@
inv_box.icon = ui_style inv_box.icon = ui_style
inv_box.color = ui_color inv_box.color = ui_color
inv_box.alpha = ui_alpha inv_box.alpha = ui_alpha
inv_box.hud = src
var/list/slot_data = hud_data.gear[gear_slot] var/list/slot_data = hud_data.gear[gear_slot]
inv_box.name = gear_slot inv_box.name = gear_slot
@@ -192,6 +193,7 @@
using.screen_loc = ui_swaphand1 using.screen_loc = ui_swaphand1
using.color = ui_color using.color = ui_color
using.alpha = ui_alpha using.alpha = ui_alpha
using.hud = src
src.adding += using src.adding += using
using = new /obj/screen/inventory() using = new /obj/screen/inventory()
@@ -201,6 +203,7 @@
using.screen_loc = ui_swaphand2 using.screen_loc = ui_swaphand2
using.color = ui_color using.color = ui_color
using.alpha = ui_alpha using.alpha = ui_alpha
using.hud = src
src.adding += using src.adding += using
if(hud_data.has_resist) if(hud_data.has_resist)

View File

@@ -31,7 +31,36 @@
/obj/screen/inventory /obj/screen/inventory
var/slot_id //The indentifier for the slot. It has nothing to do with ID cards. var/slot_id //The indentifier for the slot. It has nothing to do with ID cards.
var/list/object_overlays = list() // Required for inventory/screen overlays.
/obj/screen/inventory/MouseEntered()
..()
add_overlays()
/obj/screen/inventory/MouseExited()
..()
cut_overlay(object_overlays)
object_overlays.Cut()
/obj/screen/inventory/proc/add_overlays()
var/mob/user = hud.mymob
if(hud && user && slot_id)
var/obj/item/holding = user.get_active_hand()
if(!holding || user.get_equipped_item(slot_id))
return
var/image/item_overlay = image(holding)
item_overlay.alpha = 92
if(!holding.mob_can_equip(user, slot_id, disable_warning = TRUE))
item_overlay.color = "#ff0000"
else
item_overlay.color = "#00ff00"
object_overlays += item_overlay
add_overlay(object_overlays)
/obj/screen/close /obj/screen/close
name = "close" name = "close"
@@ -102,78 +131,116 @@
icon_state = "zone_sel" icon_state = "zone_sel"
screen_loc = ui_zonesel screen_loc = ui_zonesel
var/selecting = BP_TORSO var/selecting = BP_TORSO
var/static/list/hover_overlays_cache = list()
var/hovering_choice
var/mutable_appearance/selecting_appearance
/obj/screen/zone_sel/Click(location, control,params) /obj/screen/zone_sel/Click(location, control,params)
if(isobserver(usr))
return
var/list/PL = params2list(params) var/list/PL = params2list(params)
var/icon_x = text2num(PL["icon-x"]) var/icon_x = text2num(PL["icon-x"])
var/icon_y = text2num(PL["icon-y"]) var/icon_y = text2num(PL["icon-y"])
var/old_selecting = selecting //We're only going to update_icon() if there's been a change var/choice = get_zone_at(icon_x, icon_y)
if(!choice)
return 1
return set_selected_zone(choice, usr)
/obj/screen/zone_sel/MouseEntered(location, control, params)
MouseMove(location, control, params)
/obj/screen/zone_sel/MouseMove(location, control, params)
if(isobserver(usr))
return
var/list/PL = params2list(params)
var/icon_x = text2num(PL["icon-x"])
var/icon_y = text2num(PL["icon-y"])
var/choice = get_zone_at(icon_x, icon_y)
if(hovering_choice == choice)
return
vis_contents -= hover_overlays_cache[hovering_choice]
hovering_choice = choice
var/obj/effect/overlay/zone_sel/overlay_object = hover_overlays_cache[choice]
if(!overlay_object)
overlay_object = new
overlay_object.icon_state = "[choice]"
hover_overlays_cache[choice] = overlay_object
vis_contents += overlay_object
/obj/effect/overlay/zone_sel
icon = 'icons/mob/zone_sel.dmi'
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
alpha = 128
anchored = TRUE
layer = LAYER_HUD_ABOVE
plane = PLANE_PLAYER_HUD_ABOVE
/obj/screen/zone_sel/MouseExited(location, control, params)
if(!isobserver(usr) && hovering_choice)
vis_contents -= hover_overlays_cache[hovering_choice]
hovering_choice = null
/obj/screen/zone_sel/proc/get_zone_at(icon_x, icon_y)
switch(icon_y) switch(icon_y)
if(1 to 3) //Feet if(1 to 3) //Feet
switch(icon_x) switch(icon_x)
if(10 to 15) if(10 to 15)
selecting = BP_R_FOOT return BP_R_FOOT
if(17 to 22) if(17 to 22)
selecting = BP_L_FOOT return BP_L_FOOT
else
return 1
if(4 to 9) //Legs if(4 to 9) //Legs
switch(icon_x) switch(icon_x)
if(10 to 15) if(10 to 15)
selecting = BP_R_LEG return BP_R_LEG
if(17 to 22) if(17 to 22)
selecting = BP_L_LEG return BP_L_LEG
else
return 1
if(10 to 13) //Hands and groin if(10 to 13) //Hands and groin
switch(icon_x) switch(icon_x)
if(8 to 11) if(8 to 11)
selecting = BP_R_HAND return BP_R_HAND
if(12 to 20) if(12 to 20)
selecting = BP_GROIN return BP_GROIN
if(21 to 24) if(21 to 24)
selecting = BP_L_HAND return BP_L_HAND
else
return 1
if(14 to 22) //Chest and arms to shoulders if(14 to 22) //Chest and arms to shoulders
switch(icon_x) switch(icon_x)
if(8 to 11) if(8 to 11)
selecting = BP_R_ARM return BP_R_ARM
if(12 to 20) if(12 to 20)
selecting = BP_TORSO return BP_TORSO
if(21 to 24) if(21 to 24)
selecting = BP_L_ARM return BP_L_ARM
else
return 1
if(23 to 30) //Head, but we need to check for eye or mouth if(23 to 30) //Head, but we need to check for eye or mouth
if(icon_x in 12 to 20) if(icon_x in 12 to 20)
selecting = BP_HEAD
switch(icon_y) switch(icon_y)
if(23 to 24) if(23 to 24)
if(icon_x in 15 to 17) if(icon_x in 15 to 17)
selecting = O_MOUTH return O_MOUTH
if(26) //Eyeline, eyes are on 15 and 17 if(26) //Eyeline, eyes are on 15 and 17
if(icon_x in 14 to 18) if(icon_x in 14 to 18)
selecting = O_EYES return O_EYES
if(25 to 27) if(25 to 27)
if(icon_x in 15 to 17) if(icon_x in 15 to 17)
selecting = O_EYES return O_EYES
return BP_HEAD
if(old_selecting != selecting) /obj/screen/zone_sel/proc/set_selected_zone(choice, mob/user)
update_icon() if(isobserver(user))
return 1 return
if(choice != selecting)
/obj/screen/zone_sel/proc/set_selected_zone(bodypart) selecting = choice
var/old_selecting = selecting
selecting = bodypart
if(old_selecting != selecting)
update_icon() update_icon()
/obj/screen/zone_sel/update_icon() /obj/screen/zone_sel/update_icon()
overlays.Cut() cut_overlay(selecting_appearance)
overlays += image('icons/mob/zone_sel.dmi', "[selecting]") selecting_appearance = mutable_appearance('icons/mob/zone_sel.dmi', "[selecting]")
add_overlay(selecting_appearance)
/obj/screen/Click(location, control, params) /obj/screen/Click(location, control, params)
if(!usr) return 1 if(!usr) return 1

View File

@@ -18,7 +18,7 @@
/obj/item/weapon/storage/internal/attack_hand() /obj/item/weapon/storage/internal/attack_hand()
return //make sure this is never picked up return //make sure this is never picked up
/obj/item/weapon/storage/internal/mob_can_equip() /obj/item/weapon/storage/internal/mob_can_equip(M as mob, slot, disable_warning = 0)
return 0 //make sure this is never picked up return 0 //make sure this is never picked up
//Helper procs to cleanly implement internal storages - storage items that provide inventory slots for other items. //Helper procs to cleanly implement internal storages - storage items that provide inventory slots for other items.

View File

@@ -59,7 +59,7 @@
user.recalculate_vis() user.recalculate_vis()
//BS12: Species-restricted clothing check. //BS12: Species-restricted clothing check.
/obj/item/clothing/mob_can_equip(M as mob, slot) /obj/item/clothing/mob_can_equip(M as mob, slot, disable_warning = 0)
//if we can't equip the item anyway, don't bother with species_restricted (cuts down on spam) //if we can't equip the item anyway, don't bother with species_restricted (cuts down on spam)
if (!..()) if (!..())

View File

@@ -7,7 +7,7 @@
w_class = ITEMSIZE_NORMAL w_class = ITEMSIZE_NORMAL
drop_sound = 'sound/items/drop/metalshield.ogg' drop_sound = 'sound/items/drop/metalshield.ogg'
/obj/item/clothing/gloves/arm_guard/mob_can_equip(var/mob/living/carbon/human/H, slot) /obj/item/clothing/gloves/arm_guard/mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0)
if(..()) //This will only run if no other problems occured when equiping. if(..()) //This will only run if no other problems occured when equiping.
if(H.wear_suit) if(H.wear_suit)
if(H.wear_suit.body_parts_covered & ARMS) if(H.wear_suit.body_parts_covered & ARMS)

View File

@@ -14,7 +14,7 @@
punch_force = 5 punch_force = 5
var/obj/item/clothing/gloves/gloves = null //Undergloves var/obj/item/clothing/gloves/gloves = null //Undergloves
/obj/item/clothing/gloves/gauntlets/mob_can_equip(mob/user) /obj/item/clothing/gloves/gauntlets/mob_can_equip(mob/user, slot, disable_warning = 0)
var/mob/living/carbon/human/H = user var/mob/living/carbon/human/H = user
if(H.gloves) if(H.gloves)
gloves = H.gloves gloves = H.gloves

View File

@@ -33,7 +33,7 @@
canremove = 1 canremove = 1
return ..() return ..()
/obj/item/clothing/mask/monitor/mob_can_equip(var/mob/living/carbon/human/user, var/slot) /obj/item/clothing/mask/monitor/mob_can_equip(var/mob/living/carbon/human/user, var/slot, disable_warning = FALSE)
if (!..()) if (!..())
return 0 return 0
if(istype(user)) if(istype(user))

View File

@@ -42,7 +42,7 @@
user.update_inv_shoes() //so our mob-overlays update user.update_inv_shoes() //so our mob-overlays update
user.update_action_buttons() user.update_action_buttons()
/obj/item/clothing/shoes/magboots/mob_can_equip(mob/user, slot) /obj/item/clothing/shoes/magboots/mob_can_equip(mob/user, slot, disable_warning = FALSE)
var/mob/living/carbon/human/H = user var/mob/living/carbon/human/H = user
if(H.shoes) if(H.shoes)

View File

@@ -520,7 +520,7 @@
|ACCESSORY_SLOT_ARMOR_M) |ACCESSORY_SLOT_ARMOR_M)
blood_overlay_type = "armor" blood_overlay_type = "armor"
/obj/item/clothing/suit/armor/pcarrier/mob_can_equip(var/mob/living/carbon/human/H, slot) /obj/item/clothing/suit/armor/pcarrier/mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = FALSE)
if(..()) //This will only run if no other problems occured when equiping. if(..()) //This will only run if no other problems occured when equiping.
if(H.gloves) if(H.gloves)
if(H.gloves.body_parts_covered & ARMS) if(H.gloves.body_parts_covered & ARMS)

View File

@@ -1887,7 +1887,7 @@ Departamental Swimsuits, for general use
species_restricted = list("exclude", SPECIES_TESHARI) species_restricted = list("exclude", SPECIES_TESHARI)
/obj/item/clothing/under/fluff/slime_skeleton/mob_can_equip(M as mob, slot) /obj/item/clothing/under/fluff/slime_skeleton/mob_can_equip(M as mob, slot, disable_warning = FALSE)
if(!..()) if(!..())
return 0 return 0