From fd265861bcc27bc5cf4b0282e853af7c57e3802d Mon Sep 17 00:00:00 2001 From: Leshana Date: Sat, 11 Jun 2016 16:56:57 -0400 Subject: [PATCH 1/6] Move preferences copy_to() new player mobs into the preference_setup datums. * The /datum/category_item/player_setup_item datums did a good job of organizing the code for loading/saving/editing preferences data, but all of the code that applies preferences to newly created player mobs was still in a single function. * This change adds a new proc to player_setup_item datums: copy_to_mob() which is called from the traditional copy_to() proc, allowing each preferences datum to apply its own character data to the mob. * This allowes new preferences to easily compartmentalize their new code. * I also moved all the code for existing preferences from copy_to() into the copy_to_mob() on their respective preferences datums. --- .../preference_setup/antagonism/01_basic.dm | 4 + .../preference_setup/general/01_basic.dm | 19 +++ .../preference_setup/general/03_body.dm | 47 ++++++++ .../preference_setup/general/04_equipment.dm | 24 ++++ .../preference_setup/general/05_background.dm | 10 ++ .../preference_setup/general/06_flavor.dm | 12 ++ .../preference_setup/preference_setup.dm | 16 +++ .../client/preference_setup/skills/skills.dm | 5 + code/modules/client/preferences.dm | 113 +----------------- 9 files changed, 142 insertions(+), 108 deletions(-) diff --git a/code/modules/client/preference_setup/antagonism/01_basic.dm b/code/modules/client/preference_setup/antagonism/01_basic.dm index eefc531da15..5b0be7bb71f 100644 --- a/code/modules/client/preference_setup/antagonism/01_basic.dm +++ b/code/modules/client/preference_setup/antagonism/01_basic.dm @@ -15,6 +15,10 @@ var/global/list/uplink_locations = list("PDA", "Headset", "None") /datum/category_item/player_setup_item/antagonism/basic/sanitize_character() pref.uplinklocation = sanitize_inlist(pref.uplinklocation, uplink_locations, initial(pref.uplinklocation)) +// Moved from /datum/preferences/proc/copy_to() +/datum/category_item/player_setup_item/antagonism/basic/copy_to_mob(var/mob/living/carbon/human/character) + character.exploit_record = pref.exploit_record + /datum/category_item/player_setup_item/antagonism/basic/content(var/mob/user) . +="Uplink Type : [pref.uplinklocation]" . +="
" diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm index 27aa76cc306..24f7e327f17 100644 --- a/code/modules/client/preference_setup/general/01_basic.dm +++ b/code/modules/client/preference_setup/general/01_basic.dm @@ -40,6 +40,25 @@ datum/preferences/proc/set_biological_gender(var/gender) pref.spawnpoint = sanitize_inlist(pref.spawnpoint, spawntypes, initial(pref.spawnpoint)) pref.be_random_name = sanitize_integer(pref.be_random_name, 0, 1, initial(pref.be_random_name)) +// Moved from /datum/preferences/proc/copy_to() +/datum/category_item/player_setup_item/general/basic/copy_to_mob(var/mob/living/carbon/human/character) + if(config.humans_need_surnames) + var/firstspace = findtext(pref.real_name, " ") + var/name_length = length(pref.real_name) + if(!firstspace) //we need a surname + pref.real_name += " [pick(last_names)]" + else if(firstspace == name_length) + pref.real_name += "[pick(last_names)]" + + character.real_name = pref.real_name + character.name = character.real_name + if(character.dna) + character.dna.real_name = character.real_name + + character.gender = pref.biological_gender + character.identifying_gender = pref.identifying_gender + character.age = pref.age + /datum/category_item/player_setup_item/general/basic/content() . = list() . += "Name: " diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index a092b859b31..8bd528cb5d6 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -76,6 +76,53 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O if(!pref.organ_data) pref.organ_data = list() if(!pref.rlimb_data) pref.rlimb_data = list() +// Moved from /datum/preferences/proc/copy_to() +/datum/category_item/player_setup_item/general/body/copy_to_mob(var/mob/living/carbon/human/character) + // Copy basic values + character.r_eyes = pref.r_eyes + character.g_eyes = pref.g_eyes + character.b_eyes = pref.b_eyes + character.h_style = pref.h_style + character.r_hair = pref.r_hair + character.g_hair = pref.g_hair + character.b_hair = pref.b_hair + character.f_style = pref.f_style + character.r_facial = pref.r_facial + character.g_facial = pref.g_facial + character.b_facial = pref.b_facial + character.r_skin = pref.r_skin + character.g_skin = pref.g_skin + character.b_skin = pref.b_skin + character.s_tone = pref.s_tone + character.h_style = pref.h_style + character.f_style = pref.f_style + character.b_type = pref.b_type + + // Destroy/cyborgize organs and limbs. + for(var/name in list(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM, BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG, BP_GROIN, BP_TORSO)) + var/status = pref.organ_data[name] + var/obj/item/organ/external/O = character.organs_by_name[name] + if(O) + if(status == "amputated") + O.remove_rejuv() + else if(status == "cyborg") + if(pref.rlimb_data[name]) + O.robotize(pref.rlimb_data[name]) + else + O.robotize() + + for(var/name in list(O_HEART,O_EYES,O_BRAIN)) + var/status = pref.organ_data[name] + if(!status) + continue + var/obj/item/organ/I = character.internal_organs_by_name[name] + if(I) + if(status == "assisted") + I.mechassist() + else if(status == "mechanical") + I.robotize() + return + /datum/category_item/player_setup_item/general/body/content(var/mob/user) . = list() if(!pref.preview_icon) diff --git a/code/modules/client/preference_setup/general/04_equipment.dm b/code/modules/client/preference_setup/general/04_equipment.dm index c455cef524a..537f2632e73 100644 --- a/code/modules/client/preference_setup/general/04_equipment.dm +++ b/code/modules/client/preference_setup/general/04_equipment.dm @@ -18,6 +18,30 @@ S["backbag"] << pref.backbag S["pdachoice"] << pref.pdachoice +// Moved from /datum/preferences/proc/copy_to() +/datum/category_item/player_setup_item/general/equipment/copy_to_mob(var/mob/living/carbon/human/character) + character.all_underwear.Cut() + character.all_underwear_metadata.Cut() + + for(var/underwear_category_name in pref.all_underwear) + var/datum/category_group/underwear/underwear_category = global_underwear.categories_by_name[underwear_category_name] + if(underwear_category) + var/underwear_item_name = pref.all_underwear[underwear_category_name] + character.all_underwear[underwear_category_name] = underwear_category.items_by_name[underwear_item_name] + if(pref.all_underwear_metadata[underwear_category_name]) + character.all_underwear_metadata[underwear_category_name] = pref.all_underwear_metadata[underwear_category_name] + else + pref.all_underwear -= underwear_category_name + + // TODO - Looks like this is duplicating the work of sanitize_character() if so, remove + if(pref.backbag > 4 || pref.backbag < 1) + pref.backbag = 1 //Same as above + character.backbag = pref.backbag + + if(pref.pdachoice > 3 || pref.pdachoice < 1) + pref.pdachoice = 1 + character.pdachoice = pref.pdachoice + /datum/category_item/player_setup_item/general/equipment/sanitize_character() if(!islist(pref.gear)) pref.gear = list() diff --git a/code/modules/client/preference_setup/general/05_background.dm b/code/modules/client/preference_setup/general/05_background.dm index 5708d3c757e..e3076629a8e 100644 --- a/code/modules/client/preference_setup/general/05_background.dm +++ b/code/modules/client/preference_setup/general/05_background.dm @@ -30,6 +30,16 @@ pref.nanotrasen_relation = sanitize_inlist(pref.nanotrasen_relation, COMPANY_ALIGNMENTS, initial(pref.nanotrasen_relation)) +// Moved from /datum/preferences/proc/copy_to() +/datum/category_item/player_setup_item/general/background/copy_to_mob(var/mob/living/carbon/human/character) + character.med_record = pref.med_record + character.sec_record = pref.sec_record + character.gen_record = pref.gen_record + character.home_system = pref.home_system + character.citizenship = pref.citizenship + character.personal_faction = pref.faction + character.religion = pref.religion + /datum/category_item/player_setup_item/general/background/content(var/mob/user) . += "Background Information
" . += "[company_name] Relation: [pref.nanotrasen_relation]
" diff --git a/code/modules/client/preference_setup/general/06_flavor.dm b/code/modules/client/preference_setup/general/06_flavor.dm index b312bb95e9b..94525ee06ff 100644 --- a/code/modules/client/preference_setup/general/06_flavor.dm +++ b/code/modules/client/preference_setup/general/06_flavor.dm @@ -36,6 +36,18 @@ /datum/category_item/player_setup_item/general/flavor/sanitize_character() return +// Moved from /datum/preferences/proc/copy_to() +/datum/category_item/player_setup_item/general/flavor/copy_to_mob(var/mob/living/carbon/human/character) + character.flavor_texts["general"] = pref.flavor_texts["general"] + character.flavor_texts["head"] = pref.flavor_texts["head"] + character.flavor_texts["face"] = pref.flavor_texts["face"] + character.flavor_texts["eyes"] = pref.flavor_texts["eyes"] + character.flavor_texts["torso"] = pref.flavor_texts["torso"] + character.flavor_texts["arms"] = pref.flavor_texts["arms"] + character.flavor_texts["hands"] = pref.flavor_texts["hands"] + character.flavor_texts["legs"] = pref.flavor_texts["legs"] + character.flavor_texts["feet"] = pref.flavor_texts["feet"] + /datum/category_item/player_setup_item/general/flavor/content(var/mob/user) . += "Flavor:
" . += "Set Flavor Text
" diff --git a/code/modules/client/preference_setup/preference_setup.dm b/code/modules/client/preference_setup/preference_setup.dm index 7028894fda4..a152d4399c2 100644 --- a/code/modules/client/preference_setup/preference_setup.dm +++ b/code/modules/client/preference_setup/preference_setup.dm @@ -72,6 +72,10 @@ for(var/datum/category_group/player_setup_category/PS in categories) PS.save_preferences(S) +/datum/category_collection/player_setup_collection/proc/copy_to_mob(var/mob/living/carbon/human/C) + for(var/datum/category_group/player_setup_category/PS in categories) + PS.copy_to_mob(C) + /datum/category_collection/player_setup_collection/proc/header() var/dat = "" for(var/datum/category_group/player_setup_category/PS in categories) @@ -143,6 +147,12 @@ for(var/datum/category_item/player_setup_item/PI in items) PI.save_preferences(S) +/datum/category_group/player_setup_category/proc/copy_to_mob(var/mob/living/carbon/human/C) + for(var/datum/category_item/player_setup_item/PI in items) + PI.sanitize_character() + for(var/datum/category_item/player_setup_item/PI in items) + PI.copy_to_mob(C) + /datum/category_group/player_setup_category/proc/content(var/mob/user) . = "
" var/current = 0 @@ -201,6 +211,12 @@ /datum/category_item/player_setup_item/proc/save_preferences(var/savefile/S) return +/* +* Called when the item is asked to apply its per character settings to a new mob. +*/ +/datum/category_item/player_setup_item/proc/copy_to_mob(var/mob/living/carbon/human/C) + return + /datum/category_item/player_setup_item/proc/content() return diff --git a/code/modules/client/preference_setup/skills/skills.dm b/code/modules/client/preference_setup/skills/skills.dm index 7255e25bc46..ab5a6c17e10 100644 --- a/code/modules/client/preference_setup/skills/skills.dm +++ b/code/modules/client/preference_setup/skills/skills.dm @@ -18,6 +18,11 @@ if(!pref.skills.len) pref.ZeroSkills() if(pref.used_skillpoints < 0) pref.used_skillpoints = 0 +// Moved from /datum/preferences/proc/copy_to() +/datum/category_item/player_setup_item/skills/copy_to_mob(var/mob/living/carbon/human/character) + character.skills = pref.skills + character.used_skillpoints = pref.used_skillpoints + /datum/category_item/player_setup_item/skills/content() . = list() . += "Select your Skills
" diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 665ea5836c1..0bcaff2491b 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -251,118 +251,15 @@ datum/preferences /datum/preferences/proc/copy_to(mob/living/carbon/human/character, icon_updates = 1) // Sanitizing rather than saving as someone might still be editing when copy_to occurs. player_setup.sanitize_setup() + + // This needs to happen before anything else becuase it sets some variables. character.set_species(species) + // Special Case: This references variables owned by two different datums, so do it here. if(be_random_name) real_name = random_name(identifying_gender,species) - if(config.humans_need_surnames) - var/firstspace = findtext(real_name, " ") - var/name_length = length(real_name) - if(!firstspace) //we need a surname - real_name += " [pick(last_names)]" - else if(firstspace == name_length) - real_name += "[pick(last_names)]" - - character.real_name = real_name - character.name = character.real_name - if(character.dna) - character.dna.real_name = character.real_name - - character.flavor_texts["general"] = flavor_texts["general"] - character.flavor_texts["head"] = flavor_texts["head"] - character.flavor_texts["face"] = flavor_texts["face"] - character.flavor_texts["eyes"] = flavor_texts["eyes"] - character.flavor_texts["torso"] = flavor_texts["torso"] - character.flavor_texts["arms"] = flavor_texts["arms"] - character.flavor_texts["hands"] = flavor_texts["hands"] - character.flavor_texts["legs"] = flavor_texts["legs"] - character.flavor_texts["feet"] = flavor_texts["feet"] - - character.med_record = med_record - character.sec_record = sec_record - character.gen_record = gen_record - character.exploit_record = exploit_record - - character.gender = biological_gender - character.identifying_gender = identifying_gender - character.age = age - character.b_type = b_type - - character.r_eyes = r_eyes - character.g_eyes = g_eyes - character.b_eyes = b_eyes - - character.h_style = h_style - character.r_hair = r_hair - character.g_hair = g_hair - character.b_hair = b_hair - - character.f_style = f_style - character.r_facial = r_facial - character.g_facial = g_facial - character.b_facial = b_facial - - character.r_skin = r_skin - character.g_skin = g_skin - character.b_skin = b_skin - - character.s_tone = s_tone - - character.h_style = h_style - character.f_style = f_style - - character.home_system = home_system - character.citizenship = citizenship - character.personal_faction = faction - character.religion = religion - - character.skills = skills - character.used_skillpoints = used_skillpoints - - // Destroy/cyborgize organs and limbs. - for(var/name in list(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM, BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG, BP_GROIN, BP_TORSO)) - var/status = organ_data[name] - var/obj/item/organ/external/O = character.organs_by_name[name] - if(O) - if(status == "amputated") - O.remove_rejuv() - else if(status == "cyborg") - if(rlimb_data[name]) - O.robotize(rlimb_data[name]) - else - O.robotize() - - for(var/name in list(O_HEART,O_EYES,O_BRAIN)) - var/status = organ_data[name] - if(!status) - continue - var/obj/item/organ/I = character.internal_organs_by_name[name] - if(I) - if(status == "assisted") - I.mechassist() - else if(status == "mechanical") - I.robotize() - - character.all_underwear.Cut() - character.all_underwear_metadata.Cut() - - for(var/underwear_category_name in all_underwear) - var/datum/category_group/underwear/underwear_category = global_underwear.categories_by_name[underwear_category_name] - if(underwear_category) - var/underwear_item_name = all_underwear[underwear_category_name] - character.all_underwear[underwear_category_name] = underwear_category.items_by_name[underwear_item_name] - if(all_underwear_metadata[underwear_category_name]) - character.all_underwear_metadata[underwear_category_name] = all_underwear_metadata[underwear_category_name] - else - all_underwear -= underwear_category_name - - if(backbag > 4 || backbag < 1) - backbag = 1 //Same as above - character.backbag = backbag - - if(pdachoice > 3 || pdachoice < 1) - pdachoice = 1 - character.pdachoice = pdachoice + // Ask the preferences datums to apply their own settings to the new mob + player_setup.copy_to_mob(character) if(icon_updates) character.force_update_limbs() From 11107cb8511634c2abeeebc0e93f87da36469512 Mon Sep 17 00:00:00 2001 From: Leshana Date: Sun, 12 Jun 2016 13:28:24 -0400 Subject: [PATCH 2/6] Removing redundant sanitizing; prefs has already been sanitized by this point. --- code/modules/client/preference_setup/preference_setup.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/modules/client/preference_setup/preference_setup.dm b/code/modules/client/preference_setup/preference_setup.dm index a152d4399c2..6344d538e7c 100644 --- a/code/modules/client/preference_setup/preference_setup.dm +++ b/code/modules/client/preference_setup/preference_setup.dm @@ -148,8 +148,6 @@ PI.save_preferences(S) /datum/category_group/player_setup_category/proc/copy_to_mob(var/mob/living/carbon/human/C) - for(var/datum/category_item/player_setup_item/PI in items) - PI.sanitize_character() for(var/datum/category_item/player_setup_item/PI in items) PI.copy_to_mob(C) From b624e7703a54ab3c6c5d8df28ea70209cb651bb7 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Mon, 13 Jun 2016 02:55:05 -0400 Subject: [PATCH 3/6] Adds actual video calls to communicators 'chu heard me. S'what it does. When you're on a call, there's a "Start Video" button next to each person. When you click it, you actually look through their thing, like a ghost might if they ghostcalled. You have to stay within 1 tile of a video showing communicator to see it. Multiple people can share one communicator video stream by setting it on a table or whatever, and examining it. There's a message like "It appears to be showing a video: [view]" and you can click view and you can all look at the video. COLLABORATION. SYNERGY. OTHER BUZZWORDS. I also added the feature of DECLINING requests from people. Also communicators show up on a special camera list on security consoles, but the same EPv2 network visibility turns this off as well if you wanna be all hidey. This does mean that people with the visiblity on serve as sort of roaming AI cameras for the AI as well. So the AI can watch you repair the outside of the station or whatever if you want. --- code/__defines/machinery.dm | 1 + code/game/machinery/camera/camera.dm | 3 + code/game/machinery/camera/presets.dm | 3 +- .../devices/communicator/communicator.dm | 193 ++++++++++++++++-- code/modules/mob/living/carbon/human/life.dm | 6 +- icons/obj/device.dmi | Bin 44606 -> 44622 bytes nano/templates/communicator.tmpl | 9 +- 7 files changed, 192 insertions(+), 23 deletions(-) diff --git a/code/__defines/machinery.dm b/code/__defines/machinery.dm index 1f65364e1ae..cc77b8c3c59 100644 --- a/code/__defines/machinery.dm +++ b/code/__defines/machinery.dm @@ -50,6 +50,7 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called #define NETWORK_SECURITY "Security" #define NETWORK_TELECOM "Tcomsat" #define NETWORK_THUNDER "Thunderdome" +#define NETWORK_COMMUNICATORS "Communicators" // Those networks can only be accessed by pre-existing terminals. AIs and new terminals can't use them. var/list/restricted_camera_networks = list(NETWORK_ERT,NETWORK_MERCENARY,"Secret") diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 291b9852949..7c466514194 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -35,10 +35,13 @@ var/affected_by_emp_until = 0 + var/client_huds = list() + /obj/machinery/camera/New() wires = new(src) assembly = new(src) assembly.state = 4 + client_huds |= global_hud.whitense /* // Use this to look for cameras that have the same c_tag. for(var/obj/machinery/camera/C in cameranet.cameras) diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm index 136bafa90ed..883d9611c16 100644 --- a/code/game/machinery/camera/presets.dm +++ b/code/game/machinery/camera/presets.dm @@ -17,7 +17,8 @@ var/global/list/station_networks = list( NETWORK_RESEARCH_OUTPOST, NETWORK_ROBOTS, NETWORK_PRISON, - NETWORK_SECURITY + NETWORK_SECURITY, + NETWORK_COMMUNICATORS ) var/global/list/engineering_networks = list( NETWORK_ENGINE, diff --git a/code/game/objects/items/devices/communicator/communicator.dm b/code/game/objects/items/devices/communicator/communicator.dm index e7831391361..bf7bd30ab12 100644 --- a/code/game/objects/items/devices/communicator/communicator.dm +++ b/code/game/objects/items/devices/communicator/communicator.dm @@ -18,6 +18,8 @@ var/global/list/obj/item/device/communicator/all_communicators = list() matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 10) var/video_range = 4 + var/obj/machinery/camera/communicator/video_source // Their camera + var/obj/machinery/camera/communicator/camera // Our camera var/list/voice_mobs = list() var/list/voice_requests = list() @@ -63,6 +65,9 @@ var/global/list/obj/item/device/communicator/all_communicators = list() all_communicators = sortAtom(all_communicators) node = get_exonet_node() processing_objects |= src + camera = new(src) + camera.name = "[src] #[rand(100,999)]" + camera.c_tag = camera.name //This is a pretty terrible way of doing this. spawn(5 SECONDS) //Wait for our mob to finish spawning. if(ismob(loc)) @@ -74,6 +79,14 @@ var/global/list/obj/item/device/communicator/all_communicators = list() register_device(S.loc) initialize_exonet(S.loc) +// Proc: examine() +// Parameters: user - the user doing the examining +// Description: Allows the user to click a link when examining to look at video if one is going. +/obj/item/device/communicator/examine(mob/user) + . = ..(user, 1) + if(. && video_source) + user << "It looks like it's on a video call: \[view\]" + // Proc: initialize_exonet() // Parameters: 1 (user - the person the communicator belongs to) // Description: Sets up the exonet datum, gives the device an address, and then gets a node reference. Afterwards, populates the device @@ -257,27 +270,27 @@ var/global/list/obj/item/device/communicator/all_communicators = list() //Now for ghosts who we pretend have communicators. for(var/mob/observer/dead/O in known_devices) if(O.client && O.client.prefs.communicator_visibility == 1 && O.exonet) - communicators[++communicators.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address) + communicators[++communicators.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address, "ref" = "\ref[O]") //Lists all the other communicators that we invited. for(var/obj/item/device/communicator/comm in voice_invites) if(comm.exonet) - invites[++invites.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address) + invites[++invites.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address, "ref" = "\ref[comm]") //Ghosts we invited. for(var/mob/observer/dead/O in voice_invites) if(O.exonet && O.client) - invites[++invites.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address) + invites[++invites.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address, "ref" = "\ref[O]") //Communicators that want to talk to us. for(var/obj/item/device/communicator/comm in voice_requests) if(comm.exonet) - requests[++requests.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address) + requests[++requests.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address, "ref" = "\ref[comm]") //Ghosts that want to talk to us. for(var/mob/observer/dead/O in voice_requests) if(O.exonet && O.client) - requests[++requests.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address) + requests[++requests.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address, "ref" = "\ref[O]") //Now for all the voice mobs inside the communicator. for(var/mob/living/voice/voice in contents) @@ -285,12 +298,12 @@ var/global/list/obj/item/device/communicator/all_communicators = list() //Finally, all the communicators linked to this one. for(var/obj/item/device/communicator/comm in communicating) - connected_communicators[++connected_communicators.len] = list("name" = sanitize(comm.name), "true_name" = sanitize(comm.name)) + connected_communicators[++connected_communicators.len] = list("name" = sanitize(comm.name), "true_name" = sanitize(comm.name), "ref" = "\ref[comm]") //Devices that have been messaged or recieved messages from. for(var/obj/item/device/communicator/comm in im_contacts) if(comm.exonet) - im_contacts_ui[++im_contacts_ui.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address) + im_contacts_ui[++im_contacts_ui.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address, "ref" = "\ref[comm]") //Actual messages. for(var/I in im_list) @@ -313,6 +326,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list() data["requestsReceived"] = requests data["voice_mobs"] = voices data["communicating"] = connected_communicators + data["video_comm"] = video_source ? "\ref[video_source.loc]" : null data["imContacts"] = im_contacts_ui data["imList"] = im_list_ui data["time"] = worldtime2text() @@ -325,7 +339,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list() if(!ui) // the ui does not exist, so we'll create a new() one // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "communicator.tmpl", "Communicator", 450, 700) + ui = new(user, src, ui_key, "communicator.tmpl", "Communicator", 475, 700) // when the ui is first opened this is the data it will use ui.set_initial_data(data) // open the new ui window @@ -344,9 +358,20 @@ var/global/list/obj/item/device/communicator/all_communicators = list() if(new_name) owner = new_name name = "[owner]'s [initial(name)]" + if(camera) + camera.name = name + camera.c_tag = name if(href_list["toggle_visibility"]) - network_visibility = !network_visibility + switch(network_visibility) + if(1) //Visible, becoming invisbile + network_visibility = 0 + if(camera) + camera.remove_network(NETWORK_COMMUNICATORS) + if(0) //Invisible, becoming visible + network_visibility = 1 + if(camera) + camera.add_network(NETWORK_COMMUNICATORS) if(href_list["toggle_ringer"]) ringer = !ringer @@ -371,6 +396,12 @@ var/global/list/obj/item/device/communicator/all_communicators = list() var/their_address = href_list["dial"] exonet.send_message(their_address, "voice") + if(href_list["decline"]) + var/ref_to_remove = href_list["decline"] + var/atom/decline = locate(ref_to_remove) + if(decline) + del_request(decline) + if(href_list["message"]) if(!get_connection_to_tcomms()) usr << "Error: Cannot connect to Exonet node." @@ -385,10 +416,24 @@ var/global/list/obj/item/device/communicator/all_communicators = list() var/name_to_disconnect = href_list["disconnect"] for(var/mob/living/voice/V in contents) if(name_to_disconnect == V.name) - close_connection(usr, V, "[usr] hung up.") + close_connection(usr, V, "[usr] hung up") for(var/obj/item/device/communicator/comm in communicating) if(name_to_disconnect == comm.name) - close_connection(usr, comm, "[usr] hung up.") + close_connection(usr, comm, "[usr] hung up") + + if(href_list["startvideo"]) + var/ref_to_video = href_list["startvideo"] + var/obj/item/device/communicator/comm = locate(ref_to_video) + if(comm) + connect_video(usr, comm) + + if(href_list["endvideo"]) + if(video_source) + end_video() + + if(href_list["watchvideo"]) + if(video_source) + watch_video(usr,video_source.loc) if(href_list["copy"]) target_address = href_list["copy"] @@ -398,9 +443,9 @@ var/global/list/obj/item/device/communicator/all_communicators = list() if(href_list["hang_up"]) for(var/mob/living/voice/V in contents) - close_connection(usr, V, "[usr] hung up.") + close_connection(usr, V, "[usr] hung up") for(var/obj/item/device/communicator/comm in communicating) - close_connection(usr, comm, "[usr] hung up.") + close_connection(usr, comm, "[usr] hung up") if(href_list["switch_tab"]) selected_tab = href_list["switch_tab"] @@ -475,7 +520,9 @@ var/global/list/obj/item/device/communicator/all_communicators = list() owner = user.name name = "[owner]'s [initial(name)]" - + if(camera) + camera.name = name + camera.c_tag = name // Proc: add_communicating() // Parameters: 1 (comm - the communicator to add to communicating) @@ -485,6 +532,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list() communicating |= comm listening_objects |= src + update_icon() // Proc: del_communicating() // Parameters: 1 (comm - the communicator to remove from communicating) @@ -493,6 +541,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list() if(!comm || !istype(comm)) return communicating.Remove(comm) + update_icon() // Proc: open_connection() // Parameters: 2 (user - the person who initiated the connecting being opened, candidate - the communicator or observer that will connect to the device) @@ -601,15 +650,19 @@ var/global/list/obj/item/device/communicator/all_communicators = list() visible_message("\icon[src] [reason].") voice_mobs.Remove(voice) qdel(voice) + update_icon() for(var/obj/item/device/communicator/comm in communicating) //Now we handle real communicators. if(target && comm != target) continue - comm.visible_message("\icon[src] [reason].") - visible_message("\icon[src] [reason].") src.del_communicating(comm) comm.del_communicating(src) - update_icon() + comm.visible_message("\icon[src] [reason].") + visible_message("\icon[src] [reason].") + if(comm.camera && video_source == comm.camera) //We hung up on the person on video + end_video() + if(camera && comm.video_source == camera) //We hung up on them while they were watching us + comm.end_video() if(voice_mobs.len == 0 && communicating.len == 0) listening_objects.Remove(src) @@ -649,6 +702,29 @@ var/global/list/obj/item/device/communicator/all_communicators = list() if(L) L << "\icon[src] Communications request from [who]." +// Proc: del_request() +// Parameters: 1 (candidate - the ghost or communicator to be declined) +// Description: Declines a request and cleans up both ends +/obj/item/device/communicator/proc/del_request(var/atom/candidate) + if(!(candidate in voice_requests)) + return + + if(isobserver(candidate)) + candidate << "Your communicator call request was declined." + else if(istype(candidate, /obj/item/device/communicator)) + var/obj/item/device/communicator/comm = candidate + comm.voice_invites -= src + + voice_requests -= candidate + + //Search for holder of our device. + var/mob/living/us = null + if(loc && isliving(loc)) + us = loc + + if(us) + us << "\icon[src] Declined request." + // Proc: request_im() // Parameters: 3 (candidate - the communicator wanting to message the device, origin_address - the address of the sender, text - the message) // Description: Response to a communicator trying to message the device. @@ -700,6 +776,8 @@ var/global/list/obj/item/device/communicator/all_communicators = list() all_communicators -= src processing_objects -= src listening_objects.Remove(src) + qdel(camera) + camera = null if(exonet) exonet.remove_address() exonet = null @@ -709,7 +787,11 @@ var/global/list/obj/item/device/communicator/all_communicators = list() // Parameters: None // Description: Self explanatory /obj/item/device/communicator/update_icon() - if(voice_mobs.len > 0) + if(video_source) + icon_state = "communicator-video" + return + + if(voice_mobs.len || communicating.len) icon_state = "communicator-active" return @@ -833,7 +915,71 @@ var/global/list/obj/item/device/communicator/all_communicators = list() src << "A communications request has been sent to [chosen_communicator]. Now you need to wait until someone answers." -/obj/item/device/communicator/integrated //For synths who have no hands. +// Proc: connect_video() +// Parameters: user - the mob doing the viewing of video, comm - the communicator at the far end +// Description: Sets up a videocall and puts the first view into it using watch_video, and updates the icon +/obj/item/device/communicator/proc/connect_video(mob/user,obj/item/device/communicator/comm) + if((!user) || (!comm) || user.stat) return //KO or dead, or already in a video + + if(video_source) //Already in a video + user << "You are already connected to a video call!" + + if(user.blinded) //User is blinded + user << "You cannot see well enough to do that!" + + if(!(src in comm.communicating) || !comm.camera) //You called someone with a broken communicator or one that's fake or yourself or something + user << "\icon[src]ERROR: Video failed. Either bandwidth is too low, or the other communicator is malfunctioning." + + user << "\icon[src] Attempting to start video over existing call." + sleep(30) + user << "\icon[src] Please wait..." + + video_source = comm.camera + comm.visible_message("\icon[src] New video connection from [comm].") + watch_video(user) + update_icon() + +// Proc: watch_video() +// Parameters: user - the mob doing the viewing of video +// Description: Moves a mob's eye to the far end for the duration of viewing the far end +/obj/item/device/communicator/proc/watch_video(mob/user) + if(!Adjacent(user) || !video_source) return + user.set_machine(video_source) + user.reset_view(video_source) + user << "Now viewing video session. To leave camera view: OOC -> Cancel Camera View" + spawn(0) + while(user.machine == video_source && Adjacent(user)) + var/turf/T = get_turf(video_source) + if(!T || !is_on_same_plane_or_station(T.z, user.z) || !video_source.can_use()) + user << "The screen bursts into static, then goes black." + video_cleanup(user) + return + sleep(10) + + video_cleanup(user) + +// Proc: video_cleanup() +// Parameters: user - the mob who doesn't want to see video anymore +// Description: Cleans up mob's client when they stop watching a video +/obj/item/device/communicator/proc/video_cleanup(mob/user) + if(!user) return + + user.reset_view(null) + user.unset_machine() + +// Proc: end_video() +// Parameters: reason - the text reason to print for why it ended +// Description: Ends the video call by clearing video_source +/obj/item/device/communicator/proc/end_video(var/reason) + video_source = null + + . = "\icon[src] [reason ? reason : "Video session ended"]." + + visible_message(.) + update_icon() + +//For synths who have no hands. +/obj/item/device/communicator/integrated name = "integrated communicator" desc = "A circuit used for long-range communications, able to be integrated into a system." @@ -864,3 +1010,12 @@ var/global/list/obj/item/device/communicator/all_communicators = list() return src.attack_self(usr) + +// A camera preset for spawning in the communicator +/obj/machinery/camera/communicator + network = list(NETWORK_COMMUNICATORS) + +/obj/machinery/camera/communicator/New() + ..() + client_huds |= global_hud.whitense + client_huds |= global_hud.darkMask \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 13dbd179c03..2030f3407d8 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1051,7 +1051,11 @@ if(copytext(hud.icon_state,1,4) == "hud") //ugly, but icon comparison is worse, I believe client.images.Remove(hud) - client.screen.Remove(global_hud.blurry, global_hud.druggy, global_hud.vimpaired, global_hud.darkMask, global_hud.nvg, global_hud.thermal, global_hud.meson, global_hud.science) + client.screen.Remove(global_hud.blurry, global_hud.druggy, global_hud.vimpaired, global_hud.darkMask, global_hud.nvg, global_hud.thermal, global_hud.meson, global_hud.science, global_hud.whitense) + + if(istype(client.eye,/obj/machinery/camera)) + var/obj/machinery/camera/cam = client.eye + client.screen |= cam.client_huds if(damageoverlay.overlays) damageoverlay.overlays = list() diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index cba5ea04cae7c5d90e4823141c72cc01b3b2cb5d..2c2e234a3ff93a1501b014706154fdc6bb131e76 100644 GIT binary patch delta 23396 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

