diff --git a/code/defines/obj.dm b/code/defines/obj.dm index 2aa379fd695..66b16cbf4b9 100644 --- a/code/defines/obj.dm +++ b/code/defines/obj.dm @@ -115,6 +115,7 @@ var/t_loc = null var/obj/item/item = null var/place = null + var/internalloc = null /obj/effect/equip_e/human name = "human" diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index 38861503bba..86bc3f013a5 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -491,14 +491,25 @@ return var/jobName + var/list/accesses = list() if(istype(src, /obj/item/device/pda)) if(src:id) jobName = src:id:assignment + accesses = src:id:access if(istype(src, /obj/item/weapon/card/id)) jobName = src:assignment + accesses = src:access if(jobName in get_all_jobs()) return jobName + + var/centcom = 0 + for(var/i = 1, i <= accesses.len, i++) + if(accesses[i] > 100) + centcom = 1 + break + if(centcom) + return "centcom" else - return "Unknown" \ No newline at end of file + return "Unknown" diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm index 306431524df..d4e4ea682ab 100644 --- a/code/game/machinery/OpTable.dm +++ b/code/game/machinery/OpTable.dm @@ -1,6 +1,6 @@ /obj/machinery/optable - name = "Operating table" - desc = "Used for advanced medical procedures." + name = "Operating Table" + desc = "Used for advanced medical procedures. Apparently this includes the clown." icon = 'surgery.dmi' icon_state = "table2-idle" density = 1 @@ -10,139 +10,77 @@ active_power_usage = 5 var/mob/living/carbon/victim = null var/strapped = 0.0 + var/updatesicon = 1 var/obj/machinery/computer/operating/computer = null var/id = 0.0 -/obj/machinery/optable/New() - ..() - for(var/obj/machinery/computer/operating/O in world) - if(src.id == O.id) - src.computer = O - spawn(100) - process() + New() + ..() + if(id) + for(var/obj/machinery/computer/operating/O in world) + if(src.id == O.id) + src.computer = O -/obj/machinery/optable/ex_act(severity) - - switch(severity) - if(1.0) - //SN src = null - del(src) - return - if(2.0) - if (prob(50)) + ex_act(severity) + switch(severity) + if(1.0) //SN src = null del(src) return - if(3.0) - if (prob(25)) - src.density = 0 - else - return - -/obj/machinery/optable/blob_act() - if(prob(75)) - del(src) - -/obj/machinery/optable/hand_p(mob/user as mob) - - return src.attack_paw(user) - return - -/obj/machinery/optable/attack_paw(mob/user as mob) - if ((usr.mutations & HULK)) - usr << text("\blue You destroy the operating table.") - for(var/mob/O in oviewers()) - if ((O.client && !( O.blinded ))) - O << text("\red [usr] destroys the operating table.") - src.density = 0 - del(src) - if (!( locate(/obj/machinery/optable, user.loc) )) - step(user, get_dir(user, src)) - if (user.loc == src.loc) - user.layer = TURF_LAYER - for(var/mob/M in viewers(user, null)) - M.show_message("The monkey hides under the table!", 1) - //Foreach goto(69) - return - -/obj/machinery/optable/attack_hand(mob/user as mob) - if ((usr.mutations & HULK)) - usr << text("\blue You destroy the table.") - for(var/mob/O in oviewers()) - if ((O.client && !( O.blinded ))) - O << text("\red [usr] destroys the table.") - src.density = 0 - del(src) - return - -/obj/machinery/optable/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 - - if(istype(mover) && mover.checkpass(PASSTABLE)) - return 1 - else - return 0 - - -/obj/machinery/optable/MouseDrop_T(obj/O as obj, mob/user as mob) - - if ((!( istype(O, /obj/item/weapon) ) || user.equipped() != O)) + if(2.0) + if (prob(50)) + //SN src = null + del(src) + return + if(3.0) + if (prob(25)) + src.density = 0 + else return - user.drop_item() - if (O.loc != src.loc) - step(O, get_dir(O, src)) - return -/obj/machinery/optable/proc/check_victim() - if(locate(/mob/living/carbon, src.loc)) - var/mob/M = locate(/mob/living/carbon, src.loc) - if(M.resting) - src.victim = M - icon_state = "table2-active" + blob_act() + if(prob(75)) + del(src) + + hand_p(mob/user as mob) + return src.attack_paw(user) + return + + attack_paw(mob/user as mob) + if ((usr.mutations & HULK)) + usr << text("\blue You destroy the operating table.") + for(var/mob/O in oviewers()) + if ((O.client && !( O.blinded ))) + O << text("\red [usr] destroys the operating table.") + src.density = 0 + del(src) + if (!( locate(/obj/machinery/optable, user.loc) )) + step(user, get_dir(user, src)) + if (user.loc == src.loc) + user.layer = TURF_LAYER + for(var/mob/M in viewers(user, null)) + M.show_message("The monkey hides under the table!", 1) + //Foreach goto(69) + return + + attack_hand(mob/user as mob) + if ((usr.mutations & HULK)) + usr << text("\blue You destroy the table.") + for(var/mob/O in oviewers()) + if ((O.client && !( O.blinded ))) + O << text("\red [usr] destroys the table.") + src.density = 0 + del(src) + return + + CanPass(atom/movable/mover, turf/target, height=0, air_group=0) + if(air_group || (height==0)) return 1 + + if(istype(mover) && mover.checkpass(PASSTABLE)) return 1 - src.victim = null - icon_state = "table2-idle" - return 0 - -/obj/machinery/optable/process() - check_victim() - -/obj/machinery/optable/attackby(obj/item/weapon/W as obj, mob/user as mob) - - if (istype(W, /obj/item/weapon/grab)) - if(ismob(W:affecting)) - var/mob/M = W:affecting - if (M.client) - M.client.perspective = EYE_PERSPECTIVE - M.client.eye = src - M.resting = 1 - M.loc = src.loc - for (var/mob/C in viewers(src)) - C.show_message("\red [M] has been laid on the operating table by [user].", 3) - for(var/obj/O in src) - O.loc = src.loc - src.add_fingerprint(user) - icon_state = "table2-active" - src.victim = M - del(W) - return - user.drop_item() - if(W && W.loc) - W.loc = src.loc - return - -/obj/machinery/optable/portable - name = "Mobile operating table" - desc = "Used for advanced medical procedures. Seems to be movable, neat." - icon = 'rollerbed.dmi' - icon_state = "up" - density = 1 - anchored = 0 - - New() - ..() - processing_objects.Remove(src) + else + return 0 MouseDrop_T(obj/O as obj, mob/user as mob) if ((!( istype(O, /obj/item/weapon) ) || user.equipped() != O)) @@ -152,9 +90,24 @@ step(O, get_dir(O, src)) return + proc/check_victim() + if(locate(/mob/living/carbon, src.loc)) + var/mob/M = locate(/mob/living/carbon, src.loc) + if(M.resting) + src.victim = M + if(updatesicon) + icon_state = "table2-active" + return 1 + src.victim = null + if(updatesicon) + icon_state = "table2-idle" + processing_objects.Remove(src) + return 0 + + process() + check_victim() + attackby(obj/item/weapon/W as obj, mob/user as mob) - if(!anchored) - return if (istype(W, /obj/item/weapon/grab)) if(ismob(W:affecting)) var/mob/M = W:affecting @@ -168,6 +121,8 @@ for(var/obj/O in src) O.loc = src.loc src.add_fingerprint(user) + if(updatesicon) + icon_state = "table2-active" src.victim = M processing_objects.Add(src) del(W) @@ -177,15 +132,23 @@ W.loc = src.loc return - check_victim() - if(locate(/mob/living/carbon/human, src.loc)) - var/mob/M = locate(/mob/living/carbon/human, src.loc) - if(M.resting) - src.victim = M - return 1 - src.victim = null - processing_objects.Remove(src) - return 0 +/obj/machinery/optable/portable + name = "mobile operating Table" + desc = "Used for advanced medical procedures. Seems to be movable, neat." + icon = 'rollerbed.dmi' + icon_state = "up" + density = 1 + anchored = 0 + id = null + updatesicon = 0 + + New() + ..() + + attackby(obj/item/weapon/W as obj, mob/user as mob) + if(!anchored) + return + return ..() verb/make_deployable() set category = "Object" diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm index fcfa830ebef..91ae88093ea 100644 --- a/code/game/machinery/telecomms/broadcaster.dm +++ b/code/game/machinery/telecomms/broadcaster.dm @@ -62,7 +62,7 @@ machinetype = 6 heatgen = 0 var/intercept = 0 // if nonzero, broadcasts all messages to syndicate channel - var/syndi = 1 //If 1, it goes to syndicate frequency. Else, goes to deathsquad + var/syndi = 1 //If 1, it goes to syndicate frequency. Else, goes to deathsquad/Response Team receive_signal(datum/signal/signal) @@ -210,7 +210,7 @@ // --- Broadcast to response team radio! --- - else if(data == 3) + else if(data == 4) var/datum/radio_frequency/syndicateconnection = radio_controller.return_frequency(1439) for (var/obj/item/device/radio/R in syndicateconnection.devices["[RADIO_CHAT]"]) diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm index 8c1108ef89b..2fc5a6c975c 100644 --- a/code/game/machinery/telecomms/machine_interactions.dm +++ b/code/game/machinery/telecomms/machine_interactions.dm @@ -77,6 +77,9 @@ newpath = text2path(I) var/obj/item/s = new newpath s.loc = user.loc + if(istype(P, /obj/item/weapon/cable_coil)) + var/obj/item/weapon/cable_coil/A = P + A.amount = 1 // Drop a circuit board too C.loc = user.loc @@ -113,13 +116,16 @@ dat += "
Network: [network]" dat += "
Prefabrication: [autolinkers.len ? "TRUE" : "FALSE"]" dat += "
Linked Network Entities:
    " + + var/i = 0 for(var/obj/machinery/telecomms/T in links) - dat += "
  1. \ref[T] [T.name] ([T.id]) (X)
  2. " + i++ + dat += "
  3. \ref[T] [T.name] ([T.id]) \[X\]
  4. " dat += "
