diff --git a/code/_onclick/hud/screen/screen_intent.dm b/code/_onclick/hud/screen/screen_intent.dm index ca75b836812..067a234fbd4 100644 --- a/code/_onclick/hud/screen/screen_intent.dm +++ b/code/_onclick/hud/screen/screen_intent.dm @@ -48,6 +48,19 @@ icon = intent.icon icon_state = selected ? intent.icon_state : "[intent.icon_state]_off" +/obj/screen/intent_button/MouseEntered(location, control, params) + if(intent && (intent.name || intent.desc)) + openToolTip(user = usr, tip_src = src, params = params, content = intent.desc) + return ..() + +/obj/screen/intent_button/MouseDown() + closeToolTip(usr) + return ..() + +/obj/screen/intent_button/MouseExited() + closeToolTip(usr) + return ..() + /obj/screen/intent name = "intent" icon = 'icons/screen/intents.dmi' @@ -98,20 +111,21 @@ var/decl/intent/owner_intent = owner.get_intent() var/i = 1 - var/list/all_intents = owner.get_available_intents() + var/list/unused_selectors = intent_selectors?.Copy() + var/list/all_intents = owner.get_available_intents(skip_update = TRUE) for(var/decl/intent/intent as anything in all_intents) var/obj/screen/intent_button/intent_button = get_intent_button(i) if(intent == owner_intent) intent_button.set_selected(intent) else intent_button.set_deselected(intent) + LAZYREMOVE(unused_selectors, intent_button) i++ apply_intent_button_offset(intent_button, i, length(all_intents)) add_vis_contents(intent_button) - if(i < length(intent_selectors)) - for(var/index = i+1 to length(intent_selectors)) - remove_vis_contents(intent_selectors[index]) + if(length(unused_selectors)) + remove_vis_contents(unused_selectors) /obj/screen/intent/binary intent_width = 32 diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index d4ba0cec66f..6b7a52844eb 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -1164,8 +1164,13 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out. /obj/item/proc/loadout_should_keep(obj/item/new_item, mob/wearer) return type != new_item.type && !replaced_in_loadout +/obj/item/dropped(mob/user, slot) + . = ..() + user?.clear_available_intents() + /obj/item/equipped(mob/user, slot) . = ..() + user?.clear_available_intents() // delay for 1ds to allow the rest of the call stack to resolve if(!QDELETED(src) && !QDELETED(user) && user.get_equipped_slot_for_item(src) == slot) try_burn_wearer(user, slot, 1) @@ -1296,3 +1301,6 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out. squash_item() if(!QDELETED(src)) physically_destroyed() + +/obj/item/proc/get_provided_intents(mob/wielder) + return null diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index f4482ab7e98..a963be6b2e4 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -466,7 +466,8 @@ return /mob/proc/select_held_item_slot(var/slot) - return + SHOULD_CALL_PARENT(TRUE) + clear_available_intents() /mob/proc/get_inventory_slots() return diff --git a/code/modules/mob/living/inventory.dm b/code/modules/mob/living/inventory.dm index f0ab7bdc92e..827d16090d0 100644 --- a/code/modules/mob/living/inventory.dm +++ b/code/modules/mob/living/inventory.dm @@ -58,6 +58,7 @@ queue_hand_rebuild() /mob/living/select_held_item_slot(var/slot) + . = ..() var/last_slot = get_active_held_item_slot() if(slot != last_slot && (slot in get_held_item_slots())) _held_item_slot_selected = slot diff --git a/code/modules/mob/mob_intent.dm b/code/modules/mob/mob_intent.dm index b55b2342ed8..1e28bd7df8d 100644 --- a/code/modules/mob/mob_intent.dm +++ b/code/modules/mob/mob_intent.dm @@ -35,6 +35,10 @@ var/icon = 'icons/screen/intents.dmi' /// State used to update intent selector. var/icon_state + /// Whether or not this intent is available if you have an item in your hand. + var/requires_empty_hand + /// Intents to be removed from the available list if this intent is present. + var/list/blocks_other_intents /decl/intent/validate() . = ..() @@ -83,20 +87,10 @@ icon_state = "intent_disarm" sort_order = 2 // Corresponding to hotkey order. -// Used by nymphs. -/decl/intent/harm/binary - icon = 'icons/screen/intents_wide.dmi' - uid = "intent_harm_simple" - intent_flags = (I_FLAG_HARM|I_FLAG_DISARM) - -/decl/intent/help/binary - icon = 'icons/screen/intents_wide.dmi' - uid = "intent_help_simple" - intent_flags = (I_FLAG_HARM|I_FLAG_GRAB) - /mob /// Decl for current 'intent' of mob; hurt, harm, etc. Initialized by get_intent(). - var/decl/intent/_a_intent + VAR_PRIVATE/decl/intent/_a_intent + VAR_PRIVATE/list/_available_intents /mob/proc/check_intent(checking_intent) var/decl/intent/intent = get_intent() // Ensures intent has been initalised. @@ -112,7 +106,7 @@ if(!isnum(new_intent)) new_intent = resolve_intent(new_intent) else // Retrieve intent decl based on flag. - for(var/decl/intent/intent as anything in get_available_intents()) + for(var/decl/intent/intent as anything in get_available_intents(skip_update = TRUE)) if(intent.intent_flags & new_intent) new_intent = intent break @@ -127,6 +121,15 @@ /mob/proc/get_intent() RETURN_TYPE(/decl/intent) + var/list/available_intents = get_available_intents() + if(length(available_intents) && (!_a_intent || !(_a_intent in available_intents))) + var/new_intent + if(_a_intent) + for(var/decl/intent/intent in available_intents) + if(_a_intent.intent_flags & intent.intent_flags) + new_intent = intent + break + _a_intent = new_intent || available_intents[1] if(!_a_intent) _a_intent = get_default_intent() return _a_intent @@ -134,25 +137,59 @@ /mob/proc/get_default_intent() return GET_DECL(/decl/intent/help) -/mob/proc/get_available_intents() - var/static/list/available_intents - if(!available_intents) - available_intents = list( +/mob/proc/get_default_intents() + var/static/list/default_intents + if(!default_intents) + default_intents = list( GET_DECL(/decl/intent/help), GET_DECL(/decl/intent/disarm), GET_DECL(/decl/intent/grab), GET_DECL(/decl/intent/harm) ) - available_intents = sortTim(available_intents, /proc/cmp_decl_sort_value_asc) - return available_intents + return default_intents + +/mob/proc/clear_available_intents(skip_update, skip_sleep) + set waitfor = FALSE + if(!skip_sleep) + sleep(0) + if(QDELETED(src)) + return + _available_intents = null + if(!skip_update && istype(hud_used) && hud_used.action_intent) + hud_used.action_intent.update_icon() + +/mob/proc/get_available_intents(skip_update, force) + var/obj/item/held = get_active_held_item() + if(!held) + _available_intents = get_default_intents() + else if(force || !_available_intents) + // Grab all relevant intents. + _available_intents = list() + for(var/decl/intent/intent as anything in get_default_intents()) + if(intent.requires_empty_hand) + continue + _available_intents += intent + // Add inhand intents. + var/list/held_intents = held.get_provided_intents(src) + if(length(held_intents)) + _available_intents |= held_intents + // Trim blocked intents. + for(var/decl/intent/intent as anything in _available_intents) + _available_intents -= intent.blocks_other_intents + // Sort by hotkey order. + _available_intents = sortTim(_available_intents, /proc/cmp_decl_sort_value_asc) + // Update our HUD immediately. + if(!skip_update && istype(hud_used) && hud_used.action_intent) + hud_used.action_intent.update_icon() + return _available_intents /mob/proc/cycle_intent(input) set name = "a-intent" set hidden = TRUE switch(input) if(INTENT_HOTKEY_RIGHT) - return set_intent(next_in_list(get_intent(), get_available_intents())) + return set_intent(next_in_list(get_intent(), get_available_intents(skip_update = TRUE))) if(INTENT_HOTKEY_LEFT) - return set_intent(previous_in_list(get_intent(), get_available_intents())) + return set_intent(previous_in_list(get_intent(), get_available_intents(skip_update = TRUE))) else // Fallback, should just use set_intent() directly return set_intent(input) diff --git a/mods/mobs/dionaea/mob/_nymph.dm b/mods/mobs/dionaea/mob/_nymph.dm index a1c8efe4486..9e6f68f30ba 100644 --- a/mods/mobs/dionaea/mob/_nymph.dm +++ b/mods/mobs/dionaea/mob/_nymph.dm @@ -76,18 +76,6 @@ heal_damage(OXY, rads, do_update_health = FALSE) heal_damage(TOX, rads) -/* -/mob/living/simple_animal/alien/diona/get_default_intent() - return GET_DECL(/decl/intent/help/binary/diona) - -/mob/living/simple_animal/alien/diona/get_available_intents() - var/static/list/available_intents = list( - GET_DECL(/decl/intent/harm/binary/diona), - GET_DECL(/decl/intent/help/binary/diona) - ) - return available_intents -*/ - /decl/bodytype/diona name = "nymph" bodytype_flag = 0 diff --git a/mods/mobs/dionaea/mob/nymph_ui.dm b/mods/mobs/dionaea/mob/nymph_ui.dm index fc44f7639a3..dca19d4b764 100644 --- a/mods/mobs/dionaea/mob/nymph_ui.dm +++ b/mods/mobs/dionaea/mob/nymph_ui.dm @@ -1,17 +1,3 @@ -/* Commented out due to issues with interactions and combined intent flags. -/obj/screen/intent/binary/diona - icon = 'mods/mobs/dionaea/icons/ui_intents.dmi' - screen_loc = DIONA_SCREEN_LOC_INTENT - -/decl/intent/harm/binary/diona - icon = 'mods/mobs/dionaea/icons/ui_intent_overlay.dmi' - uid = "intent_harm_binary_diona" - -/decl/intent/help/binary/diona - icon = 'mods/mobs/dionaea/icons/ui_intent_overlay.dmi' - uid = "intent_help_binary_diona" -*/ - /decl/ui_style/diona name = "Diona" restricted = TRUE diff --git a/mods/species/ascent/mobs/nymph/_nymph.dm b/mods/species/ascent/mobs/nymph/_nymph.dm index 16447b0c51d..da48aabf82e 100644 --- a/mods/species/ascent/mobs/nymph/_nymph.dm +++ b/mods/species/ascent/mobs/nymph/_nymph.dm @@ -51,15 +51,3 @@ /mob/living/simple_animal/alien/kharmaan/get_dexterity(var/silent) return (DEXTERITY_EQUIP_ITEM) - -/* -/mob/living/simple_animal/alien/kharmaan/get_default_intent() - return GET_DECL(/decl/intent/help/binary/ascent) - -/mob/living/simple_animal/alien/kharmaan/get_available_intents() - var/static/list/available_intents = list( - GET_DECL(/decl/intent/harm/binary/ascent), - GET_DECL(/decl/intent/help/binary/ascent) - ) - return available_intents -*/ \ No newline at end of file diff --git a/mods/species/ascent/mobs/nymph/nymph_ui.dm b/mods/species/ascent/mobs/nymph/nymph_ui.dm index e3b6d1ec70c..85fc14b3aff 100644 --- a/mods/species/ascent/mobs/nymph/nymph_ui.dm +++ b/mods/species/ascent/mobs/nymph/nymph_ui.dm @@ -1,16 +1,3 @@ -/* Commented out due to issues with interactions and combined intent flags. -/obj/screen/intent/binary/ascent - icon = 'mods/species/ascent/icons/ui_intents.dmi' - screen_loc = ANYMPH_SCREEN_LOC_INTENT - -/decl/intent/harm/binary/ascent - icon = 'mods/species/ascent/icons/ui_intent_overlay.dmi' - uid = "intent_harm_binary_ascent" - -/decl/intent/help/binary/ascent - icon = 'mods/species/ascent/icons/ui_intent_overlay.dmi' - uid = "intent_help_binary_ascent" -*/ /obj/screen/ascent_nymph_molt name = "molt" icon = 'mods/species/ascent/icons/ui_molt.dmi'