mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 17:52:36 +00:00
## About The Pull Request Fixes https://github.com/tgstation/tgstation/issues/90931 ## Why It's Good For The Game Can't callout while incapacitated (dead, stunned, etc.). While cuffed reverts to proper "leg" pointing. ## Changelog 🆑 fix: callouts no longer work while you are incapacitated /🆑
184 lines
5.7 KiB
Plaintext
184 lines
5.7 KiB
Plaintext
#define CALLOUT_TIME (5 SECONDS)
|
|
#define CALLOUT_COOLDOWN 3 SECONDS
|
|
|
|
/// Component that allows its owner/owner's wearer to use callouts system - their pointing is replaced with a fancy radial which allows them to summon glowing markers
|
|
/datum/component/callouts
|
|
/// If parent is clothing, slot on which this component activates
|
|
var/item_slot
|
|
/// If we are currently active
|
|
var/active = TRUE
|
|
/// Current user of this component
|
|
var/mob/cur_user
|
|
/// Whenever the user should shout the voiceline
|
|
var/voiceline = FALSE
|
|
/// If voiceline is true, what prefix the user should use
|
|
var/radio_prefix = null
|
|
/// List of all callout options
|
|
var/static/list/callout_options = typecacheof(subtypesof(/datum/callout_option))
|
|
/// Text displayed when parent is examined
|
|
var/examine_text = null
|
|
/// Cooldown for callouts
|
|
COOLDOWN_DECLARE(callout_cooldown)
|
|
|
|
/datum/component/callouts/Initialize(item_slot = null, voiceline = FALSE, radio_prefix = null, examine_text = null)
|
|
if (!isitem(parent) && !ismob(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
src.item_slot = item_slot
|
|
src.voiceline = voiceline
|
|
src.radio_prefix = radio_prefix
|
|
src.examine_text = examine_text
|
|
|
|
if (ismob(parent))
|
|
cur_user = parent
|
|
return
|
|
|
|
var/atom/atom_parent = parent
|
|
|
|
if (!ismob(atom_parent.loc))
|
|
return
|
|
|
|
var/mob/user = atom_parent.loc
|
|
if (!isnull(item_slot) && user.get_item_by_slot(item_slot) != parent)
|
|
return
|
|
|
|
RegisterSignal(atom_parent.loc, COMSIG_MOB_CLICKON, PROC_REF(on_click))
|
|
cur_user = atom_parent.loc
|
|
|
|
/datum/component/callouts/Destroy(force)
|
|
cur_user = null
|
|
. = ..()
|
|
|
|
/datum/component/callouts/RegisterWithParent()
|
|
RegisterSignal(parent, COMSIG_MOB_CLICKON, PROC_REF(on_click))
|
|
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equipped))
|
|
RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(on_dropped))
|
|
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examines))
|
|
RegisterSignal(parent, COMSIG_CLICK_CTRL, PROC_REF(on_ctrl_click))
|
|
|
|
/datum/component/callouts/UnregisterFromParent()
|
|
UnregisterSignal(parent, list(COMSIG_MOB_CLICKON, COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED, COMSIG_ATOM_EXAMINE, COMSIG_CLICK_CTRL))
|
|
|
|
/datum/component/callouts/proc/on_ctrl_click(datum/source, mob/living/user)
|
|
SIGNAL_HANDLER
|
|
|
|
if (!isitem(parent))
|
|
return
|
|
|
|
if (user.incapacitated)
|
|
return
|
|
|
|
var/obj/item/item_parent = parent
|
|
active = !active
|
|
item_parent.balloon_alert(user, active ? "callouts enabled" : "callouts disabled")
|
|
|
|
/datum/component/callouts/proc/on_equipped(datum/source, mob/equipper, slot)
|
|
SIGNAL_HANDLER
|
|
|
|
if (item_slot & slot)
|
|
RegisterSignal(equipper, COMSIG_MOB_CLICKON, PROC_REF(on_click))
|
|
cur_user = equipper
|
|
else if (cur_user == equipper)
|
|
UnregisterSignal(cur_user, COMSIG_MOB_CLICKON, PROC_REF(on_click))
|
|
cur_user = null
|
|
|
|
/datum/component/callouts/proc/on_dropped(datum/source, mob/user)
|
|
SIGNAL_HANDLER
|
|
|
|
if (cur_user == user)
|
|
UnregisterSignal(cur_user, COMSIG_MOB_CLICKON, PROC_REF(on_click))
|
|
cur_user = null
|
|
|
|
/datum/component/callouts/proc/on_examines(mob/source, mob/user, list/examine_list)
|
|
SIGNAL_HANDLER
|
|
if (!isnull(examine_text))
|
|
examine_list += examine_text
|
|
|
|
/datum/component/callouts/proc/on_click(mob/user, atom/clicked_atom, list/modifiers)
|
|
SIGNAL_HANDLER
|
|
|
|
if (!LAZYACCESS(modifiers, SHIFT_CLICK) || !LAZYACCESS(modifiers, MIDDLE_CLICK))
|
|
return
|
|
|
|
if (user.incapacitated)
|
|
return
|
|
|
|
if (!active)
|
|
return
|
|
|
|
if (!COOLDOWN_FINISHED(src, callout_cooldown))
|
|
clicked_atom.balloon_alert(user, "callout is on cooldown!")
|
|
return COMSIG_MOB_CANCEL_CLICKON
|
|
|
|
INVOKE_ASYNC(src, PROC_REF(callout_picker), user, clicked_atom)
|
|
return COMSIG_MOB_CANCEL_CLICKON
|
|
|
|
/datum/component/callouts/proc/callout_picker(mob/user, atom/clicked_atom)
|
|
var/list/callout_items = list()
|
|
for(var/datum/callout_option/callout_option as anything in callout_options)
|
|
callout_items[callout_option] = image(icon = 'icons/hud/radial.dmi', icon_state = callout_option::icon_state)
|
|
|
|
var/datum/callout_option/selection = show_radial_menu(user, get_turf(clicked_atom), callout_items, button_animation_flags = NONE, click_on_hover = TRUE, user_space = TRUE)
|
|
if (!selection)
|
|
return
|
|
|
|
COOLDOWN_START(src, callout_cooldown, CALLOUT_COOLDOWN)
|
|
new /obj/effect/temp_visual/callout(get_turf(user), user, selection, clicked_atom)
|
|
SEND_SIGNAL(user, COMSIG_MOB_CREATED_CALLOUT, selection, clicked_atom)
|
|
if (voiceline)
|
|
user.say((!isnull(radio_prefix) ? radio_prefix : "") + selection::voiceline, forced = src)
|
|
|
|
/obj/effect/temp_visual/callout
|
|
name = "callout"
|
|
icon = 'icons/effects/callouts.dmi'
|
|
icon_state = "point"
|
|
plane = ABOVE_LIGHTING_PLANE
|
|
duration = CALLOUT_TIME
|
|
|
|
/obj/effect/temp_visual/callout/Initialize(mapload, mob/creator, datum/callout_option/callout, atom/target)
|
|
. = ..()
|
|
if (isnull(creator))
|
|
return
|
|
icon_state = callout::icon_state
|
|
color = colorize_string(creator.GetVoice(), 2, 0.9)
|
|
update_appearance()
|
|
var/turf/target_loc = get_turf(target)
|
|
animate(src, pixel_x = (target_loc.x - loc.x) * ICON_SIZE_X + target.pixel_x, pixel_y = (target_loc.y - loc.y) * ICON_SIZE_Y + target.pixel_y, time = 0.2 SECONDS, easing = EASE_OUT)
|
|
|
|
/datum/callout_option
|
|
var/name = "ERROR"
|
|
var/icon_state = "point"
|
|
var/voiceline = "Something has gone wrong!"
|
|
|
|
/datum/callout_option/point
|
|
name = "Point"
|
|
icon_state = "point"
|
|
voiceline = "Here!"
|
|
|
|
/datum/callout_option/danger
|
|
name = "Danger"
|
|
icon_state = "danger"
|
|
voiceline = "Danger there!"
|
|
|
|
/datum/callout_option/guard
|
|
name = "Guard"
|
|
icon_state = "guard"
|
|
voiceline = "Hold this position!"
|
|
|
|
/datum/callout_option/attack
|
|
name = "Attack"
|
|
icon_state = "attack"
|
|
voiceline = "Attack there!"
|
|
|
|
/datum/callout_option/mine
|
|
name = "Mine"
|
|
icon_state = "mine"
|
|
voiceline = "Dig here!"
|
|
|
|
/datum/callout_option/move
|
|
name = "Move"
|
|
icon_state = "move"
|
|
voiceline = "Reposition there!"
|
|
|
|
#undef CALLOUT_TIME
|
|
#undef CALLOUT_COOLDOWN
|