atrjSTSCSE8& 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 delta 23385 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 X%Gz

-
{{:helper.link('Disconnect', 'close', {'disconnect' : value.true_name}, null, 'redButton')}}
+ {{:helper.link('Disconnect', 'close', {'disconnect' : value.true_name}, null, 'redButton')}} + {{if data.video_comm == null}} + {{:helper.link('Start Video', 'signal-diag', {'startvideo' : value.ref})}} + {{else data.video_comm == value.ref}} + {{:helper.link('End Video', 'signal-diag', {'endvideo' : value.true_name}, null, 'redButton')}} + {{/if}}
{{/for}} @@ -114,7 +119,7 @@ Used In File(s): code\game\objects\items\devices\communicator\communicator.dm {{:value.name}}
-
{{:value.address}}
{{:helper.link('Dial', 'signal-diag', {'dial' : value.address})}} +
{{:value.address}}
{{:helper.link('Accept', 'signal-diag', {'dial' : value.address})}}{{:helper.link('Decline', 'close', {'decline' : value.ref})}}
{{/for}} From fdc8b33b2c8f70607558bad138c0d3ba77a91094 Mon Sep 17 00:00:00 2001 From: Yoshax Date: Mon, 13 Jun 2016 20:19:52 +0100 Subject: [PATCH 4/6] Adds towels to fitness vendor, color is randomised --- code/game/machinery/vending.dm | 6 ++++-- code/game/objects/items/weapons/towels.dm | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index b0f1460249a..0f3ff025b95 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -741,7 +741,8 @@ /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask = 8, /obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar = 8, /obj/item/weapon/reagent_containers/food/snacks/liquidfood = 8, - /obj/item/weapon/reagent_containers/pill/diet = 8) + /obj/item/weapon/reagent_containers/pill/diet = 8, + /obj/item/weapon/towel/random = 8) prices = list(/obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton = 3, /obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton/chocolate = 3, @@ -749,7 +750,8 @@ /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask = 5, /obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar = 5, /obj/item/weapon/reagent_containers/food/snacks/liquidfood = 5, - /obj/item/weapon/reagent_containers/pill/diet = 25) + /obj/item/weapon/reagent_containers/pill/diet = 25, + /obj/item/weapon/towel/random = 40) contraband = list(/obj/item/weapon/reagent_containers/syringe/steroid = 4) diff --git a/code/game/objects/items/weapons/towels.dm b/code/game/objects/items/weapons/towels.dm index 94c266142e5..d51cc8d1d06 100644 --- a/code/game/objects/items/weapons/towels.dm +++ b/code/game/objects/items/weapons/towels.dm @@ -12,3 +12,7 @@ /obj/item/weapon/towel/attack_self(mob/living/user as mob) user.visible_message(text("[] uses [] to towel themselves off.", user, src)) playsound(user, 'sound/weapons/towelwipe.ogg', 25, 1) + +/obj/item/weapon/towel/random/New() + ..() + color = "#"+get_random_colour() \ No newline at end of file From 3e0745677f055f6c4c680db16843b8816cf0c8bb Mon Sep 17 00:00:00 2001 From: Yoshax Date: Mon, 13 Jun 2016 20:20:07 +0100 Subject: [PATCH 5/6] Fixes chocolate milk and milk --- code/modules/reagents/reagent_containers/food/drinks.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/reagents/reagent_containers/food/drinks.dm b/code/modules/reagents/reagent_containers/food/drinks.dm index 69472021b84..f2770d98237 100644 --- a/code/modules/reagents/reagent_containers/food/drinks.dm +++ b/code/modules/reagents/reagent_containers/food/drinks.dm @@ -132,7 +132,7 @@ reagents.add_reagent("soymilk", 50) /obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton - name = "small chocolate milk carton" + name = "small milk carton" volume = 30 icon_state = "mini-milk" /obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton/New() @@ -140,9 +140,9 @@ reagents.add_reagent("milk", 30) /obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton/chocolate - name = "Small Carton of Chocolate Milk" + name = "small chocolate milk carton" desc = "It's milk! This one is in delicious chocolate flavour." - + icon_state = "mini-milk_choco" /obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton/chocolate/New() ..() reagents.add_reagent("chocolate_milk", 30) From fff26d1289793d372806db2ab30839b81c6b936e Mon Sep 17 00:00:00 2001 From: Yoshax Date: Mon, 13 Jun 2016 20:20:17 +0100 Subject: [PATCH 6/6] Fixes GRC to make it not shit --- code/_helpers/unsorted.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index 0858ebc1a40..1e14d391833 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -1257,7 +1257,7 @@ var/list/WALLITEMS = list( arglist = list2params(arglist) return "[content]" -/proc/get_random_colour(var/simple, var/lower, var/upper) +/proc/get_random_colour(var/simple, var/lower=0, var/upper=255) var/colour if(simple) colour = pick(list("FF0000","FF7F00","FFFF00","00FF00","0000FF","4B0082","8F00FF"))