" dat += "
Filtering Frequencies: " - var/i = 0 + i = 0 if(length(freq_listening)) for(var/x in freq_listening) i++ @@ -197,6 +203,16 @@ temp = "-% Removed frequency filter [x] %-" freq_listening.Remove(x) + if(href_list["unlink"]) + + var/obj/machinery/telecomms/T = links[text2num(href_list["unlink"])] + temp = "-% Removed \ref[T] [T.name] from linked entities. %-" + + // Remove link entries from both T and src. + if(src in T.links) + T.links.Remove(src) + links.Remove(T) + if(href_list["link"]) if(P.buffer) @@ -222,13 +238,6 @@ temp = "-% Buffer successfully flushed. %-" P.buffer = null - if(href_list["remove"]) - - temp = "-% Link successfully removed. %-" - for(var/obj/machinery/telecomms/T in links) - if(T.id == href_list["remove"]) - src.links.Remove(T) - break usr.machine = src src.add_fingerprint(usr) diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index 8029addbfe3..9283f50e04c 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -283,13 +283,8 @@ the implant may become unstable and either pre-maturely inject the subject or si if(M.stat == 2) var/turf/t = get_turf(M) var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null) - var/mob/living/carbon/human/G = new /mob/living/carbon/human(null) - G.real_name = "[mobname]'s death alarm" - G.name = "[mobname]'s death alarm" - G.universal_speak = 1 - a.talk_into(G,"[mobname] has died in [t.loc.name]!") + a.autosay("[mobname] has died in [t.loc.name]!", "[mobname]'s Death Alarm") del(a) - del(G) processing_objects.Remove(src) diff --git a/code/game/objects/radio/radio.dm b/code/game/objects/radio/radio.dm index 1643c38ec3c..37d459777d7 100644 --- a/code/game/objects/radio/radio.dm +++ b/code/game/objects/radio/radio.dm @@ -183,6 +183,121 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use updateDialog() add_fingerprint(usr) +/obj/item/device/radio/proc/autosay(var/message, var/from, var/channel) + var/datum/radio_frequency/connection = null + if(channel && channels && channels.len > 0) + if (channel == "department") + //world << "DEBUG: channel=\"[channel]\" switching to \"[channels[1]]\"" + channel = channels[1] + connection = secure_radio_connections[channel] + else + connection = radio_connection + channel = null + if (!istype(connection)) + return + + if(subspace_transmission) + // First, we want to generate a new radio signal + var/datum/signal/signal = new + signal.transmission_method = 2 // 2 would be a subspace transmission. + // transmission_method could probably be enumerated through #define. Would be neater. + + // --- Finally, tag the actual signal with the appropriate values --- + signal.data = list( + // Identity-associated tags: + "mob" = new /mob/living/silicon/ai(src), // store a reference to the mob + "mobtype" = /mob/living/silicon/ai, // the mob's type + "realname" = from, // the mob's real name + "name" = from, // the mob's display name + "job" = "Automated Announcement", // the mob's job + "key" = "none", // the mob's key + "vmessage" = "*garbled automated announcement*", // the message to display if the voice wasn't understood + "vname" = "synthesized voice", // the name to display if the voice wasn't understood + "vmask" = 0, // 1 if the mob is using a voice gas mask + + // We store things that would otherwise be kept in the actual mob + // so that they can be logged even AFTER the mob is deleted or something + + // Other tags: + "compression" = rand(45,50), // compressed radio signal + "message" = message, // the actual sent message + "connection" = connection, // the radio connection to use + "radio" = src, // stores the radio used for transmission + "slow" = 0, // how much to sleep() before broadcasting - simulates net lag + "traffic" = 0 // dictates the total traffic sum that the signal went through + ) + signal.frequency = connection.frequency // Quick frequency set + + //#### Sending the signal to all subspace receivers ####// + for(var/obj/machinery/telecomms/receiver/R in world) + R.receive_signal(signal) + + // Allinone can act as receivers. + for(var/obj/machinery/telecomms/allinone/R in world) + R.receive_signal(signal) + + // Receiving code can be located in Telecommunications.dm + return + + + /* ###### Intercoms and station-bounced radios ###### */ + + var/filter_type = 2 + + /* --- Intercoms can only broadcast to other intercoms, but bounced radios can broadcast to bounced radios and intercoms --- */ + if(istype(src, /obj/item/device/radio/intercom)) + filter_type = 1 + + + var/datum/signal/signal = new + signal.transmission_method = 2 + + + /* --- Try to send a normal subspace broadcast first */ + + signal.data = list( + + "mob" = new /mob/living/silicon/ai(src), // store a reference to the mob + "mobtype" = /mob/living/silicon/ai, // the mob's type + "realname" = from, // the mob's real name + "name" = from, // the mob's display name + "job" = "Automated Announcement", // the mob's job + "key" = "none", // the mob's key + "vmessage" = "*garbled automated announcement*", // the message to display if the voice wasn't understood + "vname" = "synthesized voice", // the name to display if the voice wasn't understood + "vmask" = 0, // 1 if the mob is using a voice gas mask + + // We store things that would otherwise be kept in the actual mob + // so that they can be logged even AFTER the mob is deleted or something + + // Other tags: + "compression" = 0, // compressed radio signal + "message" = message, // the actual sent message + "connection" = connection, // the radio connection to use + "radio" = src, // stores the radio used for transmission + "slow" = 0, // how much to sleep() before broadcasting - simulates net lag + "traffic" = 0 // dictates the total traffic sum that the signal went through + ) + signal.frequency = connection.frequency // Quick frequency set + + for(var/obj/machinery/telecomms/receiver/R in world) + R.receive_signal(signal) + + + sleep(rand(10,25)) // wait a little... + + if(signal.data["done"]) + del(signal) // delete the signal - we're done here. + return + + // Oh my god; the comms are down or something because the signal hasn't been broadcasted yet. + // Send a mundane broadcast with limited targets: + + Broadcast_Message(connection, new /mob/living/silicon/ai(src), 0, "*garbled automated announcement*", + src, message, from, "Automated Announcement", from, "synthesized voice", + filter_type, signal.data["compression"]) + return + /obj/item/device/radio/talk_into(mob/M as mob, message, channel) if(GLOBAL_RADIO_TYPE == 1) // NEW RADIO SYSTEMS: By Doohl diff --git a/code/game/response_team.dm b/code/game/response_team.dm index 56fa9855282..87901a232a7 100644 --- a/code/game/response_team.dm +++ b/code/game/response_team.dm @@ -22,14 +22,12 @@ client/verb/JoinResponseTeam() var/new_name = input(usr, "Pick a name","Name") as null|text if(!new_name) return - var/gender = alert(usr, "Pick a gender","Gender","Male","Female") - - var/mob/living/carbon/human/new_commando = create_response_team(L, leader_selected, new_name, gender) + var/mob/living/carbon/human/new_commando = create_response_team(L, leader_selected, new_name) new_commando.mind.key = usr.key new_commando.key = usr.key - new_commando << "\blue You are [!leader_selected?"member":"LEADER"] of an armed response team in CentComm's service. Something went down on [station_name()] and they're now on code red. Go in there and fix the problem." + new_commando << "\blue You are [!leader_selected?" a member":" the LEADER"] of an armed response team in CentComm's service. Something went down on [station_name()] and they're now on code red. Go in there and fix the problem." new_commando << "You should first gear up and discuss a plan with your team. More members may be joining, don't move out before you're ready." else @@ -75,30 +73,105 @@ proc/trigger_armed_response_team() send_emergency_team = 1 -/client/proc/create_response_team(obj/spawn_location, leader_selected = 0, commando_name, gender) +/client/proc/create_response_team(obj/spawn_location, leader_selected = 0, commando_name) - var/mob/living/carbon/human/new_commando = new(spawn_location.loc) - new_commando.gender = ((gender == "Male") ? MALE : FEMALE) + var/mob/living/carbon/human/M = new(spawn_location.loc) - var/datum/preferences/A = new()//Randomize appearance for the commando. - A.randomize_appearance_for(new_commando) + var/new_facial = input("Please select facial hair color.", "Character Generation") as color + if(new_facial) + M.r_facial = hex2num(copytext(new_facial, 2, 4)) + M.g_facial = hex2num(copytext(new_facial, 4, 6)) + M.b_facial = hex2num(copytext(new_facial, 6, 8)) - new_commando.real_name = commando_name - new_commando.age = !leader_selected ? rand(23,35) : rand(35,45) + var/new_hair = input("Please select hair color.", "Character Generation") as color + if(new_facial) + M.r_hair = hex2num(copytext(new_hair, 2, 4)) + M.g_hair = hex2num(copytext(new_hair, 4, 6)) + M.b_hair = hex2num(copytext(new_hair, 6, 8)) - new_commando.dna.ready_dna(new_commando)//Creates DNA. + var/new_eyes = input("Please select eye color.", "Character Generation") as color + if(new_eyes) + M.r_eyes = hex2num(copytext(new_eyes, 2, 4)) + M.g_eyes = hex2num(copytext(new_eyes, 4, 6)) + M.b_eyes = hex2num(copytext(new_eyes, 6, 8)) + + var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation") as text + + if (new_tone) + M.s_tone = max(min(round(text2num(new_tone)), 220), 1) + M.s_tone = -M.s_tone + 35 + + // hair + var/list/all_hairs = typesof(/datum/sprite_accessory/hair) - /datum/sprite_accessory/hair + var/list/hairs = list() + + // loop through potential hairs + for(var/x in all_hairs) + var/datum/sprite_accessory/hair/H = new x // create new hair datum based on type x + hairs.Add(H.name) // add hair name to hairs + del(H) // delete the hair after it's all done + + var/new_style = input("Please select hair style", "Character Generation") as null|anything in hairs + + // if new style selected (not cancel) + if (new_style) + M.h_style = new_style + + for(var/x in all_hairs) // loop through all_hairs again. Might be slightly CPU expensive, but not significantly. + var/datum/sprite_accessory/hair/H = new x // create new hair datum + if(H.name == new_style) + M.hair_style = H // assign the hair_style variable a new hair datum + break + else + del(H) // if hair H not used, delete. BYOND can garbage collect, but better safe than sorry + + // facial hair + var/list/all_fhairs = typesof(/datum/sprite_accessory/facial_hair) - /datum/sprite_accessory/facial_hair + var/list/fhairs = list() + + for(var/x in all_fhairs) + var/datum/sprite_accessory/facial_hair/H = new x + fhairs.Add(H.name) + del(H) + + new_style = input("Please select facial style", "Character Generation") as null|anything in fhairs + + if(new_style) + M.f_style = new_style + for(var/x in all_fhairs) + var/datum/sprite_accessory/facial_hair/H = new x + if(H.name == new_style) + M.facial_hair_style = H + break + else + del(H) + + var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female") + if (new_gender) + if(new_gender == "Male") + M.gender = MALE + else + M.gender = FEMALE + M.update_body() + M.update_face() + M.update_clothing() + + M.real_name = commando_name + M.age = !leader_selected ? rand(23,35) : rand(35,45) + + M.dna.ready_dna(M)//Creates DNA. //Creates mind stuff. - new_commando.mind = new - new_commando.mind.current = new_commando - new_commando.mind.original = new_commando - new_commando.mind.assigned_role = "MODE" - new_commando.mind.special_role = "Response Team" - if(!(new_commando.mind in ticker.minds)) - ticker.minds += new_commando.mind//Adds them to regular mind list. - new_commando.equip_strike_team(leader_selected) + M.mind = new + M.mind.current = M + M.mind.original = M + M.mind.assigned_role = "MODE" + M.mind.special_role = "Response Team" + if(!(M.mind in ticker.minds)) + ticker.minds += M.mind//Adds them to regular mind list. + M.equip_strike_team(leader_selected) del(spawn_location) - return new_commando + return M /mob/living/carbon/human/proc/equip_strike_team(leader_selected = 0) @@ -117,10 +190,10 @@ proc/trigger_armed_response_team() camera.c_tag = real_name //Basic Uniform - equip_if_possible(new /obj/item/clothing/under/color/black(src), slot_w_uniform) + equip_if_possible(new /obj/item/clothing/under/syndicate/tacticool(src), slot_w_uniform) equip_if_possible(new /obj/item/device/flashlight(src), slot_l_store) equip_if_possible(new /obj/item/weapon/clipboard(src), slot_r_store) - equip_if_possible(new /obj/item/weapon/gun/energy/taser(src), slot_belt) + equip_if_possible(new /obj/item/weapon/gun/energy/gun(src), slot_belt) //Glasses equip_if_possible(new /obj/item/clothing/glasses/sunglasses/sechud(src), slot_glasses) @@ -144,7 +217,10 @@ proc/trigger_armed_response_team() var/obj/item/weapon/card/id/W = new(src) W.name = "[real_name]'s ID Card" W.icon_state = "centcom" - W.access = get_access("Head of Personnel") + if(leader_selected) + W.access = get_access("Captain") + else + W.access = get_access("Head of Personnel") W.access += list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage)//Let's add their alloted CentCom access. W.assignment = "Emergency Response Team" W.registered = real_name diff --git a/code/game/specops_shuttle.dm b/code/game/specops_shuttle.dm index 29179a7e17a..f05c6326cab 100644 --- a/code/game/specops_shuttle.dm +++ b/code/game/specops_shuttle.dm @@ -2,6 +2,7 @@ #define SPECOPS_MOVETIME 600 //Time to station is milliseconds. 60 seconds, enough time for everyone to be on the shuttle before it leaves. #define SPECOPS_STATION_AREATYPE "/area/shuttle/specops/station" //Type of the spec ops shuttle area for station #define SPECOPS_DOCK_AREATYPE "/area/shuttle/specops/centcom" //Type of the spec ops shuttle area for dock +#define SPECOPS_RETURN_DELAY 6000 //Time between the shuttle is capable of moving. var/specops_shuttle_moving_to_station = 0 var/specops_shuttle_moving_to_centcom = 0 @@ -18,18 +19,16 @@ var/specops_shuttle_timeleft = 0 var/temp = null var/hacked = 0 var/allowedtocall = 0 + var/specops_shuttle_timereset = 0 -/proc/specops_process() - var/area/centcom/control/cent_com = locate()//To find announcer. This area should exist for this proc to work. - var/area/centcom/specops/special_ops = locate()//Where is the specops area located? - var/mob/living/silicon/decoy/announcer = locate() in cent_com//We need a fake AI to announce some stuff below. Otherwise it will be wonky. +/proc/specops_return() + var/obj/item/device/radio/intercom/announcer = new /obj/item/device/radio/intercom(null)//We need a fake AI to announce some stuff below. Otherwise it will be wonky. + announcer.config(list("Response Team" = 0)) var/message_tracker[] = list(0,1,2,3,5,10,30,45)//Create a a list with potential time values. - var/message = "THE SPECIAL OPERATIONS SHUTTLE IS PREPARING FOR LAUNCH"//Initial message shown. + var/message = "THE SPECIAL OPERATIONS SHUTTLE IS PREPARING TO RETURN"//Initial message shown. if(announcer) - announcer.say(message) - message = "ARMORED SQUAD TAKE YOUR POSITION ON GRAVITY LAUNCH PAD" - announcer.say(message) + announcer.autosay(message, "A.L.I.C.E.", "Response Team") while(specops_shuttle_time - world.timeofday > 0) var/ticksleft = specops_shuttle_time - world.timeofday @@ -45,7 +44,76 @@ var/specops_shuttle_timeleft = 0 message = "ALERT: [rounded_time_left] SECOND[(rounded_time_left!=1)?"S":""] REMAIN" if(rounded_time_left==0) message = "ALERT: TAKEOFF" - announcer.say(message) + announcer.autosay(message, "A.L.I.C.E.", "Response Team") + message_tracker -= rounded_time_left//Remove the number from the list so it won't be called again next cycle. + //Should call all the numbers but lag could mean some issues. Oh well. Not much I can do about that. + + sleep(5) + + specops_shuttle_moving_to_station = 0 + specops_shuttle_moving_to_centcom = 0 + + specops_shuttle_at_station = 1 + + var/area/start_location = locate(/area/shuttle/specops/station) + var/area/end_location = locate(/area/shuttle/specops/centcom) + + var/list/dstturfs = list() + var/throwy = world.maxy + + for(var/turf/T in end_location) + dstturfs += T + if(T.y < throwy) + throwy = T.y + + // hey you, get out of the way! + for(var/turf/T in dstturfs) + // find the turf to move things to + var/turf/D = locate(T.x, throwy - 1, 1) + //var/turf/E = get_step(D, SOUTH) + for(var/atom/movable/AM as mob|obj in T) + AM.Move(D) + if(istype(T, /turf/simulated)) + del(T) + + start_location.move_contents_to(end_location) + + for(var/turf/T in get_area_turfs(end_location) ) + var/mob/M = locate(/mob) in T + M << "\red You have arrived at Central Command. Operation has ended!" + + for(var/obj/machinery/computer/specops_shuttle/S in world) + S.specops_shuttle_timereset = world.time + SPECOPS_RETURN_DELAY + + del(announcer) + +/proc/specops_process() + var/area/centcom/specops/special_ops = locate()//Where is the specops area located? + var/obj/item/device/radio/intercom/announcer = new /obj/item/device/radio/intercom(null)//We need a fake AI to announce some stuff below. Otherwise it will be wonky. + announcer.config(list("Response Team" = 0)) + + var/message_tracker[] = list(0,1,2,3,5,10,30,45)//Create a a list with potential time values. + var/message = "THE SPECIAL OPERATIONS SHUTTLE IS PREPARING FOR LAUNCH"//Initial message shown. + if(announcer) + announcer.autosay(message, "A.L.I.C.E.", "Response Team") + message = "ARMORED SQUAD TAKE YOUR POSITION ON GRAVITY LAUNCH PAD" + announcer.autosay(message, "A.L.I.C.E.", "Response Team") + + while(specops_shuttle_time - world.timeofday > 0) + var/ticksleft = specops_shuttle_time - world.timeofday + + if(ticksleft > 1e5) + specops_shuttle_time = world.timeofday + 10 // midnight rollover + specops_shuttle_timeleft = (ticksleft / 10) + + //All this does is announce the time before launch. + if(announcer) + var/rounded_time_left = round(specops_shuttle_timeleft)//Round time so that it will report only once, not in fractions. + if(rounded_time_left in message_tracker)//If that time is in the list for message announce. + message = "ALERT: [rounded_time_left] SECOND[(rounded_time_left!=1)?"S":""] REMAIN" + if(rounded_time_left==0) + message = "ALERT: TAKEOFF" + announcer.autosay(message, "A.L.I.C.E.", "Response Team") message_tracker -= rounded_time_left//Remove the number from the list so it won't be called again next cycle. //Should call all the numbers but lag could mean some issues. Oh well. Not much I can do about that. @@ -155,9 +223,18 @@ var/specops_shuttle_timeleft = 0 var/mob/M = locate(/mob) in T M << "\red You have arrived to [station_name]. Commence operation!" + for(var/obj/machinery/computer/specops_shuttle/S in world) + S.specops_shuttle_timereset = world.time + SPECOPS_RETURN_DELAY + + del(announcer) + /proc/specops_can_move() - if(specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) return 0 - else return 1 + if(specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) + return 0 + for(var/obj/machinery/computer/specops_shuttle/S in world) + if(world.time <= S.specops_shuttle_timereset) + return 0 + return 1 /obj/machinery/computer/specops_shuttle/attack_ai(var/mob/user as mob) return attack_hand(user) @@ -190,7 +267,7 @@ var/specops_shuttle_timeleft = 0 else dat += {"
Special Operations Shuttle
\nLocation: [specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom ? "Departing for [station_name] in ([specops_shuttle_timeleft] seconds.)":specops_shuttle_at_station ? "Station":"Dock"]
- [specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom ? "\n*The Special Ops. shuttle is already leaving.*
\n
":specops_shuttle_at_station ? "\nShuttle Offline
\n
":"\nDepart to [station_name]
\n
"] + [specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom ? "\n*The Special Ops. shuttle is already leaving.*
\n
":specops_shuttle_at_station ? "\nShuttle standing by...
\n
":"\nDepart to [station_name]
\n
"] \nClose"} user << browse(dat, "window=computer;size=575x450") @@ -207,8 +284,23 @@ var/specops_shuttle_timeleft = 0 if (href_list["sendtodock"]) if(!specops_shuttle_at_station|| specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) return - usr << "\blue Central Command will not allow the Special Operations shuttle to return." - return + if (!specops_can_move()) + usr << "\blue Central Command will not allow the Special Operations shuttle to return yet." + if(world.time <= specops_shuttle_timereset) + if (((world.time - specops_shuttle_timereset)/10) > 60) + usr << "\blue [-((world.time - specops_shuttle_timereset)/10)/60] minutes remain!" + usr << "\blue [-(world.time - specops_shuttle_timereset)/10] seconds remain!" + return + + usr << "\blue The Special Operations shuttle will arrive at Central Command in [(SPECOPS_MOVETIME/10)] seconds." + + temp += "Shuttle departing.

OK" + updateUsrDialog() + + specops_shuttle_moving_to_centcom = 1 + specops_shuttle_time = world.timeofday + SPECOPS_MOVETIME + spawn(0) + specops_return() else if (href_list["sendtostation"]) if(specops_shuttle_at_station || specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) return diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 7f2942be4b0..2c3aa31f76e 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -480,6 +480,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that "assassin", "death commando", "syndicate commando", + "response team", "centcom official", "centcom commander", "special ops officer", @@ -677,6 +678,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that if("syndicate commando") M.equip_syndicate_commando() + if("response team") + M.equip_strike_team() + if("centcom official") M.equip_if_possible(new /obj/item/clothing/under/rank/centcom_officer(M), M.slot_w_uniform) M.equip_if_possible(new /obj/item/clothing/shoes/black(M), M.slot_shoes) @@ -686,7 +690,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that var/obj/item/clothing/glasses/sunglasses/V = new(M) V.loc = K M.equip_if_possible(K, M.slot_wear_suit) - M.equip_if_possible(new /obj/item/weapon/gun/energy(M), M.slot_s_store) + M.equip_if_possible(new /obj/item/weapon/gun/energy/gun(M), M.slot_s_store) var/obj/item/device/pda/heads/pda = new(M) pda.owner = M.real_name diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 60500eef49a..a8f7ee216f5 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -2118,11 +2118,11 @@ It can still be worn/put on as normal. if (!( istype(target.wear_mask, /obj/item/clothing/mask) )) return else - if (istype(target.back, /obj/item/weapon/tank)) + if (istype(target.back, /obj/item/weapon/tank) && (internalloc == "back" || !internalloc)) target.internal = target.back - else if (istype(target.s_store, /obj/item/weapon/tank)) + else if (istype(target.s_store, /obj/item/weapon/tank) && (internalloc == "store" || !internalloc)) target.internal = target.s_store - else if (istype(target.belt, /obj/item/weapon/tank)) + else if (istype(target.belt, /obj/item/weapon/tank) && (internalloc == "belt" || !internalloc)) target.internal = target.belt if (target.internal) for(var/mob/M in viewers(target, 1)) @@ -2160,14 +2160,14 @@ It can still be worn/put on as normal.
Right Ear: [(r_ear ? r_ear : "Nothing")]
Head: [(head ? head : "Nothing")]
Shoes: [(shoes ? shoes : "Nothing")] -
Belt: [(belt ? belt : "Nothing")] +
Belt: [(belt ? belt : "Nothing")] [(istype(wear_mask, /obj/item/clothing/mask) && istype(belt, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : ""]
Uniform: [(w_uniform ? w_uniform : "Nothing")]
(Exo)Suit: [(wear_suit ? wear_suit : "Nothing")] -
Back: [(back ? back : "Nothing")] +
Back: [(back ? back : "Nothing")][(istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : ""]
ID: [(wear_id ? wear_id : "Nothing")] -
Suit Storage: [(s_store ? s_store : "Nothing")] +
Suit Storage: [(s_store ? s_store : "Nothing")] [(istype(wear_mask, /obj/item/clothing/mask) && istype(s_store, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : ""]
[(handcuffed ? text("Handcuffed") : text("Not Handcuffed"))] -
[(internal ? text("Remove Internal") : ((istype(wear_mask, /obj/item/clothing/mask) && (istype(back, /obj/item/weapon/tank) || istype(belt, /obj/item/weapon/tank) || istype(s_store, /obj/item/weapon/tank)) && !( internal )) ? text(" Set Internal", src) : ""))] +
[(internal ? text("Remove Internal") : "")]
Empty Pockets
Empty Hat
Refresh @@ -2341,6 +2341,8 @@ It can still be worn/put on as normal. O.s_loc = usr.loc O.t_loc = loc O.place = href_list["item"] + if(href_list["loc"]) + O.internalloc = href_list["loc"] requests += O spawn( 0 ) O.process() diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index af2c6097c03..6d3ac0648ee 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -270,15 +270,9 @@ proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank) if (ticker.current_state == GAME_STATE_PLAYING) - var/ailist[] = list() - for (var/mob/living/silicon/ai/A in world) - if (!A.stat) - ailist += A - if (ailist.len) - var/mob/living/silicon/ai/announcer = pick(ailist) - if(character.mind) - if((character.mind.assigned_role != "Cyborg") && (character.mind.special_role != "MODE")) - announcer.say("[character.real_name] has signed up as [rank].") + var/obj/item/device/radio/intercom/a = new /obj/item/device/radio/intercom(null) + a.autosay("[character.real_name] has arrived on the station.", "Arrivals Announcement Computer") + del(a) proc/ManifestLateSpawn(var/mob/living/carbon/human/H, icon/H_icon) // Attempted fix to add late joiners to various databases -- TLE diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 92ba2cb0c05..5c759614b59 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -37,6 +37,18 @@ for(var/obj/O in contents) O.emp_act(severity) + attack(mob/living/M as mob, mob/living/user as mob, def_zone) + if (M == user && user.zone_sel.selecting == "mouth" && load_into_chamber()) + M.visible_message("\red [user] sticks their gun in their mouth, ready to pull the trigger...") + if(!do_after(user, 40)) + M.visible_message("\blue [user] decided life was worth living") + return + M.visible_message("\red [user] pulls the trigger.") + M.apply_damage(70, BRUTE, "head") + M.apply_damage(110, BRUTE, "chest") + return + else + return ..() afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag, params)//TODO: go over this if(flag) return //we're placing gun on a table or in backpack diff --git a/code/stylesheet.dm b/code/stylesheet.dm index 0cc4bfb71e9..077a64b60da 100644 --- a/code/stylesheet.dm +++ b/code/stylesheet.dm @@ -94,7 +94,8 @@ h1, h2, h3, h4, h5, h6 .comradio { - color: #ACA82D; + color:#FF9900; + text-decoration: underline; } .syndradio diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index 8fe609fbb67..e7425bb46c3 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