From f113ff44acbe78b1a5c8c716de6923526c6aeed6 Mon Sep 17 00:00:00 2001 From: Morrow Date: Tue, 24 Oct 2023 23:33:16 -0400 Subject: [PATCH 01/10] WIP --- .../signals/atom/mob/living/signals_human.dm | 4 + .../dcs/signals/atom/mob/signals_mob.dm | 4 + .../dcs/signals/atom/signals_atom.dm | 17 + .../__DEFINES/dcs/signals/atom/signals_obj.dm | 3 - code/__DEFINES/equipment.dm | 8 +- code/_onclick/click.dm | 3 + code/_onclick/human.dm | 3 + code/datums/components/phone.dm | 463 ++++++++++++++ code/game/objects/items/storage/backpack.dm | 92 +-- code/modules/admin/game_master/game_master.dm | 24 + code/modules/cm_phone/handset.dm | 178 ++++++ code/modules/cm_phone/internal_phone.dm | 4 +- code/modules/cm_phone/phone.dm | 593 ++---------------- code/modules/mob/say.dm | 3 + .../vehicles/interior/interior_landmarks.dm | 24 +- colonialmarines.dme | 2 + maps/map_files/generic/Admin_level.dmm | 2 +- tgui/packages/tgui/interfaces/PhoneMenu.js | 34 +- 18 files changed, 824 insertions(+), 637 deletions(-) create mode 100644 code/datums/components/phone.dm create mode 100644 code/modules/cm_phone/handset.dm diff --git a/code/__DEFINES/dcs/signals/atom/mob/living/signals_human.dm b/code/__DEFINES/dcs/signals/atom/mob/living/signals_human.dm index 6614272d33..ed1ac4a5bb 100644 --- a/code/__DEFINES/dcs/signals/atom/mob/living/signals_human.dm +++ b/code/__DEFINES/dcs/signals/atom/mob/living/signals_human.dm @@ -67,3 +67,7 @@ #define COMSIG_HUMAN_SURGERY_APPLY_MODIFIERS "human_surgery_apply_modifiers" /// From /mob/living/carbon/human/proc/get_flags_cold_protection() #define COMSIG_HUMAN_COLD_PROTECTION_APPLY_MODIFIERS "human_cold_protection_apply_modifiers" + +/// From /mob/living/carbon/human/UnarmedAttack() +#define COMSIG_HUMAN_BEFORE_ATTACK_HAND "human_before_attack_hand" + #define COMPONENT_CANCEL_ATTACK_HAND (1<<0) diff --git a/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm b/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm index bab6064cfd..b9e89bf441 100644 --- a/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm +++ b/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm @@ -128,3 +128,7 @@ /// From /obj/item/proc/pickup() : (obj/item/picked_up) #define COMSIG_MOB_PICKUP_ITEM "mob_pickup_item" + +/// From /mob/proc/say_dead(message) +#define COMSIG_DEAD_SPEAK "comsig_dead_speak" + #define COMPONENT_OVERRIDE_DEAD_SPEAK (1<<0) diff --git a/code/__DEFINES/dcs/signals/atom/signals_atom.dm b/code/__DEFINES/dcs/signals/atom/signals_atom.dm index 7431c5593b..8d699b0b2e 100644 --- a/code/__DEFINES/dcs/signals/atom/signals_atom.dm +++ b/code/__DEFINES/dcs/signals/atom/signals_atom.dm @@ -45,3 +45,20 @@ ///When the transform or an atom is varedited through vv topic. #define COMSIG_ATOM_VV_MODIFY_TRANSFORM "atom_vv_modify_transform" + +/// From /mob/living/carbon/human/UnarmedAttack() +#define COMSIG_ATOM_HUMAN_ATTACK_HAND "atom_human_attack_hand" + #define COMPONENT_CANCEL_ATTACK_HAND (1<<0) + +/// From /mob/proc/click_adjacent() +#define COMSIG_ATOM_MOB_ATTACKBY "atom_mob_attackby" + #define COMPONENT_CANCEL_ATTACKBY (1<<0) + +/// From /datum/component/phone/proc/picked_up_call() and /datum/component/phone/proc/post_call_phone() +#define COMSIG_ATOM_PHONE_PICKED_UP "atom_phone_picked_up" +/// From /datum/component/phone/proc/recall_handset() +#define COMSIG_ATOM_PHONE_HUNG_UP "atom_phone_hung_up" +/// From /datum/component/phone/proc/call_phone() +#define COMSIG_ATOM_PHONE_RINGING "atom_phone_ringing" +/// From /datum/component/phone/proc/reset_call() +#define COMSIG_ATOM_PHONE_STOPPED_RINGING "atom_phone_stopped_ringing" diff --git a/code/__DEFINES/dcs/signals/atom/signals_obj.dm b/code/__DEFINES/dcs/signals/atom/signals_obj.dm index aebd0d09d0..7e4436b3cf 100644 --- a/code/__DEFINES/dcs/signals/atom/signals_obj.dm +++ b/code/__DEFINES/dcs/signals/atom/signals_obj.dm @@ -22,9 +22,6 @@ #define COMSIG_SENTRY_EMPTY_AMMO_ALERT "signal_sentry_empty_ammo" #define COMSIG_SENTRY_DESTROYED_ALERT "signal_sentry_destroyed" -/// from /obj/structure/transmitter/update_icon() -#define COMSIG_TRANSMITTER_UPDATE_ICON "transmitter_update_icon" - #define COMSIG_TENT_COLLAPSING "tent_collapsing" /// from /obj/proc/afterbuckle() diff --git a/code/__DEFINES/equipment.dm b/code/__DEFINES/equipment.dm index 5f8f27a657..3c6cefe5bc 100644 --- a/code/__DEFINES/equipment.dm +++ b/code/__DEFINES/equipment.dm @@ -552,7 +552,7 @@ var/global/list/uniform_categories = list( #define PHONE_UPP_SOLDIER "Soldier" #define PHONE_IO "IO" -#define PHONE_DND_FORCED 2 -#define PHONE_DND_ON 1 -#define PHONE_DND_OFF 0 -#define PHONE_DND_FORBIDDEN -1 +#define PHONE_DO_NOT_DISTURB_FORCED 2 +#define PHONE_DO_NOT_DISTURB_ON 1 +#define PHONE_DO_NOT_DISTURB_OFF 0 +#define PHONE_DO_NOT_DISTURB_FORBIDDEN -1 diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 21f3fcafd9..fe0c9e7b72 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -149,6 +149,9 @@ if(W.attack_speed && !src.contains(A)) //Not being worn or carried in the user's inventory somewhere, including internal storages. next_move += W.attack_speed + if(SEND_SIGNAL(A, COMSIG_ATOM_MOB_ATTACKBY, W, src) & COMPONENT_CANCEL_ATTACKBY) + return + if(!A.attackby(W, src, mods) && A && !QDELETED(A)) // in case the attackby slept if(!W) diff --git a/code/_onclick/human.dm b/code/_onclick/human.dm index cb71e27f9d..74e3261650 100644 --- a/code/_onclick/human.dm +++ b/code/_onclick/human.dm @@ -80,6 +80,9 @@ to_chat(src, SPAN_NOTICE("You try to move your [temp.display_name], but cannot!")) return + if(SEND_SIGNAL(A, COMSIG_ATOM_HUMAN_ATTACK_HAND, src) & COMPONENT_CANCEL_ATTACK_HAND) + return + A.attack_hand(src, click_parameters) /datum/proc/handle_click(mob/living/carbon/human/user, atom/A, params) //Heres our handle click relay proc thing. diff --git a/code/datums/components/phone.dm b/code/datums/components/phone.dm new file mode 100644 index 0000000000..7a1ce44491 --- /dev/null +++ b/code/datums/components/phone.dm @@ -0,0 +1,463 @@ + +/// Holds all of our phone components +GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) + +/datum/component/phone + + /// Our phone category which sorts us into tabs in the phone menu TGUI + var/phone_category = "Uncategorised" + + /// Honestly no idea yet - Morrow + var/phone_color = "white" + + /// The id of our phone which shows up when we talk + var/phone_id = "Telephone" + + /// Our phone icon that is displayed in the phone menu TGUI + var/phone_icon + + /// Our connected handset + var/obj/item/handset/phone_handset + + /// What actually holds our phone, defaults to parent but may be set differently + var/atom/holder + + /// A phone we are calling or has called us + var/datum/component/phone/calling_phone + + /// Range of our handset + var/range = 7 + + /// Whether or not the phone is receiving calls or not. Varies between on/off or forcibly on/off. + var/do_not_disturb = PHONE_DO_NOT_DISTURB_OFF + + /// The ID of our timer to cancel an attempted call and "go to voicemail" + var/timeout_timer_id + + /// The time it takes for our timer to end to cancel an attempted call and "go to voicemail" + var/timeout_duration = 30 SECONDS + + /// Networks that this phone can take calls from + var/list/networks_receive = list(FACTION_MARINE) + + /// Networks that this phone can call + var/list/networks_transmit = list(FACTION_MARINE) + +/datum/component/phone/Initialize(...) + . = ..() + + if(!istype(parent, /atom)) + return COMPONENT_INCOMPATIBLE + + handle_initial_variables(arglist(args)) + + GLOB.phones += src + +/datum/component/phone/Destroy() + if(phone_handset) + if(phone_handset.loc == src) + UnregisterSignal(phone_handset, COMSIG_PARENT_PREQDELETED) + qdel(phone_handset) + else + phone_handset.phone_component = null + phone_handset = null + + GLOB.phones -= src + SStgui.close_uis(src) + + reset_call() + return ..() + +/datum/component/phone/proc/handle_initial_variables(phone_category, phone_color, phone_id, phone_icon, holder) + src.phone_category = phone_category + src.phone_color = phone_color + src.phone_id = phone_id + src.phone_icon = phone_icon + src.holder = holder ? holder : parent + + phone_handset = new(src.holder, src, src.holder) + RegisterSignal(phone_handset, COMSIG_PARENT_PREQDELETED, PROC_REF(override_delete)) + + RegisterSignal(src.holder, COMSIG_ATOM_HUMAN_ATTACK_HAND, PROC_REF(use_phone)) + RegisterSignal(src.holder, COMSIG_ATOM_MOB_ATTACKBY, PROC_REF(item_used_on_phone)) + +/datum/component/phone/proc/override_delete() + SIGNAL_HANDLER + recall_handset() + return COMPONENT_ABORT_QDEL + +/// When we initially interact with the phone, whether opening the menu to call someone or picking up the phone being called +/datum/component/phone/proc/use_phone(atom/phone, mob/living/carbon/human/user) + SIGNAL_HANDLER + + if(!calling_phone) + INVOKE_ASYNC(src, PROC_REF(tgui_interact), user) + return + + if(!phone_handset) + return + + if(phone_handset.loc != holder) + return + + picked_up_call(user) + calling_phone.other_phone_picked_up_call() + +/datum/component/phone/proc/item_used_on_phone(atom/phone, obj/item/attacking_item, mob/user) + SIGNAL_HANDLER + + if(attacking_item == phone_handset) + recall_handset() + return COMPONENT_CANCEL_ATTACKBY + +/datum/component/phone/proc/picked_up_call(mob/living/carbon/human/user) + to_chat(user, SPAN_PURPLE("[icon2html(holder, user)] Picked up a call from [calling_phone.phone_id].")) + playsound(get_turf(user), "rtb_handset") + + user.put_in_active_hand(phone_handset) + SEND_SIGNAL(holder, COMSIG_ATOM_PHONE_PICKED_UP) + +/datum/component/phone/proc/other_phone_picked_up_call() + if(!calling_phone) + return + + if(!phone_handset) + return + + if(timeout_timer_id) + deltimer(timeout_timer_id) + timeout_timer_id = null + + if(!ismob(phone_handset.loc)) + return + + var/mob/phone_user = phone_handset.loc + to_chat(phone_user, SPAN_PURPLE("[icon2html(calling_phone.holder, phone_user)] [calling_phone.phone_id] has picked up.")) + +/datum/component/phone/proc/get_phones() + var/list/phone_list = list() + + for(var/possible_phone in GLOB.phones) + var/datum/component/phone/target_phone = possible_phone + + if(!target_phone.phone_available()) + continue + + var/net_link = FALSE + for(var/network in networks_transmit) + if(network in target_phone.networks_receive) + net_link = TRUE + continue + if(!net_link) + continue + + var/id = target_phone.phone_id + var/num_id = 1 + while(id in phone_list) + id = "[target_phone.phone_id] [num_id]" + num_id++ + + target_phone.phone_id = id + phone_list[id] = target_phone + + return phone_list + +/datum/component/phone/proc/phone_available() + if(calling_phone) + return FALSE + + if(!phone_handset) + return FALSE + + if(phone_handset.loc != holder) + return FALSE + + if(do_not_disturb == PHONE_DO_NOT_DISTURB_ON) + return FALSE + + if(do_not_disturb == PHONE_DO_NOT_DISTURB_FORCED) + return FALSE + + return TRUE + +/datum/component/phone/proc/phone_menu_usable() + if(calling_phone) + return FALSE + + if(!phone_handset) + return FALSE + + if(phone_handset.loc != holder) + return + + return TRUE + +/datum/component/phone/proc/call_phone(mob/user, calling_phone_id) + var/list/phones = get_phones() + phones -= phone_id + + if(!length(phones) || !(calling_phone_id in phones)) + to_chat(user, SPAN_PURPLE("[icon2html(holder, user)] No phones could be located to call!")) + return + + calling_phone = phones[calling_phone_id] + if(!istype(calling_phone) || QDELETED(calling_phone)) + calling_phone = null + CRASH("Qdelled/improper atom inside phones list! (istype returned: [istype(calling_phone)], QDELETED returned: [QDELETED(calling_phone)])") + + if(!calling_phone.phone_available()) + calling_phone = null + return + + calling_phone.calling_phone = src + SEND_SIGNAL(calling_phone.holder, COMSIG_ATOM_PHONE_RINGING) + + post_call_phone(user, calling_phone_id) + + //START_PROCESSING(SSobj, src) - handle ringing - Morrow + //START_PROCESSING(SSobj, T) + +/datum/component/phone/proc/post_call_phone(mob/user, calling_phone_id) + to_chat(user, SPAN_PURPLE("[icon2html(holder, user)] Dialing [calling_phone_id]..")) + timeout_timer_id = addtimer(CALLBACK(src, PROC_REF(reset_call), TRUE), timeout_duration, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE) + playsound(get_turf(user), "rtb_handset") + + user.put_in_active_hand(phone_handset) + SEND_SIGNAL(holder, COMSIG_ATOM_PHONE_PICKED_UP) + +/datum/component/phone/proc/toggle_do_not_disturb(mob/user) + switch(do_not_disturb) + if(PHONE_DO_NOT_DISTURB_ON) + do_not_disturb = PHONE_DO_NOT_DISTURB_OFF + to_chat(user, SPAN_NOTICE("Do Not Disturb has been disabled. You can now receive calls.")) + if(PHONE_DO_NOT_DISTURB_OFF) + do_not_disturb = PHONE_DO_NOT_DISTURB_ON + to_chat(user, SPAN_WARNING("Do Not Disturb has been enabled. No calls will be received.")) + else + return FALSE + return TRUE + +/datum/component/phone/proc/reset_call(timeout = FALSE, recursed = FALSE) + if(timeout_timer_id) + deltimer(timeout_timer_id) + timeout_timer_id = null + + if(!calling_phone) + return + + if(!recursed) + calling_phone.reset_call(timeout, recursed = TRUE) + + SEND_SIGNAL(calling_phone.holder, COMSIG_ATOM_PHONE_STOPPED_RINGING) + + //STOP_PROCESSING(SSobj, T) - Stop ringing - Morrow + + handle_reset_call_message(timeout, recursed) + + calling_phone = null + +/datum/component/phone/proc/handle_reset_call_message(timeout = FALSE, recursed = FALSE) + if(!phone_handset) + return + + if(!ismob(phone_handset.loc)) + return + + var/mob/handset_user = phone_handset.loc + if(recursed) + to_chat(handset_user, SPAN_PURPLE("[icon2html(holder, handset_user)] [calling_phone.phone_id] has hung up on you.")) + else if(timeout) + to_chat(handset_user, SPAN_PURPLE("[icon2html(holder, handset_user)] Your call to [calling_phone.phone_id] has reached voicemail, you immediately disconnect the line.")) + else + to_chat(handset_user, SPAN_PURPLE("[icon2html(holder, handset_user)] You have hung up on [calling_phone.phone_id].")) + +/datum/component/phone/proc/recall_handset() + if(ismob(phone_handset.loc)) + var/mob/M = phone_handset.loc + M.drop_held_item(phone_handset) + playsound(get_turf(M), "rtb_handset", 100, FALSE, 7) + + phone_handset.forceMove(holder) + reset_call() + + SEND_SIGNAL(calling_phone.holder, COMSIG_ATOM_PHONE_HUNG_UP) + +/datum/component/phone/proc/handle_speak(message, datum/language/message_language, mob/speaker, direct_talking = TRUE) + if(message_language.flags & SIGNLANG) + return + + if(!calling_phone) + return + + if(direct_talking) + handle_hear(message, message_language, speaker, direct_talking) + + calling_phone.handle_hear(message, message_language, speaker, direct_talking) + log_say("TELEPHONE: [key_name(speaker)] [direct_talking ? "" : "was picked up "]on Phone '[phone_id]' to '[calling_phone.phone_id]' said '[message]'") + + // Add dchat listen in because it's funny, check radio preferences first, oh and don't do the background stuff - Morrow + +/datum/component/phone/proc/handle_hear(message, datum/language/message_language, mob/speaker, direct_talking) + if(!phone_handset) + return + + if(!calling_phone) + return + + if(!ismob(phone_handset.loc)) + return + + var/loudness = 0 + if(phone_handset.raised) + loudness = 3 + + var/mob/hearing_mob = phone_handset.loc + var/name_override = calling_phone.phone_id + + if(hearing_mob == speaker && direct_talking) + name_override = phone_id + + hearing_mob.hear_radio(message, "says", message_language, part_a = "", part_b = " ", vname = name_override, speaker = speaker, command = loudness, no_paygrade = TRUE) + +///datum/component/phone/proc/set_tether_holder(atom/A) - Do something with this, likely need to have a signal for if the parent is moving - Morrow +// tether_holder = A +// +// if(phone_handset) +// phone_handset.reset_tether() + + + + +//TGUI section + +/datum/component/phone/ui_status(mob/user, datum/ui_state/state) + . = ..() + if(phone_menu_usable()) + return UI_INTERACTIVE + +/datum/component/phone/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + + switch(action) + if("call_phone") + call_phone(ui.user, params["phone_id"]) + . = TRUE + + if("toggle_do_not_disturb") + toggle_do_not_disturb(ui.user) + . = TRUE + +/datum/component/phone/ui_data(mob/user) + var/list/data = list() + + data["do_not_disturb"] = do_not_disturb + + return data + +/datum/component/phone/ui_static_data(mob/user) + . = list() + + .["available_phones"] = get_phones() - list(phone_id) + var/list/phones = list() + for(var/datum/component/phone/cycled_phone as anything in GLOB.phones) + phones += list(list( + "phone_category" = cycled_phone.phone_category, + "phone_color" = cycled_phone.phone_color, + "phone_id" = cycled_phone.phone_id, + "phone_icon" = cycled_phone.phone_icon + )) + + .["phones"] = phones + +/datum/component/phone/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "PhoneMenu", phone_id) + ui.open() + + +// Virtual phone section + +/// Virtual phone used for situations where you want to be able to use a phone without a handset +/datum/component/phone/virtual + /// If it is a virtual phone we need a virtual user + var/mob/virtual_user + +/datum/component/phone/virtual/Destroy() + virtual_user = null + + return ..() + +/datum/component/phone/virtual/handle_initial_variables(phone_category, phone_color, phone_id, phone_icon, holder, virtual_user) + src.phone_category = phone_category + src.phone_color = phone_color + src.phone_id = phone_id + src.phone_icon = phone_icon + src.holder = holder ? holder : parent + src.virtual_user = virtual_user + +/datum/component/phone/virtual/picked_up_call(mob/living/carbon/human/user) + to_chat(user, SPAN_PURPLE("[icon2html(src, user)] Picked up a call from [calling_phone.phone_id].")) + +/datum/component/phone/virtual/other_phone_picked_up_call() + if(!calling_phone) + return + + if(timeout_timer_id) + deltimer(timeout_timer_id) + timeout_timer_id = null + + to_chat(virtual_user, SPAN_PURPLE("[icon2html(calling_phone.holder, virtual_user)] [calling_phone.phone_id] has picked up.")) + +/datum/component/phone/virtual/phone_available() + if(calling_phone) + return FALSE + + if(do_not_disturb == PHONE_DO_NOT_DISTURB_ON) + return FALSE + + if(do_not_disturb == PHONE_DO_NOT_DISTURB_FORCED) + return FALSE + + return TRUE + +/datum/component/phone/virtual/handle_reset_call_message(timeout = FALSE, recursed = FALSE) + if(recursed) + to_chat(virtual_user, SPAN_PURPLE("[icon2html(holder, virtual_user)] [calling_phone.phone_id] has hung up on you.")) + else if(timeout) + to_chat(virtual_user, SPAN_PURPLE("[icon2html(holder, virtual_user)] Your call to [calling_phone.phone_id] has reached voicemail, you immediately disconnect the line.")) + else + to_chat(virtual_user, SPAN_PURPLE("[icon2html(holder, virtual_user)] You have hung up on [calling_phone.phone_id].")) + +/datum/component/phone/virtual/post_call_phone(mob/user, calling_phone_id) + to_chat(user, SPAN_PURPLE("[icon2html(holder, user)] Dialing [calling_phone_id]..")) + timeout_timer_id = addtimer(CALLBACK(src, PROC_REF(reset_call), TRUE), timeout_duration, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE) + + playsound_client(user.client, "rtb_handset") + +/datum/component/phone/virtual/recall_handset() + reset_call() // I don't think this will be possible given like... we don't have a handset but just in case + return + +/datum/component/phone/virtual/handle_hear(message, datum/language/message_language, mob/speaker) + if(!calling_phone) + return + + var/name_override = calling_phone.phone_id + + if(virtual_user == speaker) + name_override = phone_id + + virtual_user.hear_radio(message, "says", message_language, part_a = "", part_b = " ", vname = name_override, speaker = speaker, command = 3, no_paygrade = TRUE) + +// TGUI section + +/datum/component/phone/virtual/ui_status(mob/user, datum/ui_state/state) + return UI_INTERACTIVE + +/datum/component/phone/virtual/ui_data(mob/user) + . = ..() + + .["virtual_phone"] = TRUE diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index 3b65811b05..3e760927fc 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -499,7 +499,7 @@ GLOBAL_LIST_EMPTY_TYPED(radio_packs, /obj/item/storage/backpack/marine/satchel/r flags_item = ITEM_OVERRIDE_NORTHFACE - var/obj/structure/transmitter/internal/internal_transmitter + //var/obj/structure/transmitter/internal/internal_transmitter var/phone_category = PHONE_MARINE var/list/networks_receive = list(FACTION_MARINE) @@ -524,14 +524,14 @@ GLOBAL_LIST_EMPTY_TYPED(radio_packs, /obj/item/storage/backpack/marine/satchel/r /obj/item/storage/backpack/marine/satchel/rto/Initialize() . = ..() - internal_transmitter = new(src) - internal_transmitter.relay_obj = src - internal_transmitter.phone_category = phone_category - internal_transmitter.enabled = FALSE - internal_transmitter.networks_receive = networks_receive - internal_transmitter.networks_transmit = networks_transmit - RegisterSignal(internal_transmitter, COMSIG_TRANSMITTER_UPDATE_ICON, PROC_REF(check_for_ringing)) - GLOB.radio_packs += src + //internal_transmitter = new(src) + //internal_transmitter.relay_obj = src + //internal_transmitter.phone_category = phone_category + //internal_transmitter.enabled = FALSE + //internal_transmitter.networks_receive = networks_receive + //internal_transmitter.networks_transmit = networks_transmit + //RegisterSignal(internal_transmitter, COMSIG_TRANSMITTER_UPDATE_ICON, PROC_REF(check_for_ringing)) + //GLOB.radio_packs += src /obj/item/storage/backpack/marine/satchel/rto/proc/check_for_ringing() SIGNAL_HANDLER @@ -539,63 +539,63 @@ GLOBAL_LIST_EMPTY_TYPED(radio_packs, /obj/item/storage/backpack/marine/satchel/r /obj/item/storage/backpack/marine/satchel/rto/update_icon() . = ..() - if(!internal_transmitter) - return + //if(!internal_transmitter) + // return - if(!internal_transmitter.attached_to \ - || internal_transmitter.attached_to.loc != internal_transmitter) - icon_state = "[base_icon]_ear" - return + //if(!internal_transmitter.attached_to \ + // || internal_transmitter.attached_to.loc != internal_transmitter) + // icon_state = "[base_icon]_ear" + // return - if(internal_transmitter.caller) - icon_state = "[base_icon]_ring" - else - icon_state = base_icon + //if(internal_transmitter.caller) + // icon_state = "[base_icon]_ring" + //else + // icon_state = base_icon /obj/item/storage/backpack/marine/satchel/rto/forceMove(atom/dest) . = ..() - if(isturf(dest)) - internal_transmitter.set_tether_holder(src) - else - internal_transmitter.set_tether_holder(loc) + //if(isturf(dest)) + // internal_transmitter.set_tether_holder(src) + //else + // internal_transmitter.set_tether_holder(loc) - Morrow /obj/item/storage/backpack/marine/satchel/rto/Destroy() GLOB.radio_packs -= src - qdel(internal_transmitter) + //qdel(internal_transmitter) return ..() /obj/item/storage/backpack/marine/satchel/rto/pickup(mob/user) . = ..() - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.comm_title) - internal_transmitter.phone_id = "[H.comm_title] [H]" - else if(H.job) - internal_transmitter.phone_id = "[H.job] [H]" - else - internal_transmitter.phone_id = "[H]" - - if(H.assigned_squad) - internal_transmitter.phone_id += " ([H.assigned_squad.name])" - else - internal_transmitter.phone_id = "[user]" - - internal_transmitter.enabled = TRUE +// if(ishuman(user)) +// var/mob/living/carbon/human/H = user +// if(H.comm_title) + //internal_transmitter.phone_id = "[H.comm_title] [H]" +// else if(H.job) + //internal_transmitter.phone_id = "[H.job] [H]" +// else + //internal_transmitter.phone_id = "[H]" + +// if(H.assigned_squad) + //internal_transmitter.phone_id += " ([H.assigned_squad.name])" +// else + //internal_transmitter.phone_id = "[user]" + + //internal_transmitter.enabled = TRUE /obj/item/storage/backpack/marine/satchel/rto/dropped(mob/user) . = ..() - internal_transmitter.phone_id = "[src]" - internal_transmitter.enabled = FALSE + //internal_transmitter.phone_id = "[src]" + //internal_transmitter.enabled = FALSE /obj/item/storage/backpack/marine/satchel/rto/proc/use_phone(mob/user) - internal_transmitter.attack_hand(user) + //internal_transmitter.attack_hand(user) /obj/item/storage/backpack/marine/satchel/rto/attackby(obj/item/W, mob/user) - if(internal_transmitter && internal_transmitter.attached_to == W) - internal_transmitter.attackby(W, user) - else - . = ..() +// if(internal_transmitter && internal_transmitter.attached_to == W) +// internal_transmitter.attackby(W, user) +// else +// . = ..() /obj/item/storage/backpack/marine/satchel/rto/upp_net name = "\improper UPP Radio Telephone Pack" diff --git a/code/modules/admin/game_master/game_master.dm b/code/modules/admin/game_master/game_master.dm index d61a7b6921..dbdf2b9ae1 100644 --- a/code/modules/admin/game_master/game_master.dm +++ b/code/modules/admin/game_master/game_master.dm @@ -73,6 +73,12 @@ GLOBAL_LIST_EMPTY(game_master_objectives) /// End Objective Stuff + /// Communication stuff + + //var/datum/component/phone/game_master/game_master_phone + + /// End Communication stuff + /// Holds what type of click intercept we are using var/current_click_intercept_action @@ -84,12 +90,15 @@ GLOBAL_LIST_EMPTY(game_master_objectives) current_submenus = list() + //game_master_phone = new() + using_client.click_intercept = src /datum/game_master/Destroy(force, ...) . = ..() submenu_types = null current_submenus = null + //QDEL_NULL(game_master_phone) /datum/game_master/ui_data(mob/user) . = ..() @@ -161,6 +170,21 @@ GLOBAL_LIST_EMPTY(game_master_objectives) current_click_intercept_action = OBJECTIVE_CLICK_INTERCEPT_ACTION return + //Communication Section + //if("use_game_master_phone") + //if(!game_master_phone) + // game_master_phone = new() + + //var/new_phone_id = tgui_input_text(ui.user, "New phone id?", "Phone ID", game_master_phone.phone_id) + //if(!new_phone_id) + // return + + //game_master_phone.phone_id = new_phone_id + + //game_master_phone.tgui_interact(ui.user) + //return + + //if("set_communication_clarity") /datum/game_master/ui_close(mob/user) . = ..() diff --git a/code/modules/cm_phone/handset.dm b/code/modules/cm_phone/handset.dm new file mode 100644 index 0000000000..fbc245f079 --- /dev/null +++ b/code/modules/cm_phone/handset.dm @@ -0,0 +1,178 @@ + +#define HANDSET_RANGE 7 + +/obj/item/handset + name = "telephone" + icon = 'icons/obj/items/misc.dmi' + icon_state = "rpb_phone" + + w_class = SIZE_LARGE + + flags_atom = FPRINT|USES_HEARING + + var/datum/component/phone/phone_component + var/atom/holder + + var/datum/effects/tethering/tether_effect + + var/raised = FALSE + var/zlevel_transfer = FALSE + var/zlevel_transfer_timer = TIMER_ID_NULL + var/zlevel_transfer_timeout = 5 SECONDS + +/obj/item/handset/Initialize(mapload, phone_component, holder) + . = ..() + + src.phone_component = phone_component + src.holder = holder + attach_to(holder) + +/obj/item/handset/Destroy() + phone_component = null + holder = null + remove_attached() + return ..() + +/obj/item/handset/hear_talk(mob/living/talker, message, verb="says", datum/language/message_language, italics = 0) + if(talker == loc) + phone_component.handle_speak(message, message_language, talker, direct_talking = TRUE) + return + + var/distance = get_dist(src, talker) + + if(distance > 1) + return + + message = stars(message, (100 - (distance * 40 + rand(-15, 15)))) + + phone_component.handle_speak(message, message_language, talker, direct_talking = FALSE) + +/obj/item/handset/proc/attach_to(atom/to_attach) + if(!istype(to_attach)) + return + + remove_attached() + + holder = to_attach + +/obj/item/handset/proc/remove_attached() + holder = null + reset_tether() + +/obj/item/handset/proc/reset_tether() + SIGNAL_HANDLER + if (tether_effect) + UnregisterSignal(tether_effect, COMSIG_PARENT_QDELETING) + if(!QDESTROYING(tether_effect)) + qdel(tether_effect) + tether_effect = null + if(!do_zlevel_check()) + on_beam_removed() + +/obj/item/handset/attack_hand(mob/user) + if(holder && get_dist(user, holder) > HANDSET_RANGE) + return FALSE + return ..() + +/obj/item/handset/proc/on_beam_removed() + if(!holder) + return + + if(loc == holder) + return + + if(get_dist(holder, src) > HANDSET_RANGE) + phone_component.recall_handset() + + var/atom/tether_to = src + + if(loc != get_turf(src)) + tether_to = loc + if(tether_to.loc != get_turf(tether_to)) + phone_component.recall_handset() + return + + var/atom/tether_from = holder + + if(tether_from == tether_to) + return + + var/list/tether_effects = apply_tether(tether_from, tether_to, range = HANDSET_RANGE, icon = "wire", always_face = FALSE) + tether_effect = tether_effects["tetherer_tether"] + RegisterSignal(tether_effect, COMSIG_PARENT_QDELETING, PROC_REF(reset_tether)) + +/obj/item/handset/attack_self(mob/user) + ..() + + if(raised) + set_raised(FALSE, user) + to_chat(user, SPAN_NOTICE("You lower [src].")) + else + set_raised(TRUE, user) + to_chat(user, SPAN_NOTICE("You raise [src] to your ear.")) + +/obj/item/handset/proc/set_raised(to_raise, mob/living/carbon/human/user) + if(!istype(user)) + return + + if(!to_raise) + raised = FALSE + item_state = "rpb_phone" + else + raised = TRUE + item_state = "rpb_phone_ear" + + user.update_inv_r_hand() + user.update_inv_l_hand() + +/obj/item/handset/dropped(mob/user) + . = ..() + UnregisterSignal(user, COMSIG_LIVING_SPEAK) + + set_raised(FALSE, user) + +/obj/item/handset/on_enter_storage(obj/item/storage/S) + . = ..() + if(phone_component) + phone_component.recall_handset() + +/obj/item/handset/forceMove(atom/dest) + . = ..() + if(.) + reset_tether() + +/obj/item/handset/proc/do_zlevel_check() + if(!holder || !loc.z || !holder.z) + return FALSE + + if(zlevel_transfer) + if(loc.z == holder.z) + zlevel_transfer = FALSE + if(zlevel_transfer_timer) + deltimer(zlevel_transfer_timer) + UnregisterSignal(holder, COMSIG_MOVABLE_MOVED) + return FALSE + return TRUE + + if(holder && loc.z != holder.z) + zlevel_transfer = TRUE + zlevel_transfer_timer = addtimer(CALLBACK(src, PROC_REF(try_doing_tether)), zlevel_transfer_timeout, TIMER_UNIQUE|TIMER_STOPPABLE) + RegisterSignal(holder, COMSIG_MOVABLE_MOVED, PROC_REF(transmitter_move_handler)) + return TRUE + return FALSE + +/obj/item/handset/proc/transmitter_move_handler(datum/source) + SIGNAL_HANDLER + zlevel_transfer = FALSE + if(zlevel_transfer_timer) + deltimer(zlevel_transfer_timer) + UnregisterSignal(holder, COMSIG_MOVABLE_MOVED) + reset_tether() + +/obj/item/handset/proc/try_doing_tether() + zlevel_transfer_timer = TIMER_ID_NULL + zlevel_transfer = FALSE + UnregisterSignal(holder, COMSIG_MOVABLE_MOVED) + reset_tether() + +#undef HANDSET_RANGE diff --git a/code/modules/cm_phone/internal_phone.dm b/code/modules/cm_phone/internal_phone.dm index 96530503aa..6bab6fc732 100644 --- a/code/modules/cm_phone/internal_phone.dm +++ b/code/modules/cm_phone/internal_phone.dm @@ -1,8 +1,7 @@ +/* /obj/structure/transmitter/internal name = "\improper internal telephone receiver" - phone_type = /obj/item/phone - var/atom/relay_obj /obj/structure/transmitter/internal/ui_host(mob/user, datum/tgui/ui) @@ -13,3 +12,4 @@ /obj/structure/transmitter/internal/Destroy() relay_obj = null return ..() +*/ diff --git a/code/modules/cm_phone/phone.dm b/code/modules/cm_phone/phone.dm index fd9c8aa02d..0aace05493 100644 --- a/code/modules/cm_phone/phone.dm +++ b/code/modules/cm_phone/phone.dm @@ -1,6 +1,4 @@ -GLOBAL_LIST_EMPTY_TYPED(transmitters, /obj/structure/transmitter) - -/obj/structure/transmitter +/obj/structure/phone_base name = "telephone receiver" icon = 'icons/obj/structures/structures.dmi' icon_state = "wall_phone" @@ -11,613 +9,92 @@ GLOBAL_LIST_EMPTY_TYPED(transmitters, /obj/structure/transmitter) var/phone_id = "Telephone" var/phone_icon - var/obj/item/phone/attached_to - var/atom/tether_holder - - var/obj/structure/transmitter/calling - var/obj/structure/transmitter/caller - - var/next_ring = 0 - - var/phone_type = /obj/item/phone - - var/range = 7 - - var/enabled = TRUE /// Whether or not the phone is receiving calls or not. Varies between on/off or forcibly on/off. - var/do_not_disturb = PHONE_DND_OFF + var/do_not_disturb = PHONE_DO_NOT_DISTURB_OFF var/base_icon_state - var/timeout_timer_id - var/timeout_duration = 30 SECONDS - - var/list/networks_receive = list(FACTION_MARINE) + var/list/networks_receive = list(FACTION_MARINE) // pass these to component, plus that shit above - Morrow var/list/networks_transmit = list(FACTION_MARINE) -/obj/structure/transmitter/hidden - do_not_disturb = PHONE_DND_FORCED - -/obj/structure/transmitter/Initialize(mapload, ...) +/obj/structure/phone_base/Initialize(mapload, ...) . = ..() base_icon_state = icon_state - attached_to = new phone_type(src) - RegisterSignal(attached_to, COMSIG_PARENT_PREQDELETED, PROC_REF(override_delete)) update_icon() - if(!get_turf(src)) - return + AddComponent(/datum/component/phone, phone_category, phone_color, phone_id, phone_icon) - GLOB.transmitters += src - -/obj/structure/transmitter/update_icon() +// this needs a specific handling on the component level - Morrow +/obj/structure/phone_base/update_icon() . = ..() SEND_SIGNAL(src, COMSIG_TRANSMITTER_UPDATE_ICON) - if(attached_to.loc != src) - icon_state = "[base_icon_state]_ear" - return - - if(caller) - icon_state = "[base_icon_state]_ring" - else - icon_state = base_icon_state - -/obj/structure/transmitter/proc/override_delete() - SIGNAL_HANDLER - recall_phone() - return COMPONENT_ABORT_QDEL - - -#define TRANSMITTER_UNAVAILABLE(T) (\ - T.get_calling_phone() \ - || !T.attached_to \ - || T.attached_to.loc != T \ - || !T.enabled\ -) - -/obj/structure/transmitter/proc/get_transmitters() - var/list/phone_list = list() - - for(var/possible_phone in GLOB.transmitters) - var/obj/structure/transmitter/target_phone = possible_phone - var/current_dnd = FALSE - switch(target_phone.do_not_disturb) - if(PHONE_DND_ON, PHONE_DND_FORCED) - current_dnd = TRUE - if(TRANSMITTER_UNAVAILABLE(target_phone) || current_dnd) // Phone not available - continue - var/net_link = FALSE - for(var/network in networks_transmit) - if(network in target_phone.networks_receive) - net_link = TRUE - continue - if(!net_link) - continue - - var/id = target_phone.phone_id - var/num_id = 1 - while(id in phone_list) - id = "[target_phone.phone_id] [num_id]" - num_id++ - - target_phone.phone_id = id - phone_list[id] = target_phone - - return phone_list - -/obj/structure/transmitter/ui_status(mob/user, datum/ui_state/state) - . = ..() - if(TRANSMITTER_UNAVAILABLE(src)) - return UI_CLOSE - -/obj/structure/transmitter/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) - . = ..() - if(.) - return - - if(TRANSMITTER_UNAVAILABLE(src)) - return - - if(!ishuman(usr)) - return - - var/mob/living/carbon/human/user = usr - - switch(action) - if("call_phone") - call_phone(user, params["phone_id"]) - . = TRUE - SStgui.close_uis(src) - if("toggle_dnd") - toggle_dnd(user) - - update_icon() - -/obj/structure/transmitter/ui_data(mob/user) - var/list/data = list() - - data["availability"] = do_not_disturb - - return data - -/obj/structure/transmitter/ui_static_data(mob/user) - . = list() - - .["available_transmitters"] = get_transmitters() - list(phone_id) - var/list/transmitters = list() - for(var/i in GLOB.transmitters) - var/obj/structure/transmitter/T = i - transmitters += list(list( - "phone_category" = T.phone_category, - "phone_color" = T.phone_color, - "phone_id" = T.phone_id, - "phone_icon" = T.phone_icon - )) - - .["transmitters"] = transmitters - -/obj/structure/transmitter/proc/call_phone(mob/living/carbon/human/user, calling_phone_id) - var/list/transmitters = get_transmitters() - transmitters -= phone_id - - if(!length(transmitters) || !(calling_phone_id in transmitters)) - to_chat(user, SPAN_PURPLE("[icon2html(src, user)] No transmitters could be located to call!")) - return - - var/obj/structure/transmitter/T = transmitters[calling_phone_id] - if(!istype(T) || QDELETED(T)) - transmitters -= T - CRASH("Qdelled/improper atom inside transmitters list! (istype returned: [istype(T)], QDELETED returned: [QDELETED(T)])") - - if(TRANSMITTER_UNAVAILABLE(T)) - return - - calling = T - T.caller = src - T.update_icon() - - to_chat(user, SPAN_PURPLE("[icon2html(src, user)] Dialing [calling_phone_id]..")) - playsound(get_turf(user), "rtb_handset") - timeout_timer_id = addtimer(CALLBACK(src, PROC_REF(reset_call), TRUE), timeout_duration, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE) - - START_PROCESSING(SSobj, src) - START_PROCESSING(SSobj, T) - - user.put_in_hands(attached_to) - -/obj/structure/transmitter/proc/toggle_dnd(mob/living/carbon/human/user) - switch(do_not_disturb) - if(PHONE_DND_ON) - do_not_disturb = PHONE_DND_OFF - to_chat(user, SPAN_NOTICE("Do Not Disturb has been disabled. You can now receive calls.")) - if(PHONE_DND_OFF) - do_not_disturb = PHONE_DND_ON - to_chat(user, SPAN_WARNING("Do Not Disturb has been enabled. No calls will be received.")) - else - return FALSE - return TRUE - -/obj/structure/transmitter/attack_hand(mob/user) - . = ..() - - if(!attached_to || attached_to.loc != src) - return - - if(!ishuman(user)) - return - - if(!enabled) - return - - if(!get_calling_phone()) - tgui_interact(user) - return - - var/obj/structure/transmitter/T = get_calling_phone() - - if(T.attached_to && ismob(T.attached_to.loc)) - var/mob/M = T.attached_to.loc - to_chat(M, SPAN_PURPLE("[icon2html(src, M)] [phone_id] has picked up.")) - if(T.timeout_timer_id) - deltimer(T.timeout_timer_id) - T.timeout_timer_id = null - - to_chat(user, SPAN_PURPLE("[icon2html(src, user)] Picked up a call from [T.phone_id].")) - playsound(get_turf(user), "rtb_handset") - - user.put_in_active_hand(attached_to) - update_icon() - - -#undef TRANSMITTER_UNAVAILABLE - -/obj/structure/transmitter/tgui_interact(mob/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "PhoneMenu", phone_id) - ui.open() - -/obj/structure/transmitter/proc/set_tether_holder(atom/A) - tether_holder = A - - if(attached_to) - attached_to.reset_tether() - -/obj/structure/transmitter/proc/reset_call(timeout = FALSE) - var/obj/structure/transmitter/T = get_calling_phone() - if(T) - if(T.attached_to && ismob(T.attached_to.loc)) - var/mob/M = T.attached_to.loc - to_chat(M, SPAN_PURPLE("[icon2html(src, M)] [phone_id] has hung up on you.")) - - if(attached_to && ismob(attached_to.loc)) - var/mob/M = attached_to.loc - if(timeout) - to_chat(M, SPAN_PURPLE("[icon2html(src, M)] Your call to [T.phone_id] has reached voicemail, you immediately disconnect the line.")) - else - to_chat(M, SPAN_PURPLE("[icon2html(src, M)] You have hung up on [T.phone_id].")) - - if(calling) - calling.caller = null - calling = null - - if(caller) - caller.calling = null - caller = null - - if(timeout_timer_id) - deltimer(timeout_timer_id) - timeout_timer_id = null - - if(T) - if(T.timeout_timer_id) - deltimer(T.timeout_timer_id) - T.timeout_timer_id = null - - T.update_icon() - STOP_PROCESSING(SSobj, T) - - STOP_PROCESSING(SSobj, src) - -/obj/structure/transmitter/process() - if(caller) - if(!attached_to) - STOP_PROCESSING(SSobj, src) - return - - if(attached_to.loc == src) - if(next_ring < world.time) - playsound(loc, 'sound/machines/telephone/telephone_ring.ogg', 75) - visible_message(SPAN_WARNING("[src] rings vigorously!")) - next_ring = world.time + 3 SECONDS - - else if(calling) - var/obj/structure/transmitter/T = get_calling_phone() - if(!T) - STOP_PROCESSING(SSobj, src) - return - - var/obj/item/phone/P = T.attached_to - - if(P && attached_to.loc == src && P.loc == T && next_ring < world.time) - playsound(get_turf(attached_to), 'sound/machines/telephone/telephone_ring.ogg', 20, FALSE, 14) - visible_message(SPAN_WARNING("[src] rings vigorously!")) - next_ring = world.time + 3 SECONDS - - else - STOP_PROCESSING(SSobj, src) - return - - -/obj/structure/transmitter/proc/recall_phone() - if(ismob(attached_to.loc)) - var/mob/M = attached_to.loc - M.drop_held_item(attached_to) - playsound(get_turf(M), "rtb_handset", 100, FALSE, 7) - - attached_to.forceMove(src) - reset_call() - - update_icon() - -/obj/structure/transmitter/proc/get_calling_phone() - if(calling) - return calling - else if(caller) - return caller - - return - -/obj/structure/transmitter/proc/handle_speak(message, datum/language/L, mob/speaking) - if(L.flags & SIGNLANG) return - - var/obj/structure/transmitter/T = get_calling_phone() - if(!istype(T)) - return - - var/obj/item/phone/P = T.attached_to - - if(!P || !attached_to) - return - - P.handle_hear(message, L, speaking) - attached_to.handle_hear(message, L, speaking) - log_say("TELEPHONE: [key_name(speaking)] on Phone '[phone_id]' to '[T.phone_id]' said '[message]'") - -/obj/structure/transmitter/attackby(obj/item/W, mob/user) - if(W == attached_to) - recall_phone() - else - . = ..() - -/obj/structure/transmitter/Destroy() - if(attached_to) - if(attached_to.loc == src) - UnregisterSignal(attached_to, COMSIG_PARENT_PREQDELETED) - qdel(attached_to) - else - attached_to.attached_to = null - attached_to = null - - GLOB.transmitters -= src - SStgui.close_uis(src) - - reset_call() + //if(attached_to.loc != src) + // icon_state = "[base_icon_state]_ear" + // return + + //if(caller) + // icon_state = "[base_icon_state]_ring" + //else + // icon_state = base_icon_state + +/obj/structure/phone_base/Destroy() + networks_receive = null + networks_transmit = null return ..() -/obj/item/phone - name = "telephone" - icon = 'icons/obj/items/misc.dmi' - icon_state = "rpb_phone" - - w_class = SIZE_LARGE - - var/obj/structure/transmitter/attached_to - var/datum/effects/tethering/tether_effect - - var/raised = FALSE - var/zlevel_transfer = FALSE - var/zlevel_transfer_timer = TIMER_ID_NULL - var/zlevel_transfer_timeout = 5 SECONDS - -/obj/item/phone/Initialize(mapload) - . = ..() - if(istype(loc, /obj/structure/transmitter)) - attach_to(loc) - -/obj/item/phone/Destroy() - remove_attached() - return ..() - -/obj/item/phone/proc/handle_speak(mob/speaking, message, datum/language/L) - SIGNAL_HANDLER - - if(!attached_to || loc == attached_to) - UnregisterSignal(speaking, COMSIG_LIVING_SPEAK) - return - - attached_to.handle_speak(message, L, speaking) - -/obj/item/phone/proc/handle_hear(message, datum/language/L, mob/speaking) - if(!attached_to) - return - - var/obj/structure/transmitter/T = attached_to.get_calling_phone() - - if(!T) - return - - if(!ismob(loc)) - return - - var/loudness = 0 - if(raised) - loudness = 3 - - var/mob/M = loc - var/vname = T.phone_id - - if(M == speaking) - vname = attached_to.phone_id - - M.hear_radio( - message, "says", L, part_a = "", - part_b = " ", vname = vname, - speaker = speaking, command = loudness, no_paygrade = TRUE) - -/obj/item/phone/proc/attach_to(obj/structure/transmitter/to_attach) - if(!istype(to_attach)) - return - - remove_attached() - - attached_to = to_attach - - -/obj/item/phone/proc/remove_attached() - attached_to = null - reset_tether() - -/obj/item/phone/proc/reset_tether() - SIGNAL_HANDLER - if (tether_effect) - UnregisterSignal(tether_effect, COMSIG_PARENT_QDELETING) - if(!QDESTROYING(tether_effect)) - qdel(tether_effect) - tether_effect = null - if(!do_zlevel_check()) - on_beam_removed() - -/obj/item/phone/attack_hand(mob/user) - if(attached_to && get_dist(user, attached_to) > attached_to.range) - return FALSE - return ..() - - -/obj/item/phone/proc/on_beam_removed() - if(!attached_to) - return - - if(loc == attached_to) - return - - if(get_dist(attached_to, src) > attached_to.range) - attached_to.recall_phone() - - var/atom/tether_to = src - - if(loc != get_turf(src)) - tether_to = loc - if(tether_to.loc != get_turf(tether_to)) - attached_to.recall_phone() - return - - var/atom/tether_from = attached_to - - if(attached_to.tether_holder) - tether_from = attached_to.tether_holder - - if(tether_from == tether_to) - return - - var/list/tether_effects = apply_tether(tether_from, tether_to, range = attached_to.range, icon = "wire", always_face = FALSE) - tether_effect = tether_effects["tetherer_tether"] - RegisterSignal(tether_effect, COMSIG_PARENT_QDELETING, PROC_REF(reset_tether)) - -/obj/item/phone/attack_self(mob/user) - ..() - if(raised) - set_raised(FALSE, user) - to_chat(user, SPAN_NOTICE("You lower [src].")) - else - set_raised(TRUE, user) - to_chat(user, SPAN_NOTICE("You raise [src] to your ear.")) - - -/obj/item/phone/proc/set_raised(to_raise, mob/living/carbon/human/H) - if(!istype(H)) - return - - if(!to_raise) - raised = FALSE - item_state = "rpb_phone" - - var/obj/item/device/radio/R = H.get_type_in_ears(/obj/item/device/radio) - R?.on = TRUE - else - raised = TRUE - item_state = "rpb_phone_ear" - - var/obj/item/device/radio/R = H.get_type_in_ears(/obj/item/device/radio) - R?.on = FALSE - - H.update_inv_r_hand() - H.update_inv_l_hand() - -/obj/item/phone/dropped(mob/user) - . = ..() - UnregisterSignal(user, COMSIG_LIVING_SPEAK) - - set_raised(FALSE, user) - -/obj/item/phone/on_enter_storage(obj/item/storage/S) - . = ..() - if(attached_to) - attached_to.recall_phone() - -/obj/item/phone/pickup(mob/user) - . = ..() - RegisterSignal(user, COMSIG_LIVING_SPEAK, PROC_REF(handle_speak)) - -/obj/item/phone/forceMove(atom/dest) - . = ..() - if(.) - reset_tether() - -/obj/item/phone/proc/do_zlevel_check() - if(!attached_to || !loc.z || !attached_to.z) - return FALSE - - if(zlevel_transfer) - if(loc.z == attached_to.z) - zlevel_transfer = FALSE - if(zlevel_transfer_timer) - deltimer(zlevel_transfer_timer) - UnregisterSignal(attached_to, COMSIG_MOVABLE_MOVED) - return FALSE - return TRUE - - if(attached_to && loc.z != attached_to.z) - zlevel_transfer = TRUE - zlevel_transfer_timer = addtimer(CALLBACK(src, PROC_REF(try_doing_tether)), zlevel_transfer_timeout, TIMER_UNIQUE|TIMER_STOPPABLE) - RegisterSignal(attached_to, COMSIG_MOVABLE_MOVED, PROC_REF(transmitter_move_handler)) - return TRUE - return FALSE - -/obj/item/phone/proc/transmitter_move_handler(datum/source) - SIGNAL_HANDLER - zlevel_transfer = FALSE - if(zlevel_transfer_timer) - deltimer(zlevel_transfer_timer) - UnregisterSignal(attached_to, COMSIG_MOVABLE_MOVED) - reset_tether() - -/obj/item/phone/proc/try_doing_tether() - zlevel_transfer_timer = TIMER_ID_NULL - zlevel_transfer = FALSE - UnregisterSignal(attached_to, COMSIG_MOVABLE_MOVED) - reset_tether() +/obj/structure/phone_base/hidden + do_not_disturb = PHONE_DO_NOT_DISTURB_FORCED -/obj/structure/transmitter/no_dnd - do_not_disturb = PHONE_DND_FORBIDDEN +/obj/structure/phone_base/no_dnd + do_not_disturb = PHONE_DO_NOT_DISTURB_FORBIDDEN //rotary desk phones (need a touch tone handset at some point) -/obj/structure/transmitter/rotary +/obj/structure/phone_base/rotary name = "rotary telephone" icon_state = "rotary_phone" desc = "The finger plate is a little stiff." -/obj/structure/transmitter/rotary/no_dnd - do_not_disturb = PHONE_DND_FORBIDDEN +/obj/structure/phone_base/rotary/no_dnd + do_not_disturb = PHONE_DO_NOT_DISTURB_FORBIDDEN -/obj/structure/transmitter/touchtone +/obj/structure/phone_base/touchtone name = "touch-tone telephone" icon_state = "rotary_phone"//placeholder desc = "Ancient aliens, it's all true. I'm an expert just like you!" -/obj/structure/transmitter/colony_net +/obj/structure/phone_base/colony_net networks_receive = list(FACTION_COLONIST) networks_transmit = list(FACTION_COLONIST) -/obj/structure/transmitter/colony_net/rotary +/obj/structure/phone_base/colony_net/rotary name = "rotary telephone" icon_state = "rotary_phone" desc = "The finger plate is a little stiff." -/obj/structure/transmitter/upp_net +/obj/structure/phone_base/upp_net networks_receive = list(FACTION_UPP) networks_transmit = list(FACTION_UPP) -/obj/structure/transmitter/upp_net/rotary +/obj/structure/phone_base/upp_net/rotary name = "rotary telephone" icon_state = "rotary_phone" desc = "The finger plate is a little stiff." -/obj/structure/transmitter/clf_net +/obj/structure/phone_base/clf_net networks_receive = list(FACTION_CLF) networks_transmit = list(FACTION_CLF) -/obj/structure/transmitter/clf_net/rotary +/obj/structure/phone_base/clf_net/rotary name = "rotary telephone" icon_state = "rotary_phone" desc = "The finger plate is a little stiff." -/obj/structure/transmitter/wy_net +/obj/structure/phone_base/wy_net networks_receive = list(FACTION_WY) networks_transmit = list(FACTION_WY) -/obj/structure/transmitter/wy_net/rotary +/obj/structure/phone_base/wy_net/rotary name = "rotary telephone" icon_state = "rotary_phone" desc = "The finger plate is a little stiff." diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index 8cd5b148a1..fc62c076c7 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -65,6 +65,9 @@ if(!src.client) //Somehow return + if(SEND_SIGNAL(src, COMSIG_DEAD_SPEAK, message) & COMPONENT_OVERRIDE_DEAD_SPEAK) + return + if(!src.client.admin_holder || !(client.admin_holder.rights & R_MOD)) if(!dsay_allowed) to_chat(src, SPAN_DANGER("Deadchat is globally muted")) diff --git a/code/modules/vehicles/interior/interior_landmarks.dm b/code/modules/vehicles/interior/interior_landmarks.dm index 90284682d2..eb62e50243 100644 --- a/code/modules/vehicles/interior/interior_landmarks.dm +++ b/code/modules/vehicles/interior/interior_landmarks.dm @@ -216,18 +216,18 @@ color = "yellow" /obj/effect/landmark/interior/spawn/telephone/on_load(datum/interior/I) - var/obj/structure/transmitter/Phone = new(loc) - - Phone.icon = icon - Phone.icon_state = icon_state - Phone.layer = layer - Phone.setDir(dir) - Phone.alpha = alpha - Phone.update_icon() - Phone.pixel_x = pixel_x - Phone.pixel_y = pixel_y - Phone.phone_category = "Vehicles" - Phone.phone_id = I.exterior.name + var/obj/structure/phone_base/phone = new(loc) + + phone.icon = icon + phone.icon_state = icon_state + phone.layer = layer + phone.setDir(dir) + phone.alpha = alpha + phone.update_icon() + phone.pixel_x = pixel_x + phone.pixel_y = pixel_y + phone.phone_category = "Vehicles" + phone.phone_id = I.exterior.name qdel(src) diff --git a/colonialmarines.dme b/colonialmarines.dme index 5228c4e0dd..2a7e598d3c 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -388,6 +388,7 @@ s// DM Environment file for colonialmarines.dme. #include "code\datums\components\label.dm" #include "code\datums\components\orbiter.dm" #include "code\datums\components\overlay_lighting.dm" +#include "code\datums\components\phone.dm" #include "code\datums\components\rename.dm" #include "code\datums\components\speed_modifier.dm" #include "code\datums\components\toxin_buildup.dm" @@ -1585,6 +1586,7 @@ s// DM Environment file for colonialmarines.dme. #include "code\modules\cm_marines\equipment\weapons.dm" #include "code\modules\cm_marines\equipment\mortar\mortar_shells.dm" #include "code\modules\cm_marines\equipment\mortar\mortars.dm" +#include "code\modules\cm_phone\handset.dm" #include "code\modules\cm_phone\internal_phone.dm" #include "code\modules\cm_phone\phone.dm" #include "code\modules\cm_preds\_yaut_defines.dm" diff --git a/maps/map_files/generic/Admin_level.dmm b/maps/map_files/generic/Admin_level.dmm index 43b3d26ec3..88182faf3b 100644 --- a/maps/map_files/generic/Admin_level.dmm +++ b/maps/map_files/generic/Admin_level.dmm @@ -662,7 +662,7 @@ /turf/open/space/transit/east/shuttlespace_ew8, /area/space) "qu" = ( -/obj/structure/transmitter/hidden{ +/obj/structure/phone_base/hidden{ dir = 8; name = "Station Telephone"; phone_id = "Unknown Signal"; diff --git a/tgui/packages/tgui/interfaces/PhoneMenu.js b/tgui/packages/tgui/interfaces/PhoneMenu.js index 9a2edf9437..1528ccd069 100644 --- a/tgui/packages/tgui/interfaces/PhoneMenu.js +++ b/tgui/packages/tgui/interfaces/PhoneMenu.js @@ -15,10 +15,10 @@ export const PhoneMenu = (props, context) => { const GeneralPanel = (props, context) => { const { act, data } = useBackend(context); - const { availability } = data; - const available_transmitters = Object.keys(data.available_transmitters); - const transmitters = data.transmitters.filter((val1) => - available_transmitters.includes(val1.phone_id) + const { do_not_disturb } = data; + const available_phones = Object.keys(data.available_phones); + const phones = data.phones.filter((val1) => + available_phones.includes(val1.phone_id) ); const [currentSearch, setSearch] = useLocalState( @@ -34,8 +34,8 @@ const GeneralPanel = (props, context) => { ); const categories = []; - for (let i = 0; i < transmitters.length; i++) { - let data = transmitters[i]; + for (let i = 0; i < phones.length; i++) { + let data = phones[i]; if (categories.includes(data.phone_category)) continue; categories.push(data.phone_category); @@ -50,14 +50,14 @@ const GeneralPanel = (props, context) => { let dnd_tooltip = 'Do Not Disturb is DISABLED'; let dnd_locked = 'No'; let dnd_icon = 'volume-high'; - if (availability === 1) { + if (do_not_disturb === 1) { dnd_tooltip = 'Do Not Disturb is ENABLED'; dnd_icon = 'volume-xmark'; - } else if (availability >= 2) { + } else if (do_not_disturb >= 2) { dnd_tooltip = 'Do Not Disturb is ENABLED (LOCKED)'; dnd_locked = 'Yes'; dnd_icon = 'volume-xmark'; - } else if (availability < 0) { + } else if (do_not_disturb < 0) { dnd_tooltip = 'Do Not Disturb is DISABLED (LOCKED)'; dnd_locked = 'Yes'; } @@ -88,7 +88,7 @@ const GeneralPanel = (props, context) => {
node.focus()}> - {transmitters.map((val) => { + {phones.map((val) => { if ( val.phone_category !== currentCategory || !val.phone_id.toLowerCase().match(currentSearch) @@ -140,9 +140,21 @@ const GeneralPanel = (props, context) => { icon={dnd_icon} fluid textAlign="center" - onClick={() => act('toggle_dnd')} + onClick={() => act('toggle_do_not_disturb')} /> + {data.virtual_phone && ( + +
); From d0835791aa104b000e7516ef501f7c8f40113138 Mon Sep 17 00:00:00 2001 From: Morrow Date: Tue, 24 Oct 2023 23:39:27 -0400 Subject: [PATCH 02/10] Oh and this --- code/modules/cm_phone/phone.dm | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/code/modules/cm_phone/phone.dm b/code/modules/cm_phone/phone.dm index 0aace05493..e0e00c394d 100644 --- a/code/modules/cm_phone/phone.dm +++ b/code/modules/cm_phone/phone.dm @@ -12,23 +12,18 @@ /// Whether or not the phone is receiving calls or not. Varies between on/off or forcibly on/off. var/do_not_disturb = PHONE_DO_NOT_DISTURB_OFF - var/base_icon_state - var/list/networks_receive = list(FACTION_MARINE) // pass these to component, plus that shit above - Morrow var/list/networks_transmit = list(FACTION_MARINE) /obj/structure/phone_base/Initialize(mapload, ...) . = ..() - base_icon_state = icon_state - - update_icon() AddComponent(/datum/component/phone, phone_category, phone_color, phone_id, phone_icon) // this needs a specific handling on the component level - Morrow -/obj/structure/phone_base/update_icon() +///obj/structure/phone_base/update_icon() . = ..() - SEND_SIGNAL(src, COMSIG_TRANSMITTER_UPDATE_ICON) + //if(attached_to.loc != src) // icon_state = "[base_icon_state]_ear" // return @@ -43,6 +38,8 @@ networks_transmit = null return ..() + + /obj/structure/phone_base/hidden do_not_disturb = PHONE_DO_NOT_DISTURB_FORCED From ac000f6a641d0bbbfa81faa05d3c6d90ff42c1a5 Mon Sep 17 00:00:00 2001 From: Morrow Date: Wed, 25 Oct 2023 16:15:46 -0400 Subject: [PATCH 03/10] Regular phone functionality complete --- .../signals/atom/mob/living/signals_human.dm | 2 +- .../dcs/signals/atom/signals_turf.dm | 2 +- code/_onclick/human.dm | 2 +- code/datums/components/phone.dm | 131 ++++++++++++------ code/datums/looping_sounds/item_sounds.dm | 8 ++ code/game/turfs/walls/wall_types.dm | 2 +- code/modules/cm_aliens/XenoStructures.dm | 2 +- .../cm_phone/{phone.dm => phone_base.dm} | 39 ++++-- colonialmarines.dme | 2 +- 9 files changed, 125 insertions(+), 65 deletions(-) rename code/modules/cm_phone/{phone.dm => phone_base.dm} (70%) diff --git a/code/__DEFINES/dcs/signals/atom/mob/living/signals_human.dm b/code/__DEFINES/dcs/signals/atom/mob/living/signals_human.dm index ed1ac4a5bb..1d7a727232 100644 --- a/code/__DEFINES/dcs/signals/atom/mob/living/signals_human.dm +++ b/code/__DEFINES/dcs/signals/atom/mob/living/signals_human.dm @@ -70,4 +70,4 @@ /// From /mob/living/carbon/human/UnarmedAttack() #define COMSIG_HUMAN_BEFORE_ATTACK_HAND "human_before_attack_hand" - #define COMPONENT_CANCEL_ATTACK_HAND (1<<0) + #define COMPONENT_CANCEL_HUMAN_ATTACK_HAND (1<<0) diff --git a/code/__DEFINES/dcs/signals/atom/signals_turf.dm b/code/__DEFINES/dcs/signals/atom/signals_turf.dm index 6a0788bcf8..b59e9d60b4 100644 --- a/code/__DEFINES/dcs/signals/atom/signals_turf.dm +++ b/code/__DEFINES/dcs/signals/atom/signals_turf.dm @@ -15,7 +15,7 @@ /// From /turf/closed/wall/resin/attackby(): (obj/item/I, mob/M) #define COMSIG_WALL_RESIN_ATTACKBY "wall_resin_attackby" - #define COMPONENT_CANCEL_ATTACKBY (1<<0) + #define COMPONENT_CANCEL_RESIN_ATTACKBY (1<<0) ///from /turf/closed/wall/proc/place_poster #define COMSIG_POSTER_PLACED "poster_placed" diff --git a/code/_onclick/human.dm b/code/_onclick/human.dm index 74e3261650..f5c0a98afd 100644 --- a/code/_onclick/human.dm +++ b/code/_onclick/human.dm @@ -80,7 +80,7 @@ to_chat(src, SPAN_NOTICE("You try to move your [temp.display_name], but cannot!")) return - if(SEND_SIGNAL(A, COMSIG_ATOM_HUMAN_ATTACK_HAND, src) & COMPONENT_CANCEL_ATTACK_HAND) + if(SEND_SIGNAL(A, COMSIG_ATOM_HUMAN_ATTACK_HAND, src) & COMPONENT_CANCEL_HUMAN_ATTACK_HAND) return A.attack_hand(src, click_parameters) diff --git a/code/datums/components/phone.dm b/code/datums/components/phone.dm index 7a1ce44491..ce21ad0cd0 100644 --- a/code/datums/components/phone.dm +++ b/code/datums/components/phone.dm @@ -25,9 +25,6 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) /// A phone we are calling or has called us var/datum/component/phone/calling_phone - /// Range of our handset - var/range = 7 - /// Whether or not the phone is receiving calls or not. Varies between on/off or forcibly on/off. var/do_not_disturb = PHONE_DO_NOT_DISTURB_OFF @@ -38,10 +35,12 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) var/timeout_duration = 30 SECONDS /// Networks that this phone can take calls from - var/list/networks_receive = list(FACTION_MARINE) + var/list/networks_receive = list() /// Networks that this phone can call - var/list/networks_transmit = list(FACTION_MARINE) + var/list/networks_transmit = list() + + var/datum/looping_sound/phone_ringing/ringing_loop /datum/component/phone/Initialize(...) . = ..() @@ -49,7 +48,8 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) if(!istype(parent, /atom)) return COMPONENT_INCOMPATIBLE - handle_initial_variables(arglist(args)) + if(!handle_initial_variables(arglist(args))) + return COMPONENT_INCOMPATIBLE GLOB.phones += src @@ -62,30 +62,51 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) phone_handset.phone_component = null phone_handset = null + networks_receive = null + networks_transmit = null + QDEL_NULL(ringing_loop) + GLOB.phones -= src SStgui.close_uis(src) reset_call() return ..() -/datum/component/phone/proc/handle_initial_variables(phone_category, phone_color, phone_id, phone_icon, holder) - src.phone_category = phone_category - src.phone_color = phone_color - src.phone_id = phone_id - src.phone_icon = phone_icon +/// Handles all of our variables usually set in Initialize(), needs to be a proc so virtual phones don't get incorrect signals or a handset +/datum/component/phone/proc/handle_initial_variables(phone_category, phone_color, phone_id, phone_icon, do_not_disturb, networks_receive, networks_transmit, holder) + src.phone_category = isnull(phone_category) ? src.phone_category : phone_category + src.phone_color = isnull(phone_color) ? src.phone_color : phone_color + src.phone_id = isnull(phone_id) ? src.phone_id : phone_id + src.phone_icon = isnull(phone_icon) ? src.phone_icon : phone_icon + src.do_not_disturb = isnull(do_not_disturb) ? src.do_not_disturb : do_not_disturb + src.networks_receive = isnull(networks_receive) ? src.networks_receive : networks_receive.Copy() + src.networks_transmit = isnull(networks_transmit) ? src.networks_transmit : networks_transmit.Copy() src.holder = holder ? holder : parent phone_handset = new(src.holder, src, src.holder) RegisterSignal(phone_handset, COMSIG_PARENT_PREQDELETED, PROC_REF(override_delete)) - RegisterSignal(src.holder, COMSIG_ATOM_HUMAN_ATTACK_HAND, PROC_REF(use_phone)) RegisterSignal(src.holder, COMSIG_ATOM_MOB_ATTACKBY, PROC_REF(item_used_on_phone)) + RegisterSignal(src.holder, COMSIG_ATOM_HUMAN_ATTACK_HAND, PROC_REF(use_phone)) + + ringing_loop = new(src.holder) + return TRUE + +/// Handles bringing our handset back in case something tries to delete it /datum/component/phone/proc/override_delete() SIGNAL_HANDLER recall_handset() return COMPONENT_ABORT_QDEL +/// Handles any attackbys on our holder so we can hang up the phone +/datum/component/phone/proc/item_used_on_phone(atom/phone, obj/item/attacking_item, mob/user) + SIGNAL_HANDLER + + if(attacking_item == phone_handset) + recall_handset() + return COMPONENT_CANCEL_ATTACKBY + /// When we initially interact with the phone, whether opening the menu to call someone or picking up the phone being called /datum/component/phone/proc/use_phone(atom/phone, mob/living/carbon/human/user) SIGNAL_HANDLER @@ -103,13 +124,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) picked_up_call(user) calling_phone.other_phone_picked_up_call() -/datum/component/phone/proc/item_used_on_phone(atom/phone, obj/item/attacking_item, mob/user) - SIGNAL_HANDLER - - if(attacking_item == phone_handset) - recall_handset() - return COMPONENT_CANCEL_ATTACKBY - +/// Handles what we want to do when we pick up a phone /datum/component/phone/proc/picked_up_call(mob/living/carbon/human/user) to_chat(user, SPAN_PURPLE("[icon2html(holder, user)] Picked up a call from [calling_phone.phone_id].")) playsound(get_turf(user), "rtb_handset") @@ -117,6 +132,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) user.put_in_active_hand(phone_handset) SEND_SIGNAL(holder, COMSIG_ATOM_PHONE_PICKED_UP) +/// Handles what we want to do when a phone we are calling picks up /datum/component/phone/proc/other_phone_picked_up_call() if(!calling_phone) return @@ -134,6 +150,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) var/mob/phone_user = phone_handset.loc to_chat(phone_user, SPAN_PURPLE("[icon2html(calling_phone.holder, phone_user)] [calling_phone.phone_id] has picked up.")) +/// Gathers all phones that we can call from our phone, returns a list of those phones /datum/component/phone/proc/get_phones() var/list/phone_list = list() @@ -162,6 +179,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) return phone_list +/// Whether or not our phone is available to be called from other phones, returns TRUE if callable, otherwise FALSE. Note: this does not account for network compatability /datum/component/phone/proc/phone_available() if(calling_phone) return FALSE @@ -180,6 +198,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) return TRUE +/// Whether or not clicking on our phone will bring up the phone menu, returns TRUE if it will, otherwise FALSE /datum/component/phone/proc/phone_menu_usable() if(calling_phone) return FALSE @@ -192,6 +211,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) return TRUE +/// Starts calling another phone, sets up connection between the phones /datum/component/phone/proc/call_phone(mob/user, calling_phone_id) var/list/phones = get_phones() phones -= phone_id @@ -209,14 +229,17 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) calling_phone = null return - calling_phone.calling_phone = src - SEND_SIGNAL(calling_phone.holder, COMSIG_ATOM_PHONE_RINGING) + calling_phone.getting_call(src) post_call_phone(user, calling_phone_id) - //START_PROCESSING(SSobj, src) - handle ringing - Morrow - //START_PROCESSING(SSobj, T) +/// What we do when our phone is receiving a call, called from incoming_call's call_phone() +/datum/component/phone/proc/getting_call(datum/component/phone/incoming_call) + calling_phone = incoming_call + SEND_SIGNAL(holder, COMSIG_ATOM_PHONE_RINGING) + ringing_loop.start() +/// What we do after our call is set up from call_phone() /datum/component/phone/proc/post_call_phone(mob/user, calling_phone_id) to_chat(user, SPAN_PURPLE("[icon2html(holder, user)] Dialing [calling_phone_id]..")) timeout_timer_id = addtimer(CALLBACK(src, PROC_REF(reset_call), TRUE), timeout_duration, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE) @@ -225,18 +248,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) user.put_in_active_hand(phone_handset) SEND_SIGNAL(holder, COMSIG_ATOM_PHONE_PICKED_UP) -/datum/component/phone/proc/toggle_do_not_disturb(mob/user) - switch(do_not_disturb) - if(PHONE_DO_NOT_DISTURB_ON) - do_not_disturb = PHONE_DO_NOT_DISTURB_OFF - to_chat(user, SPAN_NOTICE("Do Not Disturb has been disabled. You can now receive calls.")) - if(PHONE_DO_NOT_DISTURB_OFF) - do_not_disturb = PHONE_DO_NOT_DISTURB_ON - to_chat(user, SPAN_WARNING("Do Not Disturb has been enabled. No calls will be received.")) - else - return FALSE - return TRUE - +/// Resets this phone's connection as well as anything we are connected to's connection, calls itself on any other connections /datum/component/phone/proc/reset_call(timeout = FALSE, recursed = FALSE) if(timeout_timer_id) deltimer(timeout_timer_id) @@ -248,14 +260,15 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) if(!recursed) calling_phone.reset_call(timeout, recursed = TRUE) - SEND_SIGNAL(calling_phone.holder, COMSIG_ATOM_PHONE_STOPPED_RINGING) + SEND_SIGNAL(holder, COMSIG_ATOM_PHONE_STOPPED_RINGING) - //STOP_PROCESSING(SSobj, T) - Stop ringing - Morrow + ringing_loop.stop() handle_reset_call_message(timeout, recursed) calling_phone = null +/// Handles any messaging we want when a call is reset /datum/component/phone/proc/handle_reset_call_message(timeout = FALSE, recursed = FALSE) if(!phone_handset) return @@ -271,6 +284,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) else to_chat(handset_user, SPAN_PURPLE("[icon2html(holder, handset_user)] You have hung up on [calling_phone.phone_id].")) +/// Recalls our handset back to holder and calls reset_call() /datum/component/phone/proc/recall_handset() if(ismob(phone_handset.loc)) var/mob/M = phone_handset.loc @@ -280,8 +294,9 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) phone_handset.forceMove(holder) reset_call() - SEND_SIGNAL(calling_phone.holder, COMSIG_ATOM_PHONE_HUNG_UP) + SEND_SIGNAL(holder, COMSIG_ATOM_PHONE_HUNG_UP) +/// Handles any messages that our handset 'hears' and passes to us. Passes the message to this phone and any connected phone via handle_hear() /datum/component/phone/proc/handle_speak(message, datum/language/message_language, mob/speaker, direct_talking = TRUE) if(message_language.flags & SIGNLANG) return @@ -291,12 +306,13 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) if(direct_talking) handle_hear(message, message_language, speaker, direct_talking) + log_say("TELEPHONE: [key_name(speaker)] on Phone '[phone_id]' to '[calling_phone.phone_id]' said '[message]'") calling_phone.handle_hear(message, message_language, speaker, direct_talking) - log_say("TELEPHONE: [key_name(speaker)] [direct_talking ? "" : "was picked up "]on Phone '[phone_id]' to '[calling_phone.phone_id]' said '[message]'") // Add dchat listen in because it's funny, check radio preferences first, oh and don't do the background stuff - Morrow +/// Handles any messages passed from handle_speak() and serves them to the user /datum/component/phone/proc/handle_hear(message, datum/language/message_language, mob/speaker, direct_talking) if(!phone_handset) return @@ -319,7 +335,20 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) hearing_mob.hear_radio(message, "says", message_language, part_a = "", part_b = " ", vname = name_override, speaker = speaker, command = loudness, no_paygrade = TRUE) -///datum/component/phone/proc/set_tether_holder(atom/A) - Do something with this, likely need to have a signal for if the parent is moving - Morrow +/// Toggles do not disturb on or off, does not handle forced or unable do_not_disturb variables +/datum/component/phone/proc/toggle_do_not_disturb(mob/user) + switch(do_not_disturb) + if(PHONE_DO_NOT_DISTURB_ON) + do_not_disturb = PHONE_DO_NOT_DISTURB_OFF + to_chat(user, SPAN_NOTICE("Do Not Disturb has been disabled. You can now receive calls.")) + if(PHONE_DO_NOT_DISTURB_OFF) + do_not_disturb = PHONE_DO_NOT_DISTURB_ON + to_chat(user, SPAN_WARNING("Do Not Disturb has been enabled. No calls will be received.")) + else + return FALSE + return TRUE + +///datum/component/phone/proc/set_tether_holder(atom/A) - Do something with this, likely need to have a signal for if the parent is moving? - Morrow // tether_holder = A // // if(phone_handset) @@ -390,14 +419,22 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) return ..() -/datum/component/phone/virtual/handle_initial_variables(phone_category, phone_color, phone_id, phone_icon, holder, virtual_user) - src.phone_category = phone_category - src.phone_color = phone_color - src.phone_id = phone_id - src.phone_icon = phone_icon +/datum/component/phone/virtual/handle_initial_variables(phone_category, phone_color, phone_id, phone_icon, do_not_disturb, networks_receive, networks_transmit, holder, virtual_user) + src.phone_category = isnull(phone_category) ? src.phone_category : phone_category + src.phone_color = isnull(phone_color) ? src.phone_color : phone_color + src.phone_id = isnull(phone_id) ? src.phone_id : phone_id + src.phone_icon = isnull(phone_icon) ? src.phone_icon : phone_icon + src.do_not_disturb = isnull(do_not_disturb) ? src.do_not_disturb : do_not_disturb + src.networks_receive = isnull(networks_receive) ? src.networks_receive : networks_receive.Copy() + src.networks_transmit = isnull(networks_transmit) ? src.networks_transmit : networks_transmit.Copy() src.holder = holder ? holder : parent + + if(!virtual_user) + return FALSE src.virtual_user = virtual_user + return TRUE + /datum/component/phone/virtual/picked_up_call(mob/living/carbon/human/user) to_chat(user, SPAN_PURPLE("[icon2html(src, user)] Picked up a call from [calling_phone.phone_id].")) @@ -431,6 +468,10 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) else to_chat(virtual_user, SPAN_PURPLE("[icon2html(holder, virtual_user)] You have hung up on [calling_phone.phone_id].")) +/datum/component/phone/virtual/getting_call(datum/component/phone/incoming_call) + calling_phone = incoming_call + SEND_SIGNAL(holder, COMSIG_ATOM_PHONE_RINGING) + /datum/component/phone/virtual/post_call_phone(mob/user, calling_phone_id) to_chat(user, SPAN_PURPLE("[icon2html(holder, user)] Dialing [calling_phone_id]..")) timeout_timer_id = addtimer(CALLBACK(src, PROC_REF(reset_call), TRUE), timeout_duration, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE) diff --git a/code/datums/looping_sounds/item_sounds.dm b/code/datums/looping_sounds/item_sounds.dm index a2aa2fb5b6..5382ad2f42 100644 --- a/code/datums/looping_sounds/item_sounds.dm +++ b/code/datums/looping_sounds/item_sounds.dm @@ -2,3 +2,11 @@ mid_sounds = list('sound/items/taperecorder/taperecorder_hiss_mid.ogg' = 1) start_sound = list('sound/items/taperecorder/taperecorder_hiss_start.ogg' = 1) volume = 10 + +/datum/looping_sound/phone_ringing + start_sound = list('sound/machines/telephone/telephone_ring.ogg' = 1) + mid_sounds = list('sound/machines/telephone/telephone_ring.ogg' = 1) + volume = 25 + extra_range = 14 + mid_length = (3 SECONDS) + max_loops = 10 diff --git a/code/game/turfs/walls/wall_types.dm b/code/game/turfs/walls/wall_types.dm index 22979858ce..d968b8d72f 100644 --- a/code/game/turfs/walls/wall_types.dm +++ b/code/game/turfs/walls/wall_types.dm @@ -1219,7 +1219,7 @@ INITIALIZE_IMMEDIATE(/turf/closed/wall/indestructible/splashscreen) to_chat(user, SPAN_WARNING("You scrape ineffectively at \the [src].")) /turf/closed/wall/resin/attackby(obj/item/W, mob/living/user) - if(SEND_SIGNAL(src, COMSIG_WALL_RESIN_ATTACKBY, W, user) & COMPONENT_CANCEL_ATTACKBY) + if(SEND_SIGNAL(src, COMSIG_WALL_RESIN_ATTACKBY, W, user) & COMPONENT_CANCEL_RESIN_ATTACKBY) return if(!(W.flags_item & NOBLUDGEON)) diff --git a/code/modules/cm_aliens/XenoStructures.dm b/code/modules/cm_aliens/XenoStructures.dm index 73ced80994..b1fe57d55d 100644 --- a/code/modules/cm_aliens/XenoStructures.dm +++ b/code/modules/cm_aliens/XenoStructures.dm @@ -752,7 +752,7 @@ /obj/effect/alien/resin/resin_pillar/proc/handle_attackby(turf/T, obj/item/I, mob/M) SIGNAL_HANDLER attackby(I, M) - return COMPONENT_CANCEL_ATTACKBY + return COMPONENT_CANCEL_RESIN_ATTACKBY /obj/effect/alien/resin/resin_pillar/proc/handle_hitby(turf/T, atom/movable/AM) SIGNAL_HANDLER diff --git a/code/modules/cm_phone/phone.dm b/code/modules/cm_phone/phone_base.dm similarity index 70% rename from code/modules/cm_phone/phone.dm rename to code/modules/cm_phone/phone_base.dm index e0e00c394d..0048389d3e 100644 --- a/code/modules/cm_phone/phone.dm +++ b/code/modules/cm_phone/phone_base.dm @@ -18,27 +18,38 @@ /obj/structure/phone_base/Initialize(mapload, ...) . = ..() - AddComponent(/datum/component/phone, phone_category, phone_color, phone_id, phone_icon) - -// this needs a specific handling on the component level - Morrow -///obj/structure/phone_base/update_icon() - . = ..() - - //if(attached_to.loc != src) - // icon_state = "[base_icon_state]_ear" - // return - - //if(caller) - // icon_state = "[base_icon_state]_ring" - //else - // icon_state = base_icon_state + AddComponent(/datum/component/phone, phone_category, phone_color, phone_id, phone_icon, do_not_disturb, networks_receive, networks_transmit) + RegisterSignal(src, COMSIG_ATOM_PHONE_PICKED_UP, PROC_REF(phone_picked_up)) + RegisterSignal(src, COMSIG_ATOM_PHONE_HUNG_UP, PROC_REF(phone_hung_up)) + RegisterSignal(src, COMSIG_ATOM_PHONE_RINGING, PROC_REF(phone_ringing)) + RegisterSignal(src, COMSIG_ATOM_PHONE_STOPPED_RINGING, PROC_REF(phone_stopped_ringing)) /obj/structure/phone_base/Destroy() networks_receive = null networks_transmit = null return ..() +#define PHONE_ON_BASE_UNIT_ICON_STATE "[initial(icon_state)]" +#define PHONE_OFF_BASE_UNIT_ICON_STATE "[initial(icon_state)]_ear" +#define PHONE_RINGING_ICON_STATE "[initial(icon_state)]_ring" + +/obj/structure/phone_base/proc/phone_picked_up() + icon_state = PHONE_OFF_BASE_UNIT_ICON_STATE + +/obj/structure/phone_base/proc/phone_hung_up() + icon_state = PHONE_ON_BASE_UNIT_ICON_STATE + +/obj/structure/phone_base/proc/phone_ringing() + icon_state = PHONE_RINGING_ICON_STATE + +/obj/structure/phone_base/proc/phone_stopped_ringing() + if(icon_state == PHONE_OFF_BASE_UNIT_ICON_STATE) + return + icon_state = PHONE_ON_BASE_UNIT_ICON_STATE +#undef PHONE_ON_BASE_UNIT_ICON_STATE +#undef PHONE_OFF_BASE_UNIT_ICON_STATE +#undef PHONE_RINGING_ICON_STATE /obj/structure/phone_base/hidden do_not_disturb = PHONE_DO_NOT_DISTURB_FORCED diff --git a/colonialmarines.dme b/colonialmarines.dme index 2a7e598d3c..2e638847ad 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -1588,7 +1588,7 @@ s// DM Environment file for colonialmarines.dme. #include "code\modules\cm_marines\equipment\mortar\mortars.dm" #include "code\modules\cm_phone\handset.dm" #include "code\modules\cm_phone\internal_phone.dm" -#include "code\modules\cm_phone\phone.dm" +#include "code\modules\cm_phone\phone_base.dm" #include "code\modules\cm_preds\_yaut_defines.dm" #include "code\modules\cm_preds\falcon.dm" #include "code\modules\cm_preds\huntdata.dm" From db169e46fa073b8eebebd6b2e2f3cea759ffd459 Mon Sep 17 00:00:00 2001 From: Morrow Date: Wed, 25 Oct 2023 20:18:28 -0400 Subject: [PATCH 04/10] radio backpacks (shoot me) --- .../dcs/signals/atom/signals_movable.dm | 5 + code/__DEFINES/equipment.dm | 4 + code/_onclick/human.dm | 2 +- code/datums/components/phone.dm | 87 ++++++++++++--- code/game/objects/items/storage/backpack.dm | 105 +++--------------- code/modules/cm_phone/handset.dm | 27 ++--- code/modules/cm_phone/internal_phone.dm | 15 --- code/modules/cm_phone/phone_base.dm | 8 -- code/modules/movement/movement.dm | 3 + colonialmarines.dme | 1 - 10 files changed, 112 insertions(+), 145 deletions(-) delete mode 100644 code/modules/cm_phone/internal_phone.dm diff --git a/code/__DEFINES/dcs/signals/atom/signals_movable.dm b/code/__DEFINES/dcs/signals/atom/signals_movable.dm index ba889d0b52..923c2cc60f 100644 --- a/code/__DEFINES/dcs/signals/atom/signals_movable.dm +++ b/code/__DEFINES/dcs/signals/atom/signals_movable.dm @@ -4,11 +4,15 @@ /// From /atom/movable/proc/launch_towards #define COMSIG_MOVABLE_PRE_THROW "movable_pre_throw" #define COMPONENT_CANCEL_THROW (1<<0) + ///from base of atom/movable/Moved(): (/atom, dir, forced) #define COMSIG_MOVABLE_MOVED "movable_moved" /// From /atom/movable/Move(): (atom/NewLoc) #define COMSIG_MOVABLE_PRE_MOVE "movable_pre_move" #define COMPONENT_CANCEL_MOVE (1<<0) +/// From /atom/movable/proc/forceMove(): (atom/NewLoc) +#define COMSIG_MOVABLE_FORCEMOVED "movable_forcemove" + /// From /turf/open/gm/river/Entered(): (turf/open/gm/river/river, covered) #define COMSIG_MOVABLE_ENTERED_RIVER "movable_entered_river" @@ -29,3 +33,4 @@ #define COMSIG_MOVABLE_UPDATE_GLIDE_SIZE "movable_glide_size" #define COMSIG_MOVABLE_TURF_ENTER "movable_turf_enter" + diff --git a/code/__DEFINES/equipment.dm b/code/__DEFINES/equipment.dm index 3c6cefe5bc..96c0fc3738 100644 --- a/code/__DEFINES/equipment.dm +++ b/code/__DEFINES/equipment.dm @@ -556,3 +556,7 @@ var/global/list/uniform_categories = list( #define PHONE_DO_NOT_DISTURB_ON 1 #define PHONE_DO_NOT_DISTURB_OFF 0 #define PHONE_DO_NOT_DISTURB_FORBIDDEN -1 + +#define PHONE_ON_BASE_UNIT_ICON_STATE "[initial(icon_state)]" +#define PHONE_OFF_BASE_UNIT_ICON_STATE "[initial(icon_state)]_ear" +#define PHONE_RINGING_ICON_STATE "[initial(icon_state)]_ring" diff --git a/code/_onclick/human.dm b/code/_onclick/human.dm index f5c0a98afd..c7abc023a6 100644 --- a/code/_onclick/human.dm +++ b/code/_onclick/human.dm @@ -80,7 +80,7 @@ to_chat(src, SPAN_NOTICE("You try to move your [temp.display_name], but cannot!")) return - if(SEND_SIGNAL(A, COMSIG_ATOM_HUMAN_ATTACK_HAND, src) & COMPONENT_CANCEL_HUMAN_ATTACK_HAND) + if(SEND_SIGNAL(A, COMSIG_ATOM_HUMAN_ATTACK_HAND, src, click_parameters) & COMPONENT_CANCEL_HUMAN_ATTACK_HAND) return A.attack_hand(src, click_parameters) diff --git a/code/datums/components/phone.dm b/code/datums/components/phone.dm index ce21ad0cd0..e279c5af0c 100644 --- a/code/datums/components/phone.dm +++ b/code/datums/components/phone.dm @@ -40,9 +40,13 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) /// Networks that this phone can call var/list/networks_transmit = list() + /// The looping ringing sound when the phone is called var/datum/looping_sound/phone_ringing/ringing_loop -/datum/component/phone/Initialize(...) + /// Whether the phone is able to be called or not + var/enabled = TRUE + +/datum/component/phone/Initialize(phone_category, phone_color, phone_id, phone_icon, do_not_disturb, list/networks_receive, list/networks_transmit, holder) . = ..() if(!istype(parent, /atom)) @@ -55,7 +59,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) /datum/component/phone/Destroy() if(phone_handset) - if(phone_handset.loc == src) + if(!phone_handset.loc) UnregisterSignal(phone_handset, COMSIG_PARENT_PREQDELETED) qdel(phone_handset) else @@ -73,7 +77,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) return ..() /// Handles all of our variables usually set in Initialize(), needs to be a proc so virtual phones don't get incorrect signals or a handset -/datum/component/phone/proc/handle_initial_variables(phone_category, phone_color, phone_id, phone_icon, do_not_disturb, networks_receive, networks_transmit, holder) +/datum/component/phone/proc/handle_initial_variables(phone_category, phone_color, phone_id, phone_icon, do_not_disturb, list/networks_receive, list/networks_transmit, holder) src.phone_category = isnull(phone_category) ? src.phone_category : phone_category src.phone_color = isnull(phone_color) ? src.phone_color : phone_color src.phone_id = isnull(phone_id) ? src.phone_id : phone_id @@ -83,12 +87,19 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) src.networks_transmit = isnull(networks_transmit) ? src.networks_transmit : networks_transmit.Copy() src.holder = holder ? holder : parent - phone_handset = new(src.holder, src, src.holder) + phone_handset = new(null, src, src.holder) RegisterSignal(phone_handset, COMSIG_PARENT_PREQDELETED, PROC_REF(override_delete)) RegisterSignal(src.holder, COMSIG_ATOM_MOB_ATTACKBY, PROC_REF(item_used_on_phone)) RegisterSignal(src.holder, COMSIG_ATOM_HUMAN_ATTACK_HAND, PROC_REF(use_phone)) + if(istype(src.holder, /obj/item)) + RegisterSignal(src.holder, COMSIG_ITEM_PICKUP, PROC_REF(holder_picked_up)) + RegisterSignal(src.holder, COMSIG_ITEM_DROPPED, PROC_REF(holder_dropped)) + enabled = FALSE + + RegisterSignal(src.holder, COMSIG_MOVABLE_FORCEMOVED, PROC_REF(holder_forcemoved)) + ringing_loop = new(src.holder) return TRUE @@ -108,22 +119,27 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) return COMPONENT_CANCEL_ATTACKBY /// When we initially interact with the phone, whether opening the menu to call someone or picking up the phone being called -/datum/component/phone/proc/use_phone(atom/phone, mob/living/carbon/human/user) +/datum/component/phone/proc/use_phone(atom/phone, mob/living/carbon/human/user, click_parameters) SIGNAL_HANDLER if(!calling_phone) INVOKE_ASYNC(src, PROC_REF(tgui_interact), user) + + if(enabled) + return COMPONENT_CANCEL_HUMAN_ATTACK_HAND return if(!phone_handset) return - if(phone_handset.loc != holder) + if(phone_handset.loc) return picked_up_call(user) calling_phone.other_phone_picked_up_call() + return COMPONENT_CANCEL_HUMAN_ATTACK_HAND + /// Handles what we want to do when we pick up a phone /datum/component/phone/proc/picked_up_call(mob/living/carbon/human/user) to_chat(user, SPAN_PURPLE("[icon2html(holder, user)] Picked up a call from [calling_phone.phone_id].")) @@ -131,6 +147,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) user.put_in_active_hand(phone_handset) SEND_SIGNAL(holder, COMSIG_ATOM_PHONE_PICKED_UP) + ringing_loop.stop() /// Handles what we want to do when a phone we are calling picks up /datum/component/phone/proc/other_phone_picked_up_call() @@ -150,6 +167,43 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) var/mob/phone_user = phone_handset.loc to_chat(phone_user, SPAN_PURPLE("[icon2html(calling_phone.holder, phone_user)] [calling_phone.phone_id] has picked up.")) +/// Handles setting a specific phone ID and enabling the phone when the holder is picked up +/datum/component/phone/proc/holder_picked_up(obj/item/picked_up_holder, mob/user) + SIGNAL_HANDLER + + enabled = TRUE + + if(!ishuman(user)) + phone_id = "[user]" + return + + var/mob/living/carbon/human/human_user = user + if(human_user.comm_title) + phone_id = "[human_user.comm_title] [human_user]" + else if(human_user.job) + phone_id = "[human_user.job] [human_user]" + else + phone_id = "[human_user]" + + if(human_user.assigned_squad) + phone_id += " ([human_user.assigned_squad.name])" + +/// Handles disabling the phone when the holder is dropped +/datum/component/phone/proc/holder_dropped(obj/item/dropped_hold, mob/user) + SIGNAL_HANDLER + + enabled = FALSE + phone_id = "[holder]" + +/// Tells our phone_handset that the holder has been forcemoved so the tether can be updated if need be +/datum/component/phone/proc/holder_forcemoved(atom/movable/moving_atom, atom/destination) + SIGNAL_HANDLER + + if(!phone_handset) + return + + phone_handset.reset_tether() + /// Gathers all phones that we can call from our phone, returns a list of those phones /datum/component/phone/proc/get_phones() var/list/phone_list = list() @@ -187,7 +241,10 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) if(!phone_handset) return FALSE - if(phone_handset.loc != holder) + if(!enabled) + return FALSE + + if(phone_handset.loc) return FALSE if(do_not_disturb == PHONE_DO_NOT_DISTURB_ON) @@ -206,7 +263,10 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) if(!phone_handset) return FALSE - if(phone_handset.loc != holder) + if(!enabled) + return FALSE + + if(phone_handset.loc) return return TRUE @@ -291,7 +351,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) M.drop_held_item(phone_handset) playsound(get_turf(M), "rtb_handset", 100, FALSE, 7) - phone_handset.forceMove(holder) + phone_handset.moveToNullspace() reset_call() SEND_SIGNAL(holder, COMSIG_ATOM_PHONE_HUNG_UP) @@ -348,13 +408,6 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) return FALSE return TRUE -///datum/component/phone/proc/set_tether_holder(atom/A) - Do something with this, likely need to have a signal for if the parent is moving? - Morrow -// tether_holder = A -// -// if(phone_handset) -// phone_handset.reset_tether() - - //TGUI section @@ -419,7 +472,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) return ..() -/datum/component/phone/virtual/handle_initial_variables(phone_category, phone_color, phone_id, phone_icon, do_not_disturb, networks_receive, networks_transmit, holder, virtual_user) +/datum/component/phone/virtual/handle_initial_variables(phone_category, phone_color, phone_id, phone_icon, do_not_disturb, list/networks_receive, list/networks_transmit, holder, virtual_user) src.phone_category = isnull(phone_category) ? src.phone_category : phone_category src.phone_color = isnull(phone_color) ? src.phone_color : phone_color src.phone_id = isnull(phone_id) ? src.phone_id : phone_id diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index 3e760927fc..95c5f181cd 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -487,115 +487,41 @@ desc = "A heavy-duty chestrig used by some USCM technicians." icon_state = "marinesatch_techi" -GLOBAL_LIST_EMPTY_TYPED(radio_packs, /obj/item/storage/backpack/marine/satchel/rto) - /obj/item/storage/backpack/marine/satchel/rto name = "\improper USCM Radio Telephone Pack" desc = "A heavy-duty pack, used for telecommunications between central command. Commonly carried by RTOs." icon_state = "rto_backpack" item_state = "rto_backpack" has_gamemode_skin = FALSE - actions_types = list(/datum/action/item_action/rto_pack/use_phone) flags_item = ITEM_OVERRIDE_NORTHFACE - //var/obj/structure/transmitter/internal/internal_transmitter - var/phone_category = PHONE_MARINE var/list/networks_receive = list(FACTION_MARINE) var/list/networks_transmit = list(FACTION_MARINE) - var/base_icon - -/datum/action/item_action/rto_pack/use_phone/New(mob/living/user, obj/item/holder) - ..() - name = "Use Phone" - button.name = name - button.overlays.Cut() - var/image/IMG = image('icons/obj/items/misc.dmi', button, "rpb_phone") - button.overlays += IMG - -/datum/action/item_action/rto_pack/use_phone/action_activate() - for(var/obj/item/storage/backpack/marine/satchel/rto/radio_backpack in owner) - radio_backpack.use_phone(owner) - return - -/obj/item/storage/backpack/marine/satchel/rto/post_skin_selection() - base_icon = icon_state /obj/item/storage/backpack/marine/satchel/rto/Initialize() . = ..() - //internal_transmitter = new(src) - //internal_transmitter.relay_obj = src - //internal_transmitter.phone_category = phone_category - //internal_transmitter.enabled = FALSE - //internal_transmitter.networks_receive = networks_receive - //internal_transmitter.networks_transmit = networks_transmit - //RegisterSignal(internal_transmitter, COMSIG_TRANSMITTER_UPDATE_ICON, PROC_REF(check_for_ringing)) - //GLOB.radio_packs += src - -/obj/item/storage/backpack/marine/satchel/rto/proc/check_for_ringing() - SIGNAL_HANDLER - update_icon() - -/obj/item/storage/backpack/marine/satchel/rto/update_icon() - . = ..() - //if(!internal_transmitter) - // return - //if(!internal_transmitter.attached_to \ - // || internal_transmitter.attached_to.loc != internal_transmitter) - // icon_state = "[base_icon]_ear" - // return + AddComponent(/datum/component/phone, phone_category = phone_category, networks_receive = networks_receive, networks_transmit = networks_transmit) + RegisterSignal(src, COMSIG_ATOM_PHONE_PICKED_UP, PROC_REF(phone_picked_up)) + RegisterSignal(src, COMSIG_ATOM_PHONE_HUNG_UP, PROC_REF(phone_hung_up)) + RegisterSignal(src, COMSIG_ATOM_PHONE_RINGING, PROC_REF(phone_ringing)) + RegisterSignal(src, COMSIG_ATOM_PHONE_STOPPED_RINGING, PROC_REF(phone_stopped_ringing)) - //if(internal_transmitter.caller) - // icon_state = "[base_icon]_ring" - //else - // icon_state = base_icon +/obj/item/storage/backpack/marine/satchel/rto/proc/phone_picked_up() + icon_state = PHONE_OFF_BASE_UNIT_ICON_STATE -/obj/item/storage/backpack/marine/satchel/rto/forceMove(atom/dest) - . = ..() - //if(isturf(dest)) - // internal_transmitter.set_tether_holder(src) - //else - // internal_transmitter.set_tether_holder(loc) - Morrow +/obj/item/storage/backpack/marine/satchel/rto/proc/phone_hung_up() + icon_state = PHONE_ON_BASE_UNIT_ICON_STATE -/obj/item/storage/backpack/marine/satchel/rto/Destroy() - GLOB.radio_packs -= src - //qdel(internal_transmitter) - return ..() +/obj/item/storage/backpack/marine/satchel/rto/proc/phone_ringing() + icon_state = PHONE_RINGING_ICON_STATE -/obj/item/storage/backpack/marine/satchel/rto/pickup(mob/user) - . = ..() -// if(ishuman(user)) -// var/mob/living/carbon/human/H = user -// if(H.comm_title) - //internal_transmitter.phone_id = "[H.comm_title] [H]" -// else if(H.job) - //internal_transmitter.phone_id = "[H.job] [H]" -// else - //internal_transmitter.phone_id = "[H]" - -// if(H.assigned_squad) - //internal_transmitter.phone_id += " ([H.assigned_squad.name])" -// else - //internal_transmitter.phone_id = "[user]" - - //internal_transmitter.enabled = TRUE - -/obj/item/storage/backpack/marine/satchel/rto/dropped(mob/user) - . = ..() - //internal_transmitter.phone_id = "[src]" - //internal_transmitter.enabled = FALSE - -/obj/item/storage/backpack/marine/satchel/rto/proc/use_phone(mob/user) - //internal_transmitter.attack_hand(user) - - -/obj/item/storage/backpack/marine/satchel/rto/attackby(obj/item/W, mob/user) -// if(internal_transmitter && internal_transmitter.attached_to == W) -// internal_transmitter.attackby(W, user) -// else -// . = ..() +/obj/item/storage/backpack/marine/satchel/rto/proc/phone_stopped_ringing() + if(icon_state == PHONE_OFF_BASE_UNIT_ICON_STATE) + return + icon_state = PHONE_ON_BASE_UNIT_ICON_STATE /obj/item/storage/backpack/marine/satchel/rto/upp_net name = "\improper UPP Radio Telephone Pack" @@ -606,7 +532,6 @@ GLOBAL_LIST_EMPTY_TYPED(radio_packs, /obj/item/storage/backpack/marine/satchel/r name = "\improper USCM Small Radio Telephone Pack" max_storage_space = 10 - /obj/item/storage/backpack/marine/satchel/rto/small/upp_net name = "\improper UPP Radio Telephone Pack" networks_receive = list(FACTION_UPP) diff --git a/code/modules/cm_phone/handset.dm b/code/modules/cm_phone/handset.dm index fbc245f079..66ecdeb0d0 100644 --- a/code/modules/cm_phone/handset.dm +++ b/code/modules/cm_phone/handset.dm @@ -11,6 +11,7 @@ flags_atom = FPRINT|USES_HEARING var/datum/component/phone/phone_component + var/atom/holder var/datum/effects/tethering/tether_effect @@ -25,7 +26,7 @@ src.phone_component = phone_component src.holder = holder - attach_to(holder) + attach_to(src.holder) /obj/item/handset/Destroy() phone_component = null @@ -34,6 +35,8 @@ return ..() /obj/item/handset/hear_talk(mob/living/talker, message, verb="says", datum/language/message_language, italics = 0) + . = ..() + if(talker == loc) phone_component.handle_speak(message, message_language, talker, direct_talking = TRUE) return @@ -78,21 +81,15 @@ if(!holder) return - if(loc == holder) + if(!loc) return if(get_dist(holder, src) > HANDSET_RANGE) phone_component.recall_handset() - var/atom/tether_to = src + var/atom/tether_to = get_atom_on_turf(src) - if(loc != get_turf(src)) - tether_to = loc - if(tether_to.loc != get_turf(tether_to)) - phone_component.recall_handset() - return - - var/atom/tether_from = holder + var/atom/tether_from = get_atom_on_turf(holder) if(tether_from == tether_to) return @@ -127,9 +124,8 @@ /obj/item/handset/dropped(mob/user) . = ..() - UnregisterSignal(user, COMSIG_LIVING_SPEAK) - set_raised(FALSE, user) + reset_tether() /obj/item/handset/on_enter_storage(obj/item/storage/S) . = ..() @@ -141,8 +137,13 @@ if(.) reset_tether() +/obj/item/handset/moveToNullspace() + . = ..() + if(.) + reset_tether() + /obj/item/handset/proc/do_zlevel_check() - if(!holder || !loc.z || !holder.z) + if(!holder || !loc?.z || !holder.z) return FALSE if(zlevel_transfer) diff --git a/code/modules/cm_phone/internal_phone.dm b/code/modules/cm_phone/internal_phone.dm deleted file mode 100644 index 6bab6fc732..0000000000 --- a/code/modules/cm_phone/internal_phone.dm +++ /dev/null @@ -1,15 +0,0 @@ -/* -/obj/structure/transmitter/internal - name = "\improper internal telephone receiver" - - var/atom/relay_obj - -/obj/structure/transmitter/internal/ui_host(mob/user, datum/tgui/ui) - if(!relay_obj) - return ..() - return relay_obj - -/obj/structure/transmitter/internal/Destroy() - relay_obj = null - return ..() -*/ diff --git a/code/modules/cm_phone/phone_base.dm b/code/modules/cm_phone/phone_base.dm index 0048389d3e..1cb6a9f0b5 100644 --- a/code/modules/cm_phone/phone_base.dm +++ b/code/modules/cm_phone/phone_base.dm @@ -29,10 +29,6 @@ networks_transmit = null return ..() -#define PHONE_ON_BASE_UNIT_ICON_STATE "[initial(icon_state)]" -#define PHONE_OFF_BASE_UNIT_ICON_STATE "[initial(icon_state)]_ear" -#define PHONE_RINGING_ICON_STATE "[initial(icon_state)]_ring" - /obj/structure/phone_base/proc/phone_picked_up() icon_state = PHONE_OFF_BASE_UNIT_ICON_STATE @@ -47,10 +43,6 @@ return icon_state = PHONE_ON_BASE_UNIT_ICON_STATE -#undef PHONE_ON_BASE_UNIT_ICON_STATE -#undef PHONE_OFF_BASE_UNIT_ICON_STATE -#undef PHONE_RINGING_ICON_STATE - /obj/structure/phone_base/hidden do_not_disturb = PHONE_DO_NOT_DISTURB_FORCED diff --git a/code/modules/movement/movement.dm b/code/modules/movement/movement.dm index da0c76cba9..4645756e29 100644 --- a/code/modules/movement/movement.dm +++ b/code/modules/movement/movement.dm @@ -102,11 +102,14 @@ /atom/movable/proc/forceMove(atom/destination) . = FALSE + if(destination) . = doMove(destination) else CRASH("No valid destination passed into forceMove") + if(SEND_SIGNAL(src, COMSIG_MOVABLE_FORCEMOVED, destination)) + return /atom/movable/proc/moveToNullspace() return doMove(null) diff --git a/colonialmarines.dme b/colonialmarines.dme index 2e638847ad..dfab961be2 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -1587,7 +1587,6 @@ s// DM Environment file for colonialmarines.dme. #include "code\modules\cm_marines\equipment\mortar\mortar_shells.dm" #include "code\modules\cm_marines\equipment\mortar\mortars.dm" #include "code\modules\cm_phone\handset.dm" -#include "code\modules\cm_phone\internal_phone.dm" #include "code\modules\cm_phone\phone_base.dm" #include "code\modules\cm_preds\_yaut_defines.dm" #include "code\modules\cm_preds\falcon.dm" From 43a31082d70f14b84cdcd1809b0e55cd4ef83429 Mon Sep 17 00:00:00 2001 From: Morrow Date: Wed, 25 Oct 2023 21:18:05 -0400 Subject: [PATCH 05/10] dchat listening --- code/datums/components/phone.dm | 16 +++++++++++++--- code/modules/cm_phone/phone_base.dm | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/code/datums/components/phone.dm b/code/datums/components/phone.dm index e279c5af0c..1d71dcba2d 100644 --- a/code/datums/components/phone.dm +++ b/code/datums/components/phone.dm @@ -7,7 +7,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) /// Our phone category which sorts us into tabs in the phone menu TGUI var/phone_category = "Uncategorised" - /// Honestly no idea yet - Morrow + /// Color of phone displayed in the phone menu var/phone_color = "white" /// The id of our phone which shows up when we talk @@ -366,11 +366,21 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) if(direct_talking) handle_hear(message, message_language, speaker, direct_talking) + log_say("TELEPHONE: [key_name(speaker)] on Phone '[phone_id]' to '[calling_phone.phone_id]' said '[message]'") - calling_phone.handle_hear(message, message_language, speaker, direct_talking) + var/comm_paygrade = "" + + if (ishuman(speaker)) + var/mob/living/carbon/human/human_speaker = speaker + comm_paygrade = human_speaker.get_paygrade() - // Add dchat listen in because it's funny, check radio preferences first, oh and don't do the background stuff - Morrow + for(var/mob/dead/observer/cycled_observer in GLOB.player_list) + if((cycled_observer.client) && (cycled_observer.client.prefs) && (cycled_observer.client.prefs.toggles_chat & CHAT_GHOSTRADIO)) + var/ghost_message = "[comm_paygrade][speaker] (F) on '[phone_id]' to '[calling_phone.phone_id]': \"[message]\"" + cycled_observer.show_message(ghost_message, SHOW_MESSAGE_AUDIBLE) + + calling_phone.handle_hear(message, message_language, speaker, direct_talking) /// Handles any messages passed from handle_speak() and serves them to the user /datum/component/phone/proc/handle_hear(message, datum/language/message_language, mob/speaker, direct_talking) diff --git a/code/modules/cm_phone/phone_base.dm b/code/modules/cm_phone/phone_base.dm index 1cb6a9f0b5..4b74262b9e 100644 --- a/code/modules/cm_phone/phone_base.dm +++ b/code/modules/cm_phone/phone_base.dm @@ -12,7 +12,7 @@ /// Whether or not the phone is receiving calls or not. Varies between on/off or forcibly on/off. var/do_not_disturb = PHONE_DO_NOT_DISTURB_OFF - var/list/networks_receive = list(FACTION_MARINE) // pass these to component, plus that shit above - Morrow + var/list/networks_receive = list(FACTION_MARINE) var/list/networks_transmit = list(FACTION_MARINE) /obj/structure/phone_base/Initialize(mapload, ...) From 82898f22c6afe3207238bd771b61c13ea837d93e Mon Sep 17 00:00:00 2001 From: Morrow Date: Wed, 25 Oct 2023 21:28:04 -0400 Subject: [PATCH 06/10] flavor --- code/datums/components/phone.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/components/phone.dm b/code/datums/components/phone.dm index 1d71dcba2d..dbf753b770 100644 --- a/code/datums/components/phone.dm +++ b/code/datums/components/phone.dm @@ -377,7 +377,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) for(var/mob/dead/observer/cycled_observer in GLOB.player_list) if((cycled_observer.client) && (cycled_observer.client.prefs) && (cycled_observer.client.prefs.toggles_chat & CHAT_GHOSTRADIO)) - var/ghost_message = "[comm_paygrade][speaker] (F) on '[phone_id]' to '[calling_phone.phone_id]': \"[message]\"" + var/ghost_message = "[comm_paygrade][speaker] (F) on '[phone_id]' to '[calling_phone.phone_id]': \"[message]\"" cycled_observer.show_message(ghost_message, SHOW_MESSAGE_AUDIBLE) calling_phone.handle_hear(message, message_language, speaker, direct_talking) From 80388c960e04cbf9e62c8d3cf0b72d04ed759e74 Mon Sep 17 00:00:00 2001 From: Morrow Date: Wed, 25 Oct 2023 21:43:40 -0400 Subject: [PATCH 07/10] time to fix conflicts --- code/datums/components/phone.dm | 7 +++-- code/modules/admin/game_master/game_master.dm | 26 ++++--------------- 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/code/datums/components/phone.dm b/code/datums/components/phone.dm index dbf753b770..f9375e27ae 100644 --- a/code/datums/components/phone.dm +++ b/code/datums/components/phone.dm @@ -475,7 +475,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) /// Virtual phone used for situations where you want to be able to use a phone without a handset /datum/component/phone/virtual /// If it is a virtual phone we need a virtual user - var/mob/virtual_user + var/client/virtual_user /datum/component/phone/virtual/Destroy() virtual_user = null @@ -554,7 +554,10 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) if(virtual_user == speaker) name_override = phone_id - virtual_user.hear_radio(message, "says", message_language, part_a = "", part_b = " ", vname = name_override, speaker = speaker, command = 3, no_paygrade = TRUE) + if(!virtual_user.mob) + return + + virtual_user.mob.hear_radio(message, "says", message_language, part_a = "", part_b = " ", vname = name_override, speaker = speaker, command = 3, no_paygrade = TRUE) // TGUI section diff --git a/code/modules/admin/game_master/game_master.dm b/code/modules/admin/game_master/game_master.dm index dbdf2b9ae1..c944f9ee5c 100644 --- a/code/modules/admin/game_master/game_master.dm +++ b/code/modules/admin/game_master/game_master.dm @@ -75,7 +75,7 @@ GLOBAL_LIST_EMPTY(game_master_objectives) /// Communication stuff - //var/datum/component/phone/game_master/game_master_phone + var/atom/game_master_phone /// End Communication stuff @@ -85,12 +85,12 @@ GLOBAL_LIST_EMPTY(game_master_objectives) /datum/game_master/New(client/using_client) . = ..() - if(using_client.mob) - tgui_interact(using_client.mob) + tgui_interact(using_client.mob) current_submenus = list() - //game_master_phone = new() + game_master_phone = new() + game_master_phone.AddComponent(/datum/component/phone/virtual, "Game Master", "white", "Company Command", null, PHONE_DO_NOT_DISTURB_FORCED, list(), list(FACTION_MARINE, FACTION_COLONIST, FACTION_WY), null, using_client) using_client.click_intercept = src @@ -98,7 +98,7 @@ GLOBAL_LIST_EMPTY(game_master_objectives) . = ..() submenu_types = null current_submenus = null - //QDEL_NULL(game_master_phone) + QDEL_NULL(game_master_phone) /datum/game_master/ui_data(mob/user) . = ..() @@ -170,22 +170,6 @@ GLOBAL_LIST_EMPTY(game_master_objectives) current_click_intercept_action = OBJECTIVE_CLICK_INTERCEPT_ACTION return - //Communication Section - //if("use_game_master_phone") - //if(!game_master_phone) - // game_master_phone = new() - - //var/new_phone_id = tgui_input_text(ui.user, "New phone id?", "Phone ID", game_master_phone.phone_id) - //if(!new_phone_id) - // return - - //game_master_phone.phone_id = new_phone_id - - //game_master_phone.tgui_interact(ui.user) - //return - - //if("set_communication_clarity") - /datum/game_master/ui_close(mob/user) . = ..() From 6ef0aacf8a111823af73ef00e95fb219652e4160 Mon Sep 17 00:00:00 2001 From: Morrow Date: Wed, 25 Oct 2023 23:31:03 -0400 Subject: [PATCH 08/10] game master phone --- .../dcs/signals/atom/signals_atom.dm | 5 +- code/_onclick/human.dm | 3 +- code/datums/components/phone.dm | 75 +++++++++++++++++-- code/modules/admin/game_master/game_master.dm | 9 ++- tgui/packages/tgui/interfaces/GameMaster.js | 2 +- tgui/packages/tgui/interfaces/PhoneMenu.js | 33 ++++++-- 6 files changed, 106 insertions(+), 21 deletions(-) diff --git a/code/__DEFINES/dcs/signals/atom/signals_atom.dm b/code/__DEFINES/dcs/signals/atom/signals_atom.dm index 8d699b0b2e..01e1533189 100644 --- a/code/__DEFINES/dcs/signals/atom/signals_atom.dm +++ b/code/__DEFINES/dcs/signals/atom/signals_atom.dm @@ -47,13 +47,16 @@ #define COMSIG_ATOM_VV_MODIFY_TRANSFORM "atom_vv_modify_transform" /// From /mob/living/carbon/human/UnarmedAttack() -#define COMSIG_ATOM_HUMAN_ATTACK_HAND "atom_human_attack_hand" +#define COMSIG_ATOM_BEFORE_HUMAN_ATTACK_HAND "atom_before_human_attack_hand" #define COMPONENT_CANCEL_ATTACK_HAND (1<<0) /// From /mob/proc/click_adjacent() #define COMSIG_ATOM_MOB_ATTACKBY "atom_mob_attackby" #define COMPONENT_CANCEL_ATTACKBY (1<<0) +/// From /atom/proc/attack_hand() +#define COMSIG_ATOM_ATTACK_HAND "atom_attack_hand" + /// From /datum/component/phone/proc/picked_up_call() and /datum/component/phone/proc/post_call_phone() #define COMSIG_ATOM_PHONE_PICKED_UP "atom_phone_picked_up" /// From /datum/component/phone/proc/recall_handset() diff --git a/code/_onclick/human.dm b/code/_onclick/human.dm index c7abc023a6..0bfba04070 100644 --- a/code/_onclick/human.dm +++ b/code/_onclick/human.dm @@ -80,7 +80,7 @@ to_chat(src, SPAN_NOTICE("You try to move your [temp.display_name], but cannot!")) return - if(SEND_SIGNAL(A, COMSIG_ATOM_HUMAN_ATTACK_HAND, src, click_parameters) & COMPONENT_CANCEL_HUMAN_ATTACK_HAND) + if(SEND_SIGNAL(A, COMSIG_ATOM_BEFORE_HUMAN_ATTACK_HAND, src, click_parameters) & COMPONENT_CANCEL_HUMAN_ATTACK_HAND) return A.attack_hand(src, click_parameters) @@ -89,6 +89,7 @@ return HANDLE_CLICK_PASS_THRU /atom/proc/attack_hand(mob/user) + SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND, user) return /mob/living/carbon/human/MouseDrop_T(atom/dropping, mob/user) diff --git a/code/datums/components/phone.dm b/code/datums/components/phone.dm index f9375e27ae..5a069678c4 100644 --- a/code/datums/components/phone.dm +++ b/code/datums/components/phone.dm @@ -91,7 +91,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) RegisterSignal(phone_handset, COMSIG_PARENT_PREQDELETED, PROC_REF(override_delete)) RegisterSignal(src.holder, COMSIG_ATOM_MOB_ATTACKBY, PROC_REF(item_used_on_phone)) - RegisterSignal(src.holder, COMSIG_ATOM_HUMAN_ATTACK_HAND, PROC_REF(use_phone)) + RegisterSignal(src.holder, COMSIG_ATOM_BEFORE_HUMAN_ATTACK_HAND, PROC_REF(use_phone)) if(istype(src.holder, /obj/item)) RegisterSignal(src.holder, COMSIG_ITEM_PICKUP, PROC_REF(holder_picked_up)) @@ -322,7 +322,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) SEND_SIGNAL(holder, COMSIG_ATOM_PHONE_STOPPED_RINGING) - ringing_loop.stop() + ringing_loop?.stop() handle_reset_call_message(timeout, recursed) @@ -358,7 +358,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) /// Handles any messages that our handset 'hears' and passes to us. Passes the message to this phone and any connected phone via handle_hear() /datum/component/phone/proc/handle_speak(message, datum/language/message_language, mob/speaker, direct_talking = TRUE) - if(message_language.flags & SIGNLANG) + if(message_language?.flags & SIGNLANG) return if(!calling_phone) @@ -434,12 +434,14 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) switch(action) if("call_phone") + if(calling_phone) + return TRUE call_phone(ui.user, params["phone_id"]) - . = TRUE + return TRUE if("toggle_do_not_disturb") toggle_do_not_disturb(ui.user) - . = TRUE + return TRUE /datum/component/phone/ui_data(mob/user) var/list/data = list() @@ -496,10 +498,17 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) return FALSE src.virtual_user = virtual_user + RegisterSignal(src.holder, COMSIG_ATOM_ATTACK_HAND, PROC_REF(use_phone)) + return TRUE +/datum/component/phone/virtual/use_phone(atom/phone, mob/living/carbon/human/user, click_parameters) + INVOKE_ASYNC(src, PROC_REF(tgui_interact), user) + /datum/component/phone/virtual/picked_up_call(mob/living/carbon/human/user) - to_chat(user, SPAN_PURPLE("[icon2html(src, user)] Picked up a call from [calling_phone.phone_id].")) + to_chat(user, SPAN_PURPLE("[icon2html(holder, user)] Picked up a call from [calling_phone.phone_id].")) + + RegisterSignal(virtual_user.mob, COMSIG_DEAD_SPEAK, PROC_REF(handle_virtual_speak)) /datum/component/phone/virtual/other_phone_picked_up_call() if(!calling_phone) @@ -509,6 +518,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) deltimer(timeout_timer_id) timeout_timer_id = null + RegisterSignal(virtual_user.mob, COMSIG_DEAD_SPEAK, PROC_REF(handle_virtual_speak)) to_chat(virtual_user, SPAN_PURPLE("[icon2html(calling_phone.holder, virtual_user)] [calling_phone.phone_id] has picked up.")) /datum/component/phone/virtual/phone_available() @@ -523,6 +533,10 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) return TRUE +/datum/component/phone/virtual/reset_call(timeout = FALSE, recursed = FALSE) + . = ..() + UnregisterSignal(virtual_user.mob, COMSIG_DEAD_SPEAK) + /datum/component/phone/virtual/handle_reset_call_message(timeout = FALSE, recursed = FALSE) if(recursed) to_chat(virtual_user, SPAN_PURPLE("[icon2html(holder, virtual_user)] [calling_phone.phone_id] has hung up on you.")) @@ -534,6 +548,14 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) /datum/component/phone/virtual/getting_call(datum/component/phone/incoming_call) calling_phone = incoming_call SEND_SIGNAL(holder, COMSIG_ATOM_PHONE_RINGING) + playsound_client(virtual_user, 'sound/machines/telephone/telephone_ring.ogg', vol = 50) + addtimer(CALLBACK(src, PROC_REF(delayed_client_sound)), (10 SECONDS)) + +/datum/component/phone/virtual/proc/delayed_client_sound() + if(!calling_phone || !calling_phone.timeout_timer_id) + return + + playsound_client(virtual_user, 'sound/machines/telephone/telephone_ring.ogg', vol = 50) /datum/component/phone/virtual/post_call_phone(mob/user, calling_phone_id) to_chat(user, SPAN_PURPLE("[icon2html(holder, user)] Dialing [calling_phone_id]..")) @@ -545,7 +567,7 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) reset_call() // I don't think this will be possible given like... we don't have a handset but just in case return -/datum/component/phone/virtual/handle_hear(message, datum/language/message_language, mob/speaker) +/datum/component/phone/virtual/handle_hear(message, datum/language/message_language, mob/speaker, direct_talking) if(!calling_phone) return @@ -559,12 +581,51 @@ GLOBAL_LIST_EMPTY_TYPED(phones, /datum/component/phone) virtual_user.mob.hear_radio(message, "says", message_language, part_a = "", part_b = " ", vname = name_override, speaker = speaker, command = 3, no_paygrade = TRUE) +/// Used to fake the other side of our phone connection as a virtual user +/datum/component/phone/virtual/proc/handle_virtual_speak(mob/speaker, message) + SIGNAL_HANDLER + + if(!calling_phone) + return + + handle_hear(message, null, speaker, TRUE) + + log_say("TELEPHONE: [key_name(speaker)] on Phone '[phone_id]' to '[calling_phone.phone_id]' said '[message]'") + + for(var/mob/dead/observer/cycled_observer in GLOB.player_list) + if((cycled_observer.client) && (cycled_observer.client.prefs) && (cycled_observer.client.prefs.toggles_chat & CHAT_GHOSTRADIO)) + var/ghost_message = "Game Master on '[phone_id]' to '[calling_phone.phone_id]': \"[message]\"" + cycled_observer.show_message(ghost_message, SHOW_MESSAGE_AUDIBLE) + + calling_phone.handle_hear(message, null, speaker, TRUE) + + return COMPONENT_OVERRIDE_DEAD_SPEAK + // TGUI section /datum/component/phone/virtual/ui_status(mob/user, datum/ui_state/state) return UI_INTERACTIVE +/datum/component/phone/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + + switch(action) + if("hang_up") + reset_call() + return TRUE + if("pick_up") + if(!calling_phone) + return + picked_up_call(ui.user) + calling_phone.other_phone_picked_up_call() + return TRUE + /datum/component/phone/virtual/ui_data(mob/user) . = ..() .["virtual_phone"] = TRUE + .["being_called"] = calling_phone?.timeout_timer_id ? TRUE : FALSE + .["active_call"] = calling_phone ? TRUE : FALSE + .["calling_phone_id"] = "[calling_phone?.phone_id]" diff --git a/code/modules/admin/game_master/game_master.dm b/code/modules/admin/game_master/game_master.dm index 860c506918..d97fe8aedb 100644 --- a/code/modules/admin/game_master/game_master.dm +++ b/code/modules/admin/game_master/game_master.dm @@ -78,7 +78,7 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100) /// Communication stuff - var/atom/game_master_phone + var/atom/movable/game_master_phone /// End Communication stuff @@ -92,8 +92,8 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100) current_submenus = list() - game_master_phone = new() - game_master_phone.AddComponent(/datum/component/phone/virtual, "Game Master", "white", "Company Command", null, PHONE_DO_NOT_DISTURB_FORCED, list(), list(FACTION_MARINE, FACTION_COLONIST, FACTION_WY), null, using_client) + game_master_phone = new(null) + game_master_phone.AddComponent(/datum/component/phone/virtual, "Game Master", "white", "Company Command", null, PHONE_DO_NOT_DISTURB_ON, list(FACTION_MARINE, FACTION_COLONIST, FACTION_WY), list(FACTION_MARINE, FACTION_COLONIST, FACTION_WY), null, using_client) using_client.click_intercept = src @@ -176,6 +176,9 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100) return //Communication Section + if("use_game_master_phone") + game_master_phone.attack_hand(ui.user) + if("set_communication_clarity") var/new_clarity = text2num(params["clarity"]) if(!isnum(new_clarity)) diff --git a/tgui/packages/tgui/interfaces/GameMaster.js b/tgui/packages/tgui/interfaces/GameMaster.js index 815e37dd05..13b12f5cbc 100644 --- a/tgui/packages/tgui/interfaces/GameMaster.js +++ b/tgui/packages/tgui/interfaces/GameMaster.js @@ -81,7 +81,7 @@ export const GameMaster = (props, context) => {