mirror of
https://github.com/Skyrat-SS13/Skyrat-tg.git
synced 2026-07-14 17:33:54 +01:00
bb70889f6e
3591 individual conflicts Update build.js Update install_node.sh Update byond.js oh my fucking god hat slow huh holy shit we all fall down 2 more I missed 2900 individual conflicts 2700 Individual conflicts replaces yarn file with tg version, bumping us down to 2200-ish Down to 2000 individual conflicts 140 down mmm aaaaaaaaaaaaaaaaaaa not yt 575 soon 900 individual conflicts 600 individual conflicts, 121 file conflicts im not okay 160 across 19 files 29 in 4 files 0 conflicts, compiletime fix time some minor incap stuff missed ticks weird dupe definition stuff missed ticks 2 incap fixes undefs and pie fix Radio update and some extra minor stuff returns a single override no more dupe definitions, 175 compiletime errors Unticked file fix sound and emote stuff honk and more radio stuff
552 lines
20 KiB
Plaintext
552 lines
20 KiB
Plaintext
/proc/make_link_visual_generic(datum/mod_link/mod_link, proc_path)
|
|
var/mob/living/user = mod_link.get_user_callback.Invoke()
|
|
var/obj/effect/overlay/link_visual = new()
|
|
link_visual.name = "holocall ([mod_link.id])"
|
|
link_visual.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
|
LAZYADD(mod_link.holder.update_on_z, link_visual)
|
|
link_visual.appearance_flags |= KEEP_TOGETHER
|
|
link_visual.makeHologram(0.75)
|
|
mod_link.visual_overlays = user.overlays - user.active_thinking_indicator
|
|
link_visual.add_overlay(mod_link.visual_overlays)
|
|
mod_link.visual = link_visual
|
|
mod_link.holder.become_hearing_sensitive(REF(mod_link))
|
|
mod_link.holder.RegisterSignals(user, list(COMSIG_CARBON_APPLY_OVERLAY, COMSIG_CARBON_REMOVE_OVERLAY), proc_path)
|
|
return link_visual
|
|
|
|
/proc/get_link_visual_generic(datum/mod_link/mod_link, atom/movable/visuals, proc_path)
|
|
var/mob/living/user = mod_link.get_user_callback.Invoke()
|
|
playsound(mod_link.holder, 'sound/machines/terminal_processing.ogg', 50, vary = TRUE)
|
|
visuals.add_overlay(mutable_appearance('icons/effects/effects.dmi', "static_base", ABOVE_NORMAL_TURF_LAYER))
|
|
visuals.add_overlay(mutable_appearance('icons/effects/effects.dmi', "modlink", ABOVE_ALL_MOB_LAYER))
|
|
visuals.add_filter("crop_square", 1, alpha_mask_filter(icon = icon('icons/effects/effects.dmi', "modlink_filter")))
|
|
visuals.maptext_height = 6
|
|
visuals.alpha = 0
|
|
user.vis_contents += visuals
|
|
visuals.forceMove(user)
|
|
animate(visuals, 0.5 SECONDS, alpha = 255)
|
|
var/datum/callback/setdir_callback = CALLBACK(mod_link.holder, proc_path)
|
|
setdir_callback.Invoke(user, user.dir, user.dir)
|
|
mod_link.holder.RegisterSignal(mod_link.holder.loc, COMSIG_ATOM_DIR_CHANGE, proc_path)
|
|
|
|
/proc/delete_link_visual_generic(datum/mod_link/mod_link)
|
|
var/mob/living/user = mod_link.get_user_callback.Invoke()
|
|
playsound(mod_link.get_other().holder, 'sound/machines/terminal_processing.ogg', 50, vary = TRUE, frequency = -1)
|
|
LAZYREMOVE(mod_link.holder.update_on_z, mod_link.visual)
|
|
mod_link.holder.lose_hearing_sensitivity(REF(mod_link))
|
|
mod_link.holder.UnregisterSignal(user, list(COMSIG_CARBON_APPLY_OVERLAY, COMSIG_CARBON_REMOVE_OVERLAY, COMSIG_ATOM_DIR_CHANGE))
|
|
QDEL_NULL(mod_link.visual)
|
|
|
|
/proc/on_user_set_dir_generic(datum/mod_link/mod_link, newdir)
|
|
var/atom/other_visual = mod_link.get_other().visual
|
|
if(!newdir) //can sometimes be null or 0
|
|
return
|
|
other_visual.setDir(SOUTH)
|
|
other_visual.pixel_x = 0
|
|
other_visual.pixel_y = 0
|
|
var/matrix/new_transform = matrix()
|
|
if(newdir & NORTH)
|
|
other_visual.pixel_y = 13
|
|
other_visual.layer = BELOW_MOB_LAYER
|
|
if(newdir & SOUTH)
|
|
other_visual.pixel_y = -24
|
|
other_visual.layer = ABOVE_ALL_MOB_LAYER
|
|
new_transform.Scale(-1, 1)
|
|
new_transform.Translate(-1, 0)
|
|
if(newdir & EAST)
|
|
other_visual.pixel_x = 14
|
|
other_visual.layer = BELOW_MOB_LAYER
|
|
new_transform.Shear(0.5, 0)
|
|
new_transform.Scale(0.65, 1)
|
|
if(newdir & WEST)
|
|
other_visual.pixel_x = -14
|
|
other_visual.layer = BELOW_MOB_LAYER
|
|
new_transform.Shear(-0.5, 0)
|
|
new_transform.Scale(0.65, 1)
|
|
other_visual.transform = new_transform
|
|
|
|
/obj/item/mod/control/Initialize(mapload, datum/mod_theme/new_theme, new_skin, obj/item/mod/core/new_core)
|
|
. = ..()
|
|
mod_link = new(
|
|
src,
|
|
starting_frequency,
|
|
CALLBACK(src, PROC_REF(get_wearer)),
|
|
CALLBACK(src, PROC_REF(can_call)),
|
|
CALLBACK(src, PROC_REF(make_link_visual)),
|
|
CALLBACK(src, PROC_REF(get_link_visual)),
|
|
CALLBACK(src, PROC_REF(delete_link_visual))
|
|
)
|
|
|
|
/obj/item/mod/control/multitool_act_secondary(mob/living/user, obj/item/multitool/tool)
|
|
. = NONE
|
|
|
|
var/tool_frequency = null
|
|
if(istype(tool.buffer, /datum/mod_link))
|
|
var/datum/mod_link/buffer_link = tool.buffer
|
|
tool_frequency = buffer_link.frequency
|
|
balloon_alert(user, "frequency set")
|
|
. = ITEM_INTERACT_SUCCESS
|
|
if(!tool_frequency && mod_link.frequency)
|
|
tool.set_buffer(mod_link)
|
|
balloon_alert(user, "frequency copied")
|
|
. = ITEM_INTERACT_SUCCESS
|
|
else if(tool_frequency && !mod_link.frequency)
|
|
mod_link.frequency = tool_frequency
|
|
. = ITEM_INTERACT_SUCCESS
|
|
else if(tool_frequency && mod_link.frequency)
|
|
var/response = tgui_alert(user, "Would you like to copy or imprint the frequency?", "MODlink Frequency", list("Copy", "Imprint"))
|
|
if(!user.is_holding(tool))
|
|
return ITEM_INTERACT_BLOCKING
|
|
switch(response)
|
|
if("Copy")
|
|
tool.set_buffer(mod_link)
|
|
balloon_alert(user, "frequency copied")
|
|
. = ITEM_INTERACT_SUCCESS
|
|
if("Imprint")
|
|
mod_link.frequency = tool_frequency
|
|
balloon_alert(user, "frequency set")
|
|
. = ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/item/mod/control/proc/can_call()
|
|
return get_charge() && wearer && wearer.stat < DEAD
|
|
|
|
/obj/item/mod/control/proc/make_link_visual()
|
|
return make_link_visual_generic(mod_link, PROC_REF(on_overlay_change))
|
|
|
|
/obj/item/mod/control/proc/get_link_visual(atom/movable/visuals)
|
|
return get_link_visual_generic(mod_link, visuals, PROC_REF(on_wearer_set_dir))
|
|
|
|
/obj/item/mod/control/proc/delete_link_visual()
|
|
return delete_link_visual_generic(mod_link)
|
|
|
|
/obj/item/mod/control/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods, message_range)
|
|
. = ..()
|
|
if(speaker != wearer && speaker != ai_assistant)
|
|
return
|
|
mod_link.visual.say(raw_message, sanitize = FALSE, message_range = 2)
|
|
|
|
/obj/item/mod/control/proc/on_overlay_change(atom/source, cache_index, overlay)
|
|
SIGNAL_HANDLER
|
|
addtimer(CALLBACK(src, PROC_REF(update_link_visual)), 1 TICKS, TIMER_UNIQUE)
|
|
|
|
/obj/item/mod/control/proc/update_link_visual()
|
|
if(QDELETED(mod_link.link_call))
|
|
return
|
|
mod_link.visual.cut_overlay(mod_link.visual_overlays)
|
|
mod_link.visual_overlays = wearer.overlays - wearer.active_thinking_indicator
|
|
mod_link.visual.add_overlay(mod_link.visual_overlays)
|
|
|
|
/obj/item/mod/control/proc/on_wearer_set_dir(atom/source, dir, newdir)
|
|
SIGNAL_HANDLER
|
|
on_user_set_dir_generic(mod_link, newdir || SOUTH)
|
|
|
|
/obj/item/clothing/neck/link_scryer
|
|
name = "\improper MODlink scryer"
|
|
desc = "An intricate piece of machinery that creates a holographic video call with another MODlink-compatible device. Essentially a video necklace."
|
|
icon_state = "modlink"
|
|
actions_types = list(/datum/action/item_action/call_link)
|
|
/// The installed power cell.
|
|
var/obj/item/stock_parts/power_store/cell
|
|
/// The MODlink datum we operate.
|
|
var/datum/mod_link/mod_link
|
|
/// Initial frequency of the MODlink.
|
|
var/starting_frequency
|
|
/// An additional name tag for the scryer, seen as "MODlink scryer - [label]"
|
|
var/label
|
|
|
|
/obj/item/clothing/neck/link_scryer/Initialize(mapload)
|
|
. = ..()
|
|
mod_link = new(
|
|
src,
|
|
starting_frequency,
|
|
CALLBACK(src, PROC_REF(get_user)),
|
|
CALLBACK(src, PROC_REF(can_call)),
|
|
CALLBACK(src, PROC_REF(make_link_visual)),
|
|
CALLBACK(src, PROC_REF(get_link_visual)),
|
|
CALLBACK(src, PROC_REF(delete_link_visual))
|
|
)
|
|
START_PROCESSING(SSobj, src)
|
|
|
|
/obj/item/clothing/neck/link_scryer/Destroy()
|
|
QDEL_NULL(cell)
|
|
QDEL_NULL(mod_link)
|
|
STOP_PROCESSING(SSobj, src)
|
|
return ..()
|
|
|
|
/obj/item/clothing/neck/link_scryer/examine(mob/user)
|
|
. = ..()
|
|
// SKYRAT EDIT NIFSOFT SCRYERS - START
|
|
if(custom_examine_controls)
|
|
return
|
|
// SKYRAT EDIT NIFSOFT SCRYERS - END
|
|
if(cell)
|
|
. += span_notice("The battery charge reads [cell.percent()]%. <b>Right-click</b> with an empty hand to remove it.")
|
|
else
|
|
. += span_notice("It is missing a battery, one can be installed by clicking with a power cell on it.")
|
|
. += span_notice("The MODlink ID is [mod_link.id], frequency is [mod_link.frequency || "unset"]. <b>Right-click</b> with multitool to copy/imprint frequency.")
|
|
. += span_notice("Use in hand to set name.")
|
|
|
|
/obj/item/clothing/neck/link_scryer/equipped(mob/living/user, slot)
|
|
. = ..()
|
|
if(slot != ITEM_SLOT_NECK)
|
|
mod_link?.end_call()
|
|
|
|
/obj/item/clothing/neck/link_scryer/dropped(mob/living/user)
|
|
. = ..()
|
|
mod_link?.end_call()
|
|
|
|
/obj/item/clothing/neck/link_scryer/attack_self(mob/user, modifiers)
|
|
var/new_label = reject_bad_text(tgui_input_text(user, "Change the visible name", "Set Name", label, MAX_NAME_LEN))
|
|
if(!user.is_holding(src))
|
|
return
|
|
if(!new_label)
|
|
balloon_alert(user, "invalid name!")
|
|
return
|
|
label = new_label
|
|
balloon_alert(user, "name set")
|
|
update_name()
|
|
|
|
/obj/item/clothing/neck/link_scryer/process(seconds_per_tick)
|
|
if(!mod_link.link_call)
|
|
return
|
|
cell.use(0.02 * STANDARD_CELL_RATE * seconds_per_tick, force = TRUE)
|
|
|
|
/obj/item/clothing/neck/link_scryer/attackby(obj/item/attacked_by, mob/user, params)
|
|
. = ..()
|
|
if(cell || !istype(attacked_by, /obj/item/stock_parts/power_store/cell))
|
|
return
|
|
if(!user.transferItemToLoc(attacked_by, src))
|
|
return
|
|
cell = attacked_by
|
|
balloon_alert(user, "installed [cell.name]")
|
|
|
|
/obj/item/clothing/neck/link_scryer/update_name(updates)
|
|
. = ..()
|
|
name = "[initial(name)][label ? " - [label]" : ""]"
|
|
|
|
/obj/item/clothing/neck/link_scryer/Exited(atom/movable/gone, direction)
|
|
. = ..()
|
|
if(gone == cell)
|
|
cell = null
|
|
|
|
/obj/item/clothing/neck/link_scryer/attack_hand_secondary(mob/user, list/modifiers)
|
|
if(!cell)
|
|
return SECONDARY_ATTACK_CONTINUE_CHAIN
|
|
balloon_alert(user, "removed [cell.name]")
|
|
user.put_in_hands(cell)
|
|
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
|
|
|
/obj/item/clothing/neck/link_scryer/multitool_act_secondary(mob/living/user, obj/item/multitool/tool)
|
|
. = NONE
|
|
|
|
var/tool_frequency = null
|
|
if(istype(tool.buffer, /datum/mod_link))
|
|
var/datum/mod_link/buffer_link = tool.buffer
|
|
tool_frequency = buffer_link.frequency
|
|
balloon_alert(user, "frequency set")
|
|
. = ITEM_INTERACT_SUCCESS
|
|
if(!tool_frequency && mod_link.frequency)
|
|
tool.set_buffer(mod_link)
|
|
balloon_alert(user, "frequency copied")
|
|
. = ITEM_INTERACT_SUCCESS
|
|
else if(tool_frequency && !mod_link.frequency)
|
|
mod_link.frequency = tool_frequency
|
|
. = ITEM_INTERACT_SUCCESS
|
|
else if(tool_frequency && mod_link.frequency)
|
|
var/response = tgui_alert(user, "Would you like to copy or imprint the frequency?", "MODlink Frequency", list("Copy", "Imprint"))
|
|
if(!user.is_holding(tool))
|
|
return ITEM_INTERACT_BLOCKING
|
|
switch(response)
|
|
if("Copy")
|
|
tool.set_buffer(mod_link)
|
|
balloon_alert(user, "frequency copied")
|
|
. = ITEM_INTERACT_SUCCESS
|
|
if("Imprint")
|
|
mod_link.frequency = tool_frequency
|
|
balloon_alert(user, "frequency set")
|
|
. = ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/item/clothing/neck/link_scryer/worn_overlays(mutable_appearance/standing, isinhands)
|
|
. = ..()
|
|
if(!QDELETED(mod_link.link_call))
|
|
. += mutable_appearance('icons/mob/clothing/neck.dmi', "modlink_active")
|
|
|
|
/obj/item/clothing/neck/link_scryer/ui_action_click(mob/user)
|
|
if(mod_link.link_call)
|
|
mod_link.end_call()
|
|
else
|
|
call_link(user, mod_link)
|
|
|
|
/obj/item/clothing/neck/link_scryer/proc/get_user()
|
|
var/mob/living/carbon/user = loc
|
|
return istype(user) && user.wear_neck == src ? user : null
|
|
|
|
/obj/item/clothing/neck/link_scryer/proc/can_call()
|
|
var/mob/living/user = loc
|
|
return istype(user) && cell?.charge && user.stat < DEAD
|
|
|
|
/obj/item/clothing/neck/link_scryer/proc/make_link_visual()
|
|
var/mob/living/user = mod_link.get_user_callback.Invoke()
|
|
user.update_worn_neck()
|
|
return make_link_visual_generic(mod_link, PROC_REF(on_overlay_change))
|
|
|
|
/obj/item/clothing/neck/link_scryer/proc/get_link_visual(atom/movable/visuals)
|
|
return get_link_visual_generic(mod_link, visuals, PROC_REF(on_user_set_dir))
|
|
|
|
/obj/item/clothing/neck/link_scryer/proc/delete_link_visual()
|
|
var/mob/living/user = mod_link.get_user_callback.Invoke()
|
|
if(!QDELETED(user))
|
|
user.update_worn_neck()
|
|
return delete_link_visual_generic(mod_link)
|
|
|
|
/obj/item/clothing/neck/link_scryer/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods, message_range)
|
|
. = ..()
|
|
if(speaker != loc)
|
|
return
|
|
mod_link.visual.say(raw_message, sanitize = FALSE, message_range = 3)
|
|
|
|
/obj/item/clothing/neck/link_scryer/proc/on_overlay_change(atom/source, cache_index, overlay)
|
|
SIGNAL_HANDLER
|
|
addtimer(CALLBACK(src, PROC_REF(update_link_visual)), 1 TICKS, TIMER_UNIQUE)
|
|
|
|
/obj/item/clothing/neck/link_scryer/proc/update_link_visual()
|
|
if(QDELETED(mod_link.link_call))
|
|
return
|
|
var/mob/living/user = loc
|
|
mod_link.visual.cut_overlay(mod_link.visual_overlays)
|
|
mod_link.visual_overlays = user.overlays - user.active_thinking_indicator
|
|
mod_link.visual.add_overlay(mod_link.visual_overlays)
|
|
|
|
/obj/item/clothing/neck/link_scryer/proc/on_user_set_dir(atom/source, dir, newdir)
|
|
SIGNAL_HANDLER
|
|
on_user_set_dir_generic(mod_link, newdir || SOUTH)
|
|
|
|
/obj/item/clothing/neck/link_scryer/loaded
|
|
starting_frequency = "NT"
|
|
|
|
/obj/item/clothing/neck/link_scryer/loaded/Initialize(mapload)
|
|
. = ..()
|
|
cell = new /obj/item/stock_parts/power_store/cell/high(src)
|
|
|
|
/obj/item/clothing/neck/link_scryer/loaded/charlie
|
|
starting_frequency = MODLINK_FREQ_CHARLIE
|
|
|
|
/// A MODlink datum, used to handle unique functions that will be used in the MODlink call.
|
|
/datum/mod_link
|
|
/// Generic name for multitool buffers.
|
|
var/name = "MODlink"
|
|
/// The frequency of the MODlink. You can only call other MODlinks on the same frequency.
|
|
var/frequency
|
|
/// The unique ID of the MODlink.
|
|
var/id = ""
|
|
/// The atom that holds the MODlink.
|
|
var/atom/movable/holder
|
|
/// A reference to the visuals generated by the MODlink.
|
|
var/atom/movable/visual
|
|
/// A list of all overlays of the user, copied everytime they have an overlay change.
|
|
var/list/visual_overlays = list()
|
|
/// A reference to the call between two MODlinks.
|
|
var/datum/mod_link_call/link_call
|
|
/// A callback that returns the user of the MODlink.
|
|
var/datum/callback/get_user_callback
|
|
/// A callback that returns whether the MODlink can currently call.
|
|
var/datum/callback/can_call_callback
|
|
/// A callback that returns the visuals of the MODlink.
|
|
var/datum/callback/make_visual_callback
|
|
/// A callback that receives the visuals of the other MODlink.
|
|
var/datum/callback/get_visual_callback
|
|
/// A callback that deletes the visuals of the MODlink.
|
|
var/datum/callback/delete_visual_callback
|
|
|
|
/datum/mod_link/New(
|
|
atom/holder,
|
|
frequency,
|
|
datum/callback/get_user_callback,
|
|
datum/callback/can_call_callback,
|
|
datum/callback/make_visual_callback,
|
|
datum/callback/get_visual_callback,
|
|
datum/callback/delete_visual_callback
|
|
)
|
|
var/attempts = 0
|
|
var/digits_to_make = 3
|
|
do
|
|
if(attempts == 10)
|
|
attempts = 0
|
|
digits_to_make++
|
|
id = ""
|
|
for(var/i in 1 to digits_to_make)
|
|
id += num2text(rand(0,9))
|
|
attempts++
|
|
while(GLOB.mod_link_ids[id])
|
|
GLOB.mod_link_ids[id] = src
|
|
src.frequency = frequency
|
|
src.holder = holder
|
|
src.get_user_callback = get_user_callback
|
|
src.can_call_callback = can_call_callback
|
|
src.make_visual_callback = make_visual_callback
|
|
src.get_visual_callback = get_visual_callback
|
|
src.delete_visual_callback = delete_visual_callback
|
|
RegisterSignal(holder, COMSIG_QDELETING, PROC_REF(on_holder_delete))
|
|
|
|
/datum/mod_link/Destroy()
|
|
GLOB.mod_link_ids -= id
|
|
if(link_call)
|
|
end_call()
|
|
get_user_callback = null
|
|
make_visual_callback = null
|
|
get_visual_callback = null
|
|
delete_visual_callback = null
|
|
return ..()
|
|
|
|
/datum/mod_link/proc/get_other()
|
|
RETURN_TYPE(/datum/mod_link)
|
|
if(!link_call)
|
|
return
|
|
return link_call.caller == src ? link_call.receiver : link_call.caller
|
|
|
|
/datum/mod_link/proc/call_link(datum/mod_link/called, mob/user)
|
|
if(!frequency)
|
|
return
|
|
if(!istype(called))
|
|
holder.balloon_alert(user, "invalid target!")
|
|
return
|
|
var/mob/living/link_user = get_user_callback.Invoke()
|
|
if(!link_user)
|
|
return
|
|
if(HAS_TRAIT(link_user, TRAIT_IN_CALL))
|
|
holder.balloon_alert(user, "user already in call!")
|
|
return
|
|
var/mob/living/link_target = called.get_user_callback.Invoke()
|
|
if(!link_target)
|
|
holder.balloon_alert(user, "invalid target!")
|
|
return
|
|
if(HAS_TRAIT(link_target, TRAIT_IN_CALL))
|
|
holder.balloon_alert(user, "target already in call!")
|
|
return
|
|
if(!can_call_callback.Invoke() || !called.can_call_callback.Invoke())
|
|
holder.balloon_alert(user, "can't call!")
|
|
return
|
|
link_target.playsound_local(get_turf(called.holder), 'sound/weapons/ring.ogg', 15, vary = TRUE)
|
|
var/atom/movable/screen/alert/modlink_call/alert = link_target.throw_alert("[REF(src)]_modlink", /atom/movable/screen/alert/modlink_call)
|
|
alert.desc = "[holder] ([id]) is calling you! Left-click this to accept the call. Right-click to deny it."
|
|
alert.caller_ref = WEAKREF(src)
|
|
alert.receiver_ref = WEAKREF(called)
|
|
alert.user_ref = WEAKREF(user)
|
|
|
|
/datum/mod_link/proc/end_call()
|
|
QDEL_NULL(link_call)
|
|
|
|
/datum/mod_link/proc/on_holder_delete(atom/source)
|
|
SIGNAL_HANDLER
|
|
qdel(src)
|
|
|
|
/// A MODlink call datum, used to handle the call between two MODlinks.
|
|
/datum/mod_link_call
|
|
/// The MODlink that is calling.
|
|
var/datum/mod_link/caller
|
|
/// The MODlink that is being called.
|
|
var/datum/mod_link/receiver
|
|
|
|
/datum/mod_link_call/New(datum/mod_link/caller, datum/mod_link/receiver)
|
|
caller.link_call = src
|
|
receiver.link_call = src
|
|
src.caller = caller
|
|
src.receiver = receiver
|
|
var/mob/living/caller_mob = caller.get_user_callback.Invoke()
|
|
ADD_TRAIT(caller_mob, TRAIT_IN_CALL, REF(src))
|
|
var/mob/living/receiver_mob = receiver.get_user_callback.Invoke()
|
|
ADD_TRAIT(receiver_mob, TRAIT_IN_CALL, REF(src))
|
|
make_visuals()
|
|
START_PROCESSING(SSprocessing, src)
|
|
|
|
/datum/mod_link_call/Destroy()
|
|
var/mob/living/caller_mob = caller.get_user_callback.Invoke()
|
|
if(!QDELETED(caller_mob))
|
|
REMOVE_TRAIT(caller_mob, TRAIT_IN_CALL, REF(src))
|
|
var/mob/living/receiver_mob = receiver.get_user_callback.Invoke()
|
|
if(!QDELETED(receiver_mob))
|
|
REMOVE_TRAIT(receiver_mob, TRAIT_IN_CALL, REF(src))
|
|
STOP_PROCESSING(SSprocessing, src)
|
|
clear_visuals()
|
|
caller.link_call = null
|
|
receiver.link_call = null
|
|
return ..()
|
|
|
|
/datum/mod_link_call/process(seconds_per_tick)
|
|
if(can_continue_call())
|
|
return
|
|
qdel(src)
|
|
|
|
/datum/mod_link_call/proc/can_continue_call()
|
|
return caller.frequency == receiver.frequency && caller.can_call_callback.Invoke() && receiver.can_call_callback.Invoke()
|
|
|
|
/datum/mod_link_call/proc/make_visuals()
|
|
var/caller_visual = caller.make_visual_callback.Invoke()
|
|
var/receiver_visual = receiver.make_visual_callback.Invoke()
|
|
caller.get_visual_callback.Invoke(receiver_visual)
|
|
receiver.get_visual_callback.Invoke(caller_visual)
|
|
|
|
/datum/mod_link_call/proc/clear_visuals()
|
|
caller.delete_visual_callback.Invoke()
|
|
receiver.delete_visual_callback.Invoke()
|
|
|
|
/proc/call_link(mob/user, datum/mod_link/calling_link)
|
|
if(!calling_link.frequency)
|
|
return
|
|
var/list/callers = list()
|
|
for(var/id in GLOB.mod_link_ids)
|
|
var/datum/mod_link/link = GLOB.mod_link_ids[id]
|
|
if(link.frequency != calling_link.frequency)
|
|
continue
|
|
if(link == calling_link)
|
|
continue
|
|
if(!link.can_call_callback.Invoke())
|
|
continue
|
|
callers["[link.holder] ([id])"] = id
|
|
if(!length(callers))
|
|
calling_link.holder.balloon_alert(user, "no targets on freq [calling_link.frequency]!")
|
|
return
|
|
var/chosen_link = tgui_input_list(user, "Choose ID to call from [calling_link.frequency] frequency", "MODlink", callers)
|
|
if(!chosen_link)
|
|
return
|
|
calling_link.call_link(GLOB.mod_link_ids[callers[chosen_link]], user)
|
|
|
|
/atom/movable/screen/alert/modlink_call
|
|
name = "MODlink Call Incoming"
|
|
desc = "Someone is calling you! Left-click this to accept the call. Right-click to deny it."
|
|
icon_state = "called"
|
|
timeout = 10 SECONDS
|
|
var/end_message = "call timed out!"
|
|
/// A weak reference to the MODlink that is calling.
|
|
var/datum/weakref/caller_ref
|
|
/// A weak reference to the MODlink that is being called.
|
|
var/datum/weakref/receiver_ref
|
|
/// A weak reference to the mob that is calling.
|
|
var/datum/weakref/user_ref
|
|
|
|
/atom/movable/screen/alert/modlink_call/Click(location, control, params)
|
|
. = ..()
|
|
if(usr != owner)
|
|
return
|
|
var/datum/mod_link/caller = caller_ref.resolve()
|
|
var/datum/mod_link/receiver = receiver_ref.resolve()
|
|
if(!caller || !receiver)
|
|
return
|
|
if(caller.link_call || receiver.link_call)
|
|
return
|
|
var/list/modifiers = params2list(params)
|
|
if(LAZYACCESS(modifiers, RIGHT_CLICK))
|
|
end_message = "call denied!"
|
|
owner.clear_alert("[REF(caller)]_modlink")
|
|
return
|
|
end_message = "call accepted"
|
|
new /datum/mod_link_call(caller, receiver)
|
|
owner.clear_alert("[REF(caller)]_modlink")
|
|
|
|
/atom/movable/screen/alert/modlink_call/Destroy()
|
|
var/mob/living/user = user_ref?.resolve()
|
|
var/datum/mod_link/caller = caller_ref?.resolve()
|
|
if(!user || !caller)
|
|
return ..()
|
|
caller.holder.balloon_alert(user, end_message)
|
|
return ..()
|