From 4656db4aa96512eb84991d32d9fb878688a179af Mon Sep 17 00:00:00 2001 From: Neerti Date: Sat, 7 May 2016 03:30:10 -0400 Subject: [PATCH 01/25] Adds PDA Multicaster Adds a new machine to telecomms, which contains special PDAs corresponding to each department on the station. Sending a PDA message to one of these PDAs will duplicate it to everyone in the department the PDA is assigned to. It determines what department someone is in by cartridge type. Adds cartridges for several jobs that were missing them, for the purposes of being recognized as being in a department. The cartridges otherwise do nothing. New circuitboard to build the new pda multicaster. It can also be deconstructed with the standard machinery deconstruction steps of screwdriver > crowbar. --- code/game/machinery/pda_multicaster.dm | 101 +++++++++++++++++ code/game/objects/items/devices/PDA/PDA.dm | 107 +++++++++++++++++- code/game/objects/items/devices/PDA/cart.dm | 54 +++++++++ .../circuitboards/machinery/telecomms.dm | 11 ++ maps/polaris-3.dmm | 3 +- polaris.dme | 1 + 6 files changed, 272 insertions(+), 5 deletions(-) create mode 100644 code/game/machinery/pda_multicaster.dm diff --git a/code/game/machinery/pda_multicaster.dm b/code/game/machinery/pda_multicaster.dm new file mode 100644 index 0000000000..a7d5c780c3 --- /dev/null +++ b/code/game/machinery/pda_multicaster.dm @@ -0,0 +1,101 @@ +/obj/machinery/pda_multicaster + name = "\improper PDA multicaster" + desc = "This machine mirrors messages sent to it to specific departments." + icon = 'icons/obj/stationobjs.dmi' + icon_state = "controller" + density = 1 + anchored = 1 + circuit = /obj/item/weapon/circuitboard/telecomms/pda_multicaster + use_power = 1 + idle_power_usage = 750 + var/on = 1 // If we're currently active, + var/toggle = 1 // If we /should/ be active or not, + var/list/internal_PDAs = list() // Assoc list of PDAs inside of this, with the department name being the index, + +/obj/machinery/pda_multicaster/New() + ..() + internal_PDAs = list("command" = new /obj/item/device/pda/multicaster/command(src), + "security" = new /obj/item/device/pda/multicaster/security(src), + "engineering" = new /obj/item/device/pda/multicaster/engineering(src), + "medical" = new /obj/item/device/pda/multicaster/medical(src), + "research" = new /obj/item/device/pda/multicaster/research(src), + "cargo" = new /obj/item/device/pda/multicaster/cargo(src), + "civilian" = new /obj/item/device/pda/multicaster/civilian(src)) + +/obj/machinery/pda_multicaster/prebuilt/New() + ..() + + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/telecomms/pda_multicaster(src) + component_parts += new /obj/item/weapon/stock_parts/subspace/ansible(src) + component_parts += new /obj/item/weapon/stock_parts/subspace/filter(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + component_parts += new /obj/item/weapon/stock_parts/subspace/treatment(src) + component_parts += new /obj/item/stack/cable_coil(src, 2) + RefreshParts() + +/obj/machinery/pda_multicaster/Destroy() + for(var/atom/movable/AM in contents) + qdel(AM) + ..() + +/obj/machinery/pda_multicaster/update_icon() + if(on) + icon_state = initial(icon_state) + else + icon_state = "[initial(icon_state)]-p" + +/obj/machinery/pda_multicaster/attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/weapon/screwdriver)) + default_deconstruction_screwdriver(user, I) + else if(istype(I, /obj/item/weapon/crowbar)) + default_deconstruction_crowbar(user, I) + else + ..() + +/obj/machinery/pda_multicaster/attack_ai(mob/user) + attack_hand(user) + +/obj/machinery/pda_multicaster/attack_hand(mob/user) + toggle_power(user) + +/obj/machinery/pda_multicaster/proc/toggle_power(mob/user) + toggle = !toggle + visible_message("\the [user] turns \the [src] [toggle ? "on" : "off"].") + update_power() + if(!toggle) + var/msg = "[usr.client.key] ([usr]) has turned [src] off, at [x],[y],[z]." + message_admins(msg) + log_game(msg) + +/obj/machinery/pda_multicaster/proc/update_PDAs(var/turn_off) + for(var/obj/item/device/pda/pda in contents) + pda.toff = turn_off + +/obj/machinery/pda_multicaster/proc/update_power() + if(toggle) + if(stat & (BROKEN|NOPOWER|EMPED)) + on = 0 + update_PDAs(1) // 1 being to turn off. + idle_power_usage = 0 + else + on = 1 + update_PDAs(0) + idle_power_usage = 750 + else + on = 0 + update_PDAs(1) + idle_power_usage = 0 + update_icon() + +/obj/machinery/pda_multicaster/process() + update_power() + +/obj/machinery/pda_multicaster/emp_act(severity) + if(!(stat & EMPED)) + stat |= EMPED + var/duration = (300 * 10)/severity + spawn(rand(duration - 20, duration + 20)) + stat &= ~EMPED + update_icon() + ..() diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index a3db6b15a1..f0bb82efd0 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -163,6 +163,7 @@ var/global/list/obj/item/device/pda/PDAs = list() /obj/item/device/pda/shaftminer icon_state = "pda-miner" + default_cartridge = /obj/item/weapon/cartridge/miner /obj/item/device/pda/syndicate default_cartridge = /obj/item/weapon/cartridge/syndicate @@ -172,6 +173,7 @@ var/global/list/obj/item/device/pda/PDAs = list() hidden = 1 /obj/item/device/pda/chaplain + default_cartridge = /obj/item/weapon/cartridge/service icon_state = "pda-holy" ttone = "holy" @@ -181,13 +183,15 @@ var/global/list/obj/item/device/pda/PDAs = list() ttone = "..." /obj/item/device/pda/botanist - //default_cartridge = /obj/item/weapon/cartridge/botanist + default_cartridge = /obj/item/weapon/cartridge/service icon_state = "pda-hydro" /obj/item/device/pda/roboticist + default_cartridge = /obj/item/weapon/cartridge/signal/science icon_state = "pda-robot" /obj/item/device/pda/librarian + default_cartridge = /obj/item/weapon/cartridge/service icon_state = "pda-libb" desc = "A portable microcomputer by Thinktronic Systems, LTD. This is model is a WGW-11 series e-reader." note = "Congratulations, your station has chosen the Thinktronic 5290 WGW-11 Series E-reader and Personal Data Assistant!" @@ -200,9 +204,11 @@ var/global/list/obj/item/device/pda/PDAs = list() note = "Congratulations, you have chosen the Thinktronic 5230 Personal Data Assistant Deluxe Special Max Turbo Limited Edition!" /obj/item/device/pda/chef + default_cartridge = /obj/item/weapon/cartridge/service icon_state = "pda-chef" /obj/item/device/pda/bar + default_cartridge = /obj/item/weapon/cartridge/service icon_state = "pda-bar" /obj/item/device/pda/atmos @@ -304,6 +310,99 @@ var/global/list/obj/item/device/pda/PDAs = list() ttone = "assist" +// Used for the PDA multicaster, which mirrors messages sent to it to a specific department, +/obj/item/device/pda/multicaster + ownjob = "Relay" + icon_state = "NONE" + ttone = "data" + detonate = 0 + news_silent = 1 + var/list/cartridges_to_send_to = list() + +// This is what actually mirrors the message, +/obj/item/device/pda/multicaster/new_message(var/sending_unit, var/sender, var/sender_job, var/message) + if(sender) + var/list/targets = list() + for(var/obj/item/device/pda/pda in PDAs) + if(pda.cartridge && pda.owner && is_type_in_list(pda.cartridge, cartridges_to_send_to)) + targets |= pda + if(targets.len) + for(var/obj/item/device/pda/target in targets) + create_message(target, sender, sender_job, message) + +// This has so much copypasta, +/obj/item/device/pda/multicaster/create_message(var/obj/item/device/pda/P, var/original_sender, var/original_job, var/t) + t = sanitize(t, MAX_MESSAGE_LEN, 0) + t = replace_characters(t, list(""" = "\"")) + if (!t || !istype(P)) + return + + if (isnull(P)||P.toff || toff) + return + + last_text = world.time + var/datum/reception/reception = get_reception(src, P, t) + t = reception.message + + if(reception.message_server && (reception.telecomms_reception & TELECOMMS_RECEPTION_SENDER)) // only send the message if it's stable, + if(reception.telecomms_reception & TELECOMMS_RECEPTION_RECEIVER == 0) // Does our recipient have a broadcaster on their level?, + return + var/send_result = reception.message_server.send_pda_message("[P.owner]","[owner]","[t]") + if (send_result) + return + + P.tnote.Add(list(list("sent" = 0, "owner" = "[owner]", "job" = "[ownjob]", "message" = "[t]", "target" = "\ref[src]"))) + + if(!P.conversations.Find("\ref[src]")) + P.conversations.Add("\ref[src]") + + P.new_message(src, "[original_sender] \[Relayed\]", original_job, t, 0) + + else + return + +/obj/item/device/pda/multicaster/command/New() + ..() + owner = "Command Department" + name = "Command Department (Relay)" + cartridges_to_send_to = command_cartridges + +/obj/item/device/pda/multicaster/security/New() + ..() + owner = "Security Department" + name = "Security Department (Relay)" + cartridges_to_send_to = security_cartridges + +/obj/item/device/pda/multicaster/engineering/New() + ..() + owner = "Engineering Department" + name = "Engineering Department (Relay)" + cartridges_to_send_to = engineering_cartridges + +/obj/item/device/pda/multicaster/medical/New() + ..() + owner = "Medical Department" + name = "Medical Department (Relay)" + cartridges_to_send_to = medical_cartridges + +/obj/item/device/pda/multicaster/research/New() + ..() + owner = "Research Department" + name = "Research Department (Relay)" + cartridges_to_send_to = research_cartridges + +/obj/item/device/pda/multicaster/cargo/New() + ..() + owner = "Cargo Department" + name = "Cargo Department (Relay)" + cartridges_to_send_to = cargo_cartridges + +/obj/item/device/pda/multicaster/civilian/New() + ..() + owner = "Civilian Services Department" + name = "Civilian Services Department (Relay)" + cartridges_to_send_to = civilian_cartridges + /* * The Actual PDA */ @@ -932,7 +1031,7 @@ var/global/list/obj/item/device/pda/PDAs = list() message += "Your [P] bleeps loudly." j = prob(10) - if(j) //This kills the PDA + if(j && detonate) //This kills the PDA qdel(P) if(message) message += "It melts in a puddle of plastic." @@ -1046,8 +1145,8 @@ var/global/list/obj/item/device/pda/PDAs = list() /obj/item/device/pda/proc/new_message_from_pda(var/obj/item/device/pda/sending_device, var/message) new_message(sending_device, sending_device.owner, sending_device.ownjob, message) -/obj/item/device/pda/proc/new_message(var/sending_unit, var/sender, var/sender_job, var/message) - var/reception_message = "\icon[src] Message from [sender] ([sender_job]), \"[message]\" (Reply)" +/obj/item/device/pda/proc/new_message(var/sending_unit, var/sender, var/sender_job, var/message, var/reply = 1) + var/reception_message = "\icon[src] Message from [sender] ([sender_job]), \"[message]\" ([reply ? "Reply" : "Unable to Reply"])" new_info(message_silent, ttone, reception_message) log_pda("[usr] (PDA: [sending_unit]) sent \"[message]\" to [name]") diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index 5d576959fb..a0e37e28b8 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -1,3 +1,48 @@ +var/list/command_cartridges = list( + /obj/item/weapon/cartridge/captain, + /obj/item/weapon/cartridge/hop, + /obj/item/weapon/cartridge/hos, + /obj/item/weapon/cartridge/ce, + /obj/item/weapon/cartridge/rd, + /obj/item/weapon/cartridge/head, + /obj/item/weapon/cartridge/lawyer // Internal Affaris, + ) + +var/list/security_cartridges = list( + /obj/item/weapon/cartridge/security, + /obj/item/weapon/cartridge/detective, + /obj/item/weapon/cartridge/hos + ) + +var/list/engineering_cartridges = list( + /obj/item/weapon/cartridge/engineering, + /obj/item/weapon/cartridge/atmos, + /obj/item/weapon/cartridge/ce + ) + +var/list/medical_cartridges = list( + /obj/item/weapon/cartridge/medical, + /obj/item/weapon/cartridge/chemistry, + /obj/item/weapon/cartridge/cmo + ) + +var/list/research_cartridges = list( + /obj/item/weapon/cartridge/signal/science, + /obj/item/weapon/cartridge/rd + ) + +var/list/cargo_cartridges = list( + /obj/item/weapon/cartridge/quartermaster, // This also covers cargo-techs, apparently, + /obj/item/weapon/cartridge/miner, + /obj/item/weapon/cartridge/hop + ) + +var/list/civilian_cartridges = list( + /obj/item/weapon/cartridge/janitor, + /obj/item/weapon/cartridge/service, + /obj/item/weapon/cartridge/hop + ) + /obj/item/weapon/cartridge name = "generic cartridge" desc = "A data cartridge for portable microcomputers." @@ -98,6 +143,10 @@ access_flora = 1 */ +/obj/item/weapon/cartridge/service + name = "\improper Serv-U Pro" + desc = "A data cartridge designed to serve YOU!" + /obj/item/weapon/cartridge/signal name = "generic signaler cartridge" desc = "A data cartridge with an integrated radio signaler module." @@ -124,6 +173,11 @@ icon_state = "cart-q" access_quartermaster = 1 +/obj/item/weapon/cartridge/miner + name = "\improper Drill-Jockey 4.5" + desc = "It's covered in some sort of sand." + icon_state = "cart-q" + /obj/item/weapon/cartridge/head name = "\improper Easy-Record DELUXE" icon_state = "cart-h" diff --git a/code/game/objects/items/weapons/circuitboards/machinery/telecomms.dm b/code/game/objects/items/weapons/circuitboards/machinery/telecomms.dm index 43b654d58d..8a7516f476 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/telecomms.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/telecomms.dm @@ -87,3 +87,14 @@ /obj/item/weapon/stock_parts/subspace/crystal = 1, /obj/item/weapon/stock_parts/subspace/treatment = 2, /obj/item/stack/cable_coil = 2) + +/obj/item/weapon/circuitboard/telecomms/pda_multicaster + name = T_BOARD("pda multicaster") + build_path = "/obj/machinery/pda_multicaster" + origin_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 2, TECH_BLUESPACE = 2) + req_components = list( + /obj/item/weapon/stock_parts/subspace/ansible = 1, + /obj/item/weapon/stock_parts/subspace/filter = 1, + /obj/item/weapon/stock_parts/manipulator = 1, + /obj/item/weapon/stock_parts/subspace/treatment = 1, + /obj/item/stack/cable_coil = 2) diff --git a/maps/polaris-3.dmm b/maps/polaris-3.dmm index 3e4489a897..b9a4285c6d 100644 --- a/maps/polaris-3.dmm +++ b/maps/polaris-3.dmm @@ -233,6 +233,7 @@ "ey" = (/obj/machinery/airlock_sensor/airlock_interior{frequency = 1381; id_tag = "server_access_in_sensor"; name = "interior sensor"; pixel_y = 25},/obj/structure/sign/securearea{desc = "A warning sign which reads 'SERVER ROOM'."; name = "SERVER ROOM"; pixel_y = 32},/turf/simulated/floor/bluegrid{name = "Mainframe Base"; nitrogen = 100; oxygen = 0; temperature = 80},/area/tcommsat/chamber) "ez" = (/turf/simulated/floor/tiled/dark{nitrogen = 100; oxygen = 0; temperature = 80},/area/tcommsat/chamber) "eA" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'SERVER ROOM'."; name = "SERVER ROOM"; pixel_y = 32},/turf/simulated/floor/bluegrid{name = "Mainframe Base"; nitrogen = 100; oxygen = 0; temperature = 80},/area/tcommsat/chamber) +"eB" = (/obj/machinery/pda_multicaster/prebuilt,/turf/simulated/floor/tiled/dark{nitrogen = 100; oxygen = 0; temperature = 80},/area/tcommsat/chamber) "eC" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled,/area/tcomsat) "eD" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/lattice,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/space,/area/tcomsat) "eE" = (/obj/machinery/atmospherics/pipe/simple/hidden/black,/turf/simulated/floor/tiled/dark{nitrogen = 100; oxygen = 0; temperature = 80},/area/tcommsat/chamber) @@ -541,7 +542,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYaaaaaTaTaTaTaTaTaTaTaTcecgcfclclcncncnefdSfldGfmfofnfpewfqfhfxewfsfrftfudGfvfwdyfIfyfzfAclclchcgciaTaTaTaTaTaTaTaTaTaaaabYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYaaaaaTaaaaaaaaaaaaaTaabqaabqclclcocncocRdScXdGerfEfDezeEezerezeEezfFfGerdGcRemfHfLfJfKfMclclbqaabqaaaTaaaaaaaaaaaaaTaaaabYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYaacacacacacacacacacacabqaabqclclcocncocReVcXdGerezezezeEezerezeEezezezerdGcRemcXeLfNfOfPclclbqaabqcacacacacacacacacacaaabYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYaTcbcbcbcbcbcbcbcbcbcbboaTbqclclcocncocRdScXdGerfRfQfTfSezezezfUfWfVfXerdGcRemcXfYeFeHclclclbqaTblccccccccccccccccccccaTbYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYaTcbcbcbcbcbcbcbcbcbcbboaTbqclclcocncocRdScXdGerfRfQfTfSezeBezfUfWfVfXerdGcRemcXfYeFeHclclclbqaTblccccccccccccccccccccaTbYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYaacdcdcdcdcdcdcdcdcdcdaaaabqclclcocncocRdScXdGerererfZerergaerergberererdGcRemcXcocncoclclbtboaaaacdcdcdcdcdcdcdcdcdcdaabYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTaaaaaaaaaaaaaTaaaaaabqclclcneecnefeVcIdGdGdGdGdGdGdGdGdGdGdGdGdGdGdGefemcIcneecnclclbqaaaaaaaaaTaaaaaaaaaaaaaTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYbYbYbYbYbYbYbYbYbYaaaabqclclcocncocReVgdgedkdkgfgggcgighglgjgmgfdkdkgngoemcXcocncoclclbqaaaaaabYbYbYbYbYbYbYbYbYbYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/polaris.dme b/polaris.dme index 2dc731c0ef..982294a786 100644 --- a/polaris.dme +++ b/polaris.dme @@ -406,6 +406,7 @@ #include "code\game\machinery\nuclear_bomb.dm" #include "code\game\machinery\OpTable.dm" #include "code\game\machinery\overview.dm" +#include "code\game\machinery\pda_multicaster.dm" #include "code\game\machinery\portable_turret.dm" #include "code\game\machinery\recharger.dm" #include "code\game\machinery\rechargestation.dm" From 12a3924bcf19495a5c5303d7709156fdd08e29ce Mon Sep 17 00:00:00 2001 From: Yoshax Date: Thu, 12 May 2016 14:01:21 +0100 Subject: [PATCH 02/25] Updates changelog --- html/changelog.html | 11 +++++ html/changelogs/.all_changelog.yml | 14 +++++++ html/changelogs/Yoshax - featuresandfixes.txt | 40 ------------------- html/changelogs/Yoshax - smokefix.yml | 37 ----------------- 4 files changed, 25 insertions(+), 77 deletions(-) delete mode 100644 html/changelogs/Yoshax - featuresandfixes.txt delete mode 100644 html/changelogs/Yoshax - smokefix.yml diff --git a/html/changelog.html b/html/changelog.html index 38b2166002..3ef596ac8c 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -53,6 +53,17 @@ -->
+

12 May 2016

+

Yoshax updated:

+
    +
  • Doubles the maximum length of records and names to 6144 & 52, respectively. Also increases book length to 12288. (All numbers are in characters.)
  • +
  • Makes various services in the antag uplink purchasable once again. This includes the fake crew arrival.
  • +
  • Neckgrabs will no longer force people to the ground. In addition, weakened people can no longer resist.
  • +
  • All vending machines now have a small chance of vending an additional item.
  • +
  • Smoke from smoke bombs now lasts approximately 3 times as long and spawns some more smoke to make a heavier cloud.
  • +
  • Smoke from smoke bombs now properly does a small amount of oxygen loss damage. This damage is per cloud of smoke.
  • +
+

05 May 2016

Datraen updated:

" - //src << browse(output,"window=playersetup;size=210x280;can_close=0") - panel = new(src, "New Player","New Player", 210, 280, src) + panel = new(src, "Welcome","Welcome", 210, 280, src) panel.set_window_options("can_close=0") panel.set_content(output) panel.open() From e5b863de9902bae1de34a4b48046aa6d3fa22330 Mon Sep 17 00:00:00 2001 From: Yoshax Date: Thu, 12 May 2016 20:08:43 +0100 Subject: [PATCH 12/25] Changelings will now store and use the flavor text of their victims --- .../game/gamemodes/changeling/absorbed_dna.dm | 6 ++-- .../gamemodes/changeling/changeling_powers.dm | 2 +- .../gamemodes/changeling/powers/absorb.dm | 2 +- .../gamemodes/changeling/powers/transform.dm | 4 +-- .../Yoshax - changelingflavortext.yml | 36 +++++++++++++++++++ 5 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 html/changelogs/Yoshax - changelingflavortext.yml diff --git a/code/game/gamemodes/changeling/absorbed_dna.dm b/code/game/gamemodes/changeling/absorbed_dna.dm index bdf243b412..3c23f0270c 100644 --- a/code/game/gamemodes/changeling/absorbed_dna.dm +++ b/code/game/gamemodes/changeling/absorbed_dna.dm @@ -4,11 +4,13 @@ var/speciesName var/list/languages var/identifying_gender + var/list/flavour_texts -/datum/absorbed_dna/New(var/newName, var/newDNA, var/newSpecies, var/newLanguages, var/newIdentifying_Gender) +/datum/absorbed_dna/New(var/newName, var/newDNA, var/newSpecies, var/newLanguages, var/newIdentifying_Gender, var/list/newFlavour) ..() name = newName dna = newDNA speciesName = newSpecies languages = newLanguages - identifying_gender = newIdentifying_Gender \ No newline at end of file + identifying_gender = newIdentifying_Gender + flavour_texts = newFlavour ? newFlavour.Copy() : null \ No newline at end of file diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm index ae5ede1566..a89fe95d95 100644 --- a/code/game/gamemodes/changeling/changeling_powers.dm +++ b/code/game/gamemodes/changeling/changeling_powers.dm @@ -85,7 +85,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E var/mob/living/carbon/human/H = src if(istype(H)) - var/datum/absorbed_dna/newDNA = new(H.real_name, H.dna, H.species.name, H.languages, H.identifying_gender) + var/datum/absorbed_dna/newDNA = new(H.real_name, H.dna, H.species.name, H.languages, H.identifying_gender, H.flavor_texts) absorbDNA(newDNA) return 1 diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm index 16f34357b5..e75020fc59 100644 --- a/code/game/gamemodes/changeling/powers/absorb.dm +++ b/code/game/gamemodes/changeling/powers/absorb.dm @@ -71,7 +71,7 @@ src.verbs += /mob/proc/changeling_respec src << "We can now re-adapt, reverting our evolution so that we may start anew, if needed." - var/datum/absorbed_dna/newDNA = new(T.real_name, T.dna, T.species.name, T.languages) + var/datum/absorbed_dna/newDNA = new(T.real_name, T.dna, T.species.name, T.languages, T.identifying_gender, T.flavor_texts) absorbDNA(newDNA) if(T.mind && T.mind.changeling) diff --git a/code/game/gamemodes/changeling/powers/transform.dm b/code/game/gamemodes/changeling/powers/transform.dm index 0eec3ed213..57a55e2e21 100644 --- a/code/game/gamemodes/changeling/powers/transform.dm +++ b/code/game/gamemodes/changeling/powers/transform.dm @@ -37,11 +37,9 @@ if(ishuman(src)) var/mob/living/carbon/human/H = src H.b_type = "AB+" //For some reason we have two blood types on the mob. - for(var/flavor in H.flavor_texts) //Nulls out flavor text, so we don't keep our previous mob's flavor. - flavor = null H.identifying_gender = chosen_dna.identifying_gender + H.flavor_texts = chosen_dna.flavour_texts ? chosen_dna.flavour_texts.Copy() : null src.real_name = chosen_dna.name - src.flavor_text = "" src.UpdateAppearance() domutcheck(src, null) changeling_update_languages(changeling.absorbed_languages) diff --git a/html/changelogs/Yoshax - changelingflavortext.yml b/html/changelogs/Yoshax - changelingflavortext.yml new file mode 100644 index 0000000000..430ab2d979 --- /dev/null +++ b/html/changelogs/Yoshax - changelingflavortext.yml @@ -0,0 +1,36 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Yoshax + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Changelings will now store and apply the flavor text of their victims when they absorb and transform into them." From b6848460e397604b646d61e17a0080362560e4ff Mon Sep 17 00:00:00 2001 From: Yoshax Date: Thu, 12 May 2016 22:24:40 +0100 Subject: [PATCH 13/25] Gives Diona pay the same as Taj and Unathi --- code/modules/economy/economy_misc.dm | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/code/modules/economy/economy_misc.dm b/code/modules/economy/economy_misc.dm index 8c39fcac8d..1e87b98e4c 100644 --- a/code/modules/economy/economy_misc.dm +++ b/code/modules/economy/economy_misc.dm @@ -48,11 +48,12 @@ /var/list/economic_species_modifier = list( - /datum/species/human = 10, - /datum/species/skrell = 12, - /datum/species/teshari = 9, // Skrell sponsored, - /datum/species/tajaran = 7, - /datum/species/unathi = 7 + /datum/species/human = 10, + /datum/species/skrell = 12, + /datum/species/teshari = 9, // Skrell sponsored, + /datum/species/tajaran = 7, + /datum/species/unathi = 7, + /datum/species/diona = 7 ) //---- The following corporations are friendly with NanoTrasen and loosely enable trade and travel: From 6ba19239b2bdf0f38c04f3f118db77a45b5c7683 Mon Sep 17 00:00:00 2001 From: Yoshax Date: Thu, 12 May 2016 22:26:37 +0100 Subject: [PATCH 14/25] Adds changelog --- html/changelogs/Yoshax - dionarights.yml | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 html/changelogs/Yoshax - dionarights.yml diff --git a/html/changelogs/Yoshax - dionarights.yml b/html/changelogs/Yoshax - dionarights.yml new file mode 100644 index 0000000000..705a4dbbaa --- /dev/null +++ b/html/changelogs/Yoshax - dionarights.yml @@ -0,0 +1,36 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Yoshax + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Gives Diona a starting funds wage the same as Tajaran and Unathi." \ No newline at end of file From ab9871968fddfe552c37c1d1e21f4d7504da5534 Mon Sep 17 00:00:00 2001 From: Yoshax Date: Fri, 13 May 2016 00:37:00 +0100 Subject: [PATCH 15/25] Fixes ignored preferences not being saved between rounds --- polaris.dme | 1 + 1 file changed, 1 insertion(+) diff --git a/polaris.dme b/polaris.dme index 8412712f64..11d173eaa4 100644 --- a/polaris.dme +++ b/polaris.dme @@ -998,6 +998,7 @@ #include "code\modules\client\preference_setup\global\02_settings.dm" #include "code\modules\client\preference_setup\global\03_pai.dm" #include "code\modules\client\preference_setup\global\04_communicators.dm" +#include "code\modules\client\preference_setup\global\05_ooc.dm" #include "code\modules\client\preference_setup\global\setting_datums.dm" #include "code\modules\client\preference_setup\loadout\gear_tweaks.dm" #include "code\modules\client\preference_setup\loadout\loadout.dm" From 3e184d7982728cac35f884ba9b68494e0cbbb82c Mon Sep 17 00:00:00 2001 From: Yoshax Date: Fri, 13 May 2016 01:04:56 +0100 Subject: [PATCH 16/25] Removes ability to ignore yourself --- code/modules/client/preference_setup/global/05_ooc.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/modules/client/preference_setup/global/05_ooc.dm b/code/modules/client/preference_setup/global/05_ooc.dm index 08aa97836a..9a25cd64f1 100644 --- a/code/modules/client/preference_setup/global/05_ooc.dm +++ b/code/modules/client/preference_setup/global/05_ooc.dm @@ -32,6 +32,9 @@ var/player_to_ignore = input(user, "Who do you want to ignore?","Ignore") as null|text if(player_to_ignore) player_to_ignore = sanitize(ckey(player_to_ignore)) + if(player_to_ignore == user.ckey) + user <<"You can't ignore yourself." + return TOPIC_REFRESH pref.ignored_players |= player_to_ignore return TOPIC_REFRESH From 45b888fbfbe2bfbe8791840d215a6476c60c7554 Mon Sep 17 00:00:00 2001 From: Anewbe Date: Thu, 12 May 2016 19:08:23 -0500 Subject: [PATCH 17/25] Alters Unathi biology --- .../Chemistry-Reagents-Dispenser.dm | 18 +++++ .../Chemistry-Reagents-Food-Drinks.dm | 67 +++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm index 26b58eed31..4c3e461a27 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm @@ -375,6 +375,24 @@ /datum/reagent/sugar/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.nutrition += removed * 3 + var/effective_dose = dose + if(issmall(M)) + effective_dose *= 2 + + if(alien == IS_UNATHI) + if(effective_dose < 2) + if(effective_dose == metabolism * 2 || prob(5)) + M.emote("yawn") + else if(effective_dose < 5) + M.eye_blurry = max(M.eye_blurry, 10) + else if(effective_dose < 20) + if(prob(50)) + M.Weaken(2) + M.drowsyness = max(M.drowsyness, 20) + else + M.sleeping = max(M.sleeping, 20) + M.drowsyness = max(M.drowsyness, 60) + /datum/reagent/sulfur name = "Sulfur" id = "sulfur" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm index 637470e7cc..be96e6665a 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -17,6 +17,8 @@ affect_ingest(M, alien, removed) /datum/reagent/nutriment/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + switch(alien) + if(IS_UNATHI) removed *= 0.5 if(issmall(M)) removed *= 2 // Small bodymass, more effect from lower volume. M.heal_organ_damage(0.5 * removed, 0) M.nutrition += nutriment_factor * removed // For hunger and fatness @@ -42,6 +44,8 @@ if(IS_TESHARI) ..(M, alien, removed*1.2) // Teshari get a bit more nutrition from meat. return + if(IS_UNATHI) + ..(M, alien, removed*2.25) //Unathi get most of their nutrition from meat. ..() /datum/reagent/nutriment/protein/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) @@ -62,6 +66,27 @@ nutriment_factor = 10 color = "#FFFF00" +/datum/reagent/honey/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + ..() + + var/effective_dose = dose + if(issmall(M)) + effective_dose *= 2 + + if(alien == IS_UNATHI) + if(effective_dose < 2) + if(effective_dose == metabolism * 2 || prob(5)) + M.emote("yawn") + else if(effective_dose < 5) + M.eye_blurry = max(M.eye_blurry, 10) + else if(effective_dose < 20) + if(prob(50)) + M.Weaken(2) + M.drowsyness = max(M.drowsyness, 20) + else + M.sleeping = max(M.sleeping, 20) + M.drowsyness = max(M.drowsyness, 60) + /datum/reagent/nutriment/flour name = "flour" id = "flour" @@ -396,6 +421,27 @@ glass_name = "glass of grape juice" glass_desc = "It's grrrrrape!" +/datum/reagent/juice/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + ..() + + var/effective_dose = dose/2 + if(issmall(M)) + effective_dose *= 2 + + if(alien == IS_UNATHI) + if(effective_dose < 2) + if(effective_dose == metabolism * 2 || prob(5)) + M.emote("yawn") + else if(effective_dose < 5) + M.eye_blurry = max(M.eye_blurry, 10) + else if(effective_dose < 20) + if(prob(50)) + M.Weaken(2) + M.drowsyness = max(M.drowsyness, 20) + else + M.sleeping = max(M.sleeping, 20) + M.drowsyness = max(M.drowsyness, 60) + /datum/reagent/drink/juice/lemon name = "Lemon Juice" id = "lemonjuice" @@ -765,6 +811,27 @@ glass_desc = "Glorious brainfreezing mixture." glass_center_of_mass = list("x"=16, "y"=7) +/datum/reagent/milkshake/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + ..() + + var/effective_dose = dose/2 + if(issmall(M)) + effective_dose *= 2 + + if(alien == IS_UNATHI) + if(effective_dose < 2) + if(effective_dose == metabolism * 2 || prob(5)) + M.emote("yawn") + else if(effective_dose < 5) + M.eye_blurry = max(M.eye_blurry, 10) + else if(effective_dose < 20) + if(prob(50)) + M.Weaken(2) + M.drowsyness = max(M.drowsyness, 20) + else + M.sleeping = max(M.sleeping, 20) + M.drowsyness = max(M.drowsyness, 60) + /datum/reagent/drink/rewriter name = "Rewriter" description = "The secret of the sanctuary of the Libarian..." From 75b1f53141f9e0d245704b4956bc8dfe140229fc Mon Sep 17 00:00:00 2001 From: Yoshax Date: Fri, 13 May 2016 01:16:44 +0100 Subject: [PATCH 18/25] Comments out ignore and unignoring in character setup, properly removes ability to ignore yourself --- code/game/verbs/ignore.dm | 4 ++++ code/modules/client/preference_setup/global/05_ooc.dm | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/code/game/verbs/ignore.dm b/code/game/verbs/ignore.dm index b772bd4e81..c154628087 100644 --- a/code/game/verbs/ignore.dm +++ b/code/game/verbs/ignore.dm @@ -10,6 +10,10 @@ if(key_to_ignore in prefs.ignored_players) usr << "[key_to_ignore] is already being ignored." return + if(key_to_ignore == usr.ckey) + usr <<"You can't ignore yourself." + return + prefs.ignored_players |= key_to_ignore prefs.save_preferences() usr << "Now ignoring [key_to_ignore]." diff --git a/code/modules/client/preference_setup/global/05_ooc.dm b/code/modules/client/preference_setup/global/05_ooc.dm index 9a25cd64f1..1b9d45dc89 100644 --- a/code/modules/client/preference_setup/global/05_ooc.dm +++ b/code/modules/client/preference_setup/global/05_ooc.dm @@ -9,7 +9,7 @@ /datum/category_item/player_setup_item/player_global/ooc/save_preferences(var/savefile/S) S["ignored_players"] << pref.ignored_players - +/* /datum/category_item/player_setup_item/player_global/ooc/sanitize_preferences() if(isnull(pref.ignored_players)) pref.ignored_players = list() @@ -39,3 +39,4 @@ return TOPIC_REFRESH return ..() +*/ \ No newline at end of file From 939073a0d22a5c9bf957e834c459e2a55ea447b6 Mon Sep 17 00:00:00 2001 From: Yoshax Date: Fri, 13 May 2016 01:34:19 +0100 Subject: [PATCH 19/25] Adds click cooldown to display case --- code/game/objects/structures/displaycase.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 8ce2a88f24..2dcb1ddaad 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -55,6 +55,9 @@ /obj/structure/displaycase/attackby(obj/item/weapon/W as obj, mob/user as mob) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + user.do_attack_animation(src) + playsound(loc, 'sound/effects/Glasshit.ogg', 50, 1) src.health -= W.force src.healthcheck() ..() From 804fc11d0a780c883684644e1a4bcfe51ed3fe4e Mon Sep 17 00:00:00 2001 From: Yoshax Date: Fri, 13 May 2016 02:01:46 +0100 Subject: [PATCH 20/25] Brain damage no longer prevents implant removal surgery --- code/modules/surgery/implant.dm | 8 ++++-- html/changelogs/Yoshax - surgeryfix.yml | 36 +++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 html/changelogs/Yoshax - surgeryfix.yml diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm index f178a6a45b..7ea873c8d0 100644 --- a/code/modules/surgery/implant.dm +++ b/code/modules/surgery/implant.dm @@ -153,8 +153,12 @@ max_duration = 100 can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/internal/brain/sponge = target.internal_organs_by_name["brain"] - return ..() && (!sponge || !sponge.damage) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(affected.organ_tag == BP_HEAD) + var/obj/item/organ/internal/brain/sponge = target.internal_organs_by_name["brain"] + return ..() && (!sponge || !sponge.damage) + else + return ..() begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) diff --git a/html/changelogs/Yoshax - surgeryfix.yml b/html/changelogs/Yoshax - surgeryfix.yml new file mode 100644 index 0000000000..af529c37df --- /dev/null +++ b/html/changelogs/Yoshax - surgeryfix.yml @@ -0,0 +1,36 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Yoshax + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - bugfix: "Brain damage no longer prevent implant removal surgery." From 24f7c0ca2cac15f9aa55e32b50ec4162d563dfb3 Mon Sep 17 00:00:00 2001 From: Yoshax Date: Fri, 13 May 2016 02:51:40 +0100 Subject: [PATCH 21/25] Fixes not being able to stop wounds from bleeding --- code/modules/organs/wound.dm | 40 +++++++++++++++--------------------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/code/modules/organs/wound.dm b/code/modules/organs/wound.dm index 3cf3ecb239..2c97bf4cfc 100644 --- a/code/modules/organs/wound.dm +++ b/code/modules/organs/wound.dm @@ -13,6 +13,8 @@ var/damage = 0 // ticks of bleeding left. var/bleed_timer = 0 + // Above this amount wounds you will need to treat the wound to stop bleeding, regardless of bleed_timer + var/bleed_threshold = 30 // amount of damage the current wound type requires(less means we need to apply the next healing stage) var/min_damage = 0 @@ -187,7 +189,7 @@ return 0 //incompatible damage types if (src.amount > 1) - return 0 + return 0//merged wounds cannot be worsened. //with 1.5*, a shallow cut will be able to carry at most 30 damage, //37.5 for a deep cut @@ -208,8 +210,8 @@ if (bandaged||clamped) return 0 - if (wound_damage() <= 30 && bleed_timer <= 0) - return 0 //Bleed timer has run out. Wounds with more than 30 damage don't stop bleeding on their own. + if (bleed_timer <= 0 && wound_damage() <= bleed_threshold) + return 0 //Bleed timer has run out. Once a wound is big enough though, you'll need a bandage to stop it return 1 @@ -264,8 +266,9 @@ return null //no wound /** CUTS **/ -/datum/wound/cut/bleeding() - return ..() || wound_damage() >= 5 +/datum/wound/cut + bleed_threshold = 5 + damage_type = CUT /datum/wound/cut/small // link wound descriptions to amounts of damage @@ -273,40 +276,34 @@ // The major cut types have the max_bleeding_stage set to the clot stage (which is accordingly given the "blood soaked" descriptor). max_bleeding_stage = 3 stages = list("ugly ripped cut" = 20, "ripped cut" = 10, "cut" = 5, "healing cut" = 2, "small scab" = 0) - damage_type = CUT /datum/wound/cut/deep max_bleeding_stage = 3 stages = list("ugly deep ripped cut" = 25, "deep ripped cut" = 20, "deep cut" = 15, "clotted cut" = 8, "scab" = 2, "fresh skin" = 0) - damage_type = CUT /datum/wound/cut/flesh max_bleeding_stage = 4 stages = list("ugly ripped flesh wound" = 35, "ugly flesh wound" = 30, "flesh wound" = 25, "blood soaked clot" = 15, "large scab" = 5, "fresh skin" = 0) - damage_type = CUT /datum/wound/cut/gaping max_bleeding_stage = 3 stages = list("gaping wound" = 50, "large blood soaked clot" = 25, "blood soaked clot" = 15, "small angry scar" = 5, "small straight scar" = 0) - damage_type = CUT /datum/wound/cut/gaping_big max_bleeding_stage = 3 stages = list("big gaping wound" = 60, "healing gaping wound" = 40, "large blood soaked clot" = 25, "large angry scar" = 10, "large straight scar" = 0) - damage_type = CUT datum/wound/cut/massive max_bleeding_stage = 3 stages = list("massive wound" = 70, "massive healing wound" = 50, "massive blood soaked clot" = 25, "massive angry scar" = 10, "massive jagged scar" = 0) - damage_type = CUT /** PUNCTURES **/ +/datum/wound/puncture + bleed_threshold = 5 + damage_type = PIERCE + /datum/wound/puncture/can_worsen(damage_type, damage) - return 0 -/datum/wound/puncture/can_merge(var/datum/wound/other) - return 0 -/datum/wound/puncture/bleeding() - return ..() || wound_damage() >= 5 + return 0 //puncture wounds cannot be enlargened /datum/wound/puncture/small max_bleeding_stage = 2 @@ -334,41 +331,36 @@ datum/wound/puncture/massive damage_type = PIERCE /** BRUISES **/ -/datum/wound/bruise/bleeding() - return ..() || wound_damage() >= 20 - /datum/wound/bruise stages = list("monumental bruise" = 80, "huge bruise" = 50, "large bruise" = 30, "moderate bruise" = 20, "small bruise" = 10, "tiny bruise" = 5) + bleed_threshold = 20 max_bleeding_stage = 3 //only large bruise and above can bleed. autoheal_cutoff = 30 damage_type = BRUISE /** BURNS **/ /datum/wound/burn + damage_type = BURN max_bleeding_stage = 0 + /datum/wound/burn/bleeding() return 0 /datum/wound/burn/moderate stages = list("ripped burn" = 10, "moderate burn" = 5, "healing moderate burn" = 2, "fresh skin" = 0) - damage_type = BURN /datum/wound/burn/large stages = list("ripped large burn" = 20, "large burn" = 15, "healing large burn" = 5, "fresh skin" = 0) - damage_type = BURN /datum/wound/burn/severe stages = list("ripped severe burn" = 35, "severe burn" = 30, "healing severe burn" = 10, "burn scar" = 0) - damage_type = BURN /datum/wound/burn/deep stages = list("ripped deep burn" = 45, "deep burn" = 40, "healing deep burn" = 15, "large burn scar" = 0) - damage_type = BURN /datum/wound/burn/carbonised stages = list("carbonised area" = 50, "healing carbonised area" = 20, "massive burn scar" = 0) - damage_type = BURN /** INTERNAL BLEEDING **/ /datum/wound/internal_bleeding From 4c04c6d2b2992c54925d3881f1b697b1465c6d67 Mon Sep 17 00:00:00 2001 From: Datraen Date: Thu, 12 May 2016 22:21:47 -0400 Subject: [PATCH 22/25] Catches a missing removal of the circuit board. --- code/game/machinery/kitchen/microwave.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/kitchen/microwave.dm b/code/game/machinery/kitchen/microwave.dm index 7f82a34f1c..831edadcbf 100644 --- a/code/game/machinery/kitchen/microwave.dm +++ b/code/game/machinery/kitchen/microwave.dm @@ -327,7 +327,7 @@ src.updateUsrDialog() /obj/machinery/microwave/proc/dispose() - for (var/obj/O in (contents-component_parts)) + for (var/obj/O in ((contents-component_parts)-circuit)) O.loc = src.loc if (src.reagents.total_volume) src.dirty++ From 6c9346d0c4d7a8f1f6e5c293dd091fa0ba26d2d6 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Sat, 14 May 2016 21:09:21 -0400 Subject: [PATCH 23/25] Prevent Unexpected SQL Errors (#1628) * Don't nag me, game. * Added disabled message, made config consistent * Missed adding 'else' --- code/controllers/configuration.dm | 4 ++-- code/world.dm | 8 ++++++-- config/example/config.txt | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index bd817baf41..d456c52e71 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -21,7 +21,7 @@ var/list/gamemode_cache = list() var/log_pda = 0 // log pda messages var/log_hrefs = 0 // logs all links clicked in-game. Could be used for debugging and tracking down exploits var/log_runtime = 0 // logs world.log to a file - var/sql_enabled = 1 // for sql switching + var/sql_enabled = 0 // for sql switching var/allow_admin_ooccolor = 0 // Allows admins with relevant permissions to have their own ooc colour var/allow_vote_restart = 0 // allow votes to restart var/ert_admin_call_only = 0 @@ -289,7 +289,7 @@ var/list/gamemode_cache = list() config.log_access = 1 if ("sql_enabled") - config.sql_enabled = text2num(value) + config.sql_enabled = 1 if ("log_say") config.log_say = 1 diff --git a/code/world.dm b/code/world.dm index b81c0f7c3a..bfa399fe2a 100644 --- a/code/world.dm +++ b/code/world.dm @@ -558,7 +558,9 @@ var/failed_db_connections = 0 var/failed_old_db_connections = 0 /hook/startup/proc/connectDB() - if(!setup_database_connection()) + if(!config.sql_enabled) + world.log << "SQL connection disabled in config." + else if(!setup_database_connection()) world.log << "Your server failed to establish a connection with the feedback database." else world.log << "Feedback database connection established." @@ -600,7 +602,9 @@ proc/establish_db_connection() /hook/startup/proc/connectOldDB() - if(!setup_old_database_connection()) + if(!config.sql_enabled) + world.log << "SQL connection disabled in config." + else if(!setup_old_database_connection()) world.log << "Your server failed to establish a connection with the SQL database." else world.log << "SQL database connection established." diff --git a/config/example/config.txt b/config/example/config.txt index b38bfd7354..ec93429827 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -67,8 +67,8 @@ LOG_PDA ## log admin warning messages ##LOG_ADMINWARN ## Also duplicates a bunch of other messages. -## sql switching -# SQL_ENABLED +## Enable/disable SQL connection (comment out to disable) +SQL_ENABLED ## disconnect players who did nothing during the set amount of minutes # KICK_INACTIVE 10 From 5958a4a585a09062d2ad0e8aa006df01fb648cb9 Mon Sep 17 00:00:00 2001 From: Yoshax Date: Sun, 15 May 2016 13:57:47 +0100 Subject: [PATCH 24/25] Removes tags from blue carpet --- code/game/turfs/flooring/flooring.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/turfs/flooring/flooring.dm b/code/game/turfs/flooring/flooring.dm index 369f42fc38..ad7a0f91ce 100644 --- a/code/game/turfs/flooring/flooring.dm +++ b/code/game/turfs/flooring/flooring.dm @@ -69,7 +69,7 @@ var/list/flooring_types name = "carpet" icon_base = "bcarpet" build_type = null - flags = TURF_HAS_EDGES | TURF_HAS_CORNERS | TURF_REMOVE_CROWBAR | TURF_CAN_BURN + flags = TURF_HAS_EDGES | TURF_REMOVE_CROWBAR /decl/flooring/tiling name = "floor" From f09df76e4a55a64cf92c7ed0a575f35e2546634c Mon Sep 17 00:00:00 2001 From: Hubblenaut Date: Sun, 15 May 2016 15:38:10 +0200 Subject: [PATCH 25/25] Hacktool (#1607) * Adds hacking tool. In normal mode a hacking tool acts and functions just like any multitool. Use a screwdriver to toggle between normal and hacking mode. Hacking attempts will take 20 +(0 to 20) seconds (triangular distribution, averages at +10 seconds). Once an airlock has been successfully hacked the user will have full access to the door operation interface normally restricted to silicons. A hacking tool will remember the last 6 to 8 hacked airlocks. No time is needed to again hack remembered airlocks. Once the limit has been reached the least recently accessed airlock is forgotten. Hacking a remembered airlock will update the last accessed time. Also adds a basic observer/listener pattern implementation to, for example, make it easier to catch when objects have been destroyed and clear references. * Corrects and adds more sanity checking. * Adds hacktool to uplink devices --- code/_macros.dm | 2 + code/controllers/hooks-defs.dm | 174 +++++++++--------- .../observer_listener/atom/observer.dm | 31 ++++ .../observer_listener/datum/observer.dm | 28 +++ code/game/objects/items/devices/hacktool.dm | 100 ++++++++++ code/game/objects/items/devices/multitool.dm | 2 +- .../objects/items/devices/uplink_items.dm | 8 + polaris.dme | 3 + 8 files changed, 260 insertions(+), 88 deletions(-) create mode 100644 code/controllers/observer_listener/atom/observer.dm create mode 100644 code/controllers/observer_listener/datum/observer.dm create mode 100644 code/game/objects/items/devices/hacktool.dm diff --git a/code/_macros.dm b/code/_macros.dm index 7e8d581b90..e8caac8345 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -7,6 +7,8 @@ #define isanimal(A) istype(A, /mob/living/simple_animal) +#define isairlock(A) istype(A, /obj/machinery/door/airlock) + #define isbrain(A) istype(A, /mob/living/carbon/brain) #define iscarbon(A) istype(A, /mob/living/carbon) diff --git a/code/controllers/hooks-defs.dm b/code/controllers/hooks-defs.dm index 001372b4e3..e330024475 100644 --- a/code/controllers/hooks-defs.dm +++ b/code/controllers/hooks-defs.dm @@ -1,87 +1,87 @@ -/** - * Startup hook. - * Called in world.dm when the server starts. - */ -/hook/startup - -/** - * Roundstart hook. - * Called in gameticker.dm when a round starts. - */ -/hook/roundstart - -/** - * Roundend hook. - * Called in gameticker.dm when a round ends. - */ -/hook/roundend - -/** - * Death hook. - * Called in death.dm when someone dies. - * Parameters: var/mob/living/carbon/human, var/gibbed - */ -/hook/death - -/** - * Cloning hook. - * Called in cloning.dm when someone is brought back by the wonders of modern science. - * Parameters: var/mob/living/carbon/human - */ -/hook/clone - -/** - * Debrained hook. - * Called in brain_item.dm when someone gets debrained. - * Parameters: var/obj/item/organ/brain - */ -/hook/debrain - -/** - * Borged hook. - * Called in robot_parts.dm when someone gets turned into a cyborg. - * Parameters: var/mob/living/silicon/robot - */ -/hook/borgify - -/** - * Podman hook. - * Called in podmen.dm when someone is brought back as a Diona. - * Parameters: var/mob/living/carbon/alien/diona - */ -/hook/harvest_podman - -/** - * Payroll revoked hook. - * Called in Accounts_DB.dm when someone's payroll is stolen at the Accounts terminal. - * Parameters: var/datum/money_account - */ -/hook/revoke_payroll - -/** - * Account suspension hook. - * Called in Accounts_DB.dm when someone's account is suspended or unsuspended at the Accounts terminal. - * Parameters: var/datum/money_account - */ -/hook/change_account_status - -/** - * Employee reassignment hook. - * Called in card.dm when someone's card is reassigned at the HoP's desk. - * Parameters: var/obj/item/weapon/card/id - */ -/hook/reassign_employee - -/** - * Employee terminated hook. - * Called in card.dm when someone's card is terminated at the HoP's desk. - * Parameters: var/obj/item/weapon/card/id - */ -/hook/terminate_employee - -/** - * Crate sold hook. - * Called in supplyshuttle.dm when a crate is sold on the shuttle. - * Parameters: var/obj/structure/closet/crate/sold, var/area/shuttle - */ -/hook/sell_crate +/** + * Startup hook. + * Called in world.dm when the server starts. + */ +/hook/startup + +/** + * Roundstart hook. + * Called in gameticker.dm when a round starts. + */ +/hook/roundstart + +/** + * Roundend hook. + * Called in gameticker.dm when a round ends. + */ +/hook/roundend + +/** + * Death hook. + * Called in death.dm when someone dies. + * Parameters: var/mob/living/carbon/human, var/gibbed + */ +/hook/death + +/** + * Cloning hook. + * Called in cloning.dm when someone is brought back by the wonders of modern science. + * Parameters: var/mob/living/carbon/human + */ +/hook/clone + +/** + * Debrained hook. + * Called in brain_item.dm when someone gets debrained. + * Parameters: var/obj/item/organ/brain + */ +/hook/debrain + +/** + * Borged hook. + * Called in robot_parts.dm when someone gets turned into a cyborg. + * Parameters: var/mob/living/silicon/robot + */ +/hook/borgify + +/** + * Podman hook. + * Called in podmen.dm when someone is brought back as a Diona. + * Parameters: var/mob/living/carbon/alien/diona + */ +/hook/harvest_podman + +/** + * Payroll revoked hook. + * Called in Accounts_DB.dm when someone's payroll is stolen at the Accounts terminal. + * Parameters: var/datum/money_account + */ +/hook/revoke_payroll + +/** + * Account suspension hook. + * Called in Accounts_DB.dm when someone's account is suspended or unsuspended at the Accounts terminal. + * Parameters: var/datum/money_account + */ +/hook/change_account_status + +/** + * Employee reassignment hook. + * Called in card.dm when someone's card is reassigned at the HoP's desk. + * Parameters: var/obj/item/weapon/card/id + */ +/hook/reassign_employee + +/** + * Employee terminated hook. + * Called in card.dm when someone's card is terminated at the HoP's desk. + * Parameters: var/obj/item/weapon/card/id + */ +/hook/terminate_employee + +/** + * Crate sold hook. + * Called in supplyshuttle.dm when a crate is sold on the shuttle. + * Parameters: var/obj/structure/closet/crate/sold, var/area/shuttle + */ +/hook/sell_crate diff --git a/code/controllers/observer_listener/atom/observer.dm b/code/controllers/observer_listener/atom/observer.dm new file mode 100644 index 0000000000..da38580414 --- /dev/null +++ b/code/controllers/observer_listener/atom/observer.dm @@ -0,0 +1,31 @@ +#define OBSERVER_EVENT_DESTROY "OnDestroy" + +/atom + var/list/observer_events + +/atom/Destroy() + var/list/destroy_listeners = get_listener_list_from_event(OBSERVER_EVENT_DESTROY) + if(destroy_listeners) + for(var/destroy_listener in destroy_listeners) + call(destroy_listener, destroy_listeners[destroy_listener])(src) + + for(var/list/listeners in observer_events) + listeners.Cut() + + return ..() + +/atom/proc/register(var/event, var/procOwner, var/proc_call) + var/list/listeners = get_listener_list_from_event(event) + listeners[procOwner] = proc_call + +/atom/proc/unregister(var/event, var/procOwner) + var/list/listeners = get_listener_list_from_event(event) + listeners -= procOwner + +/atom/proc/get_listener_list_from_event(var/observer_event) + if(!observer_events) observer_events = list() + var/list/listeners = observer_events[observer_event] + if(!listeners) + listeners = list() + observer_events[observer_event] = listeners + return listeners diff --git a/code/controllers/observer_listener/datum/observer.dm b/code/controllers/observer_listener/datum/observer.dm new file mode 100644 index 0000000000..61f6fbf180 --- /dev/null +++ b/code/controllers/observer_listener/datum/observer.dm @@ -0,0 +1,28 @@ +/* +#define OBSERVER_EVENT_DESTROY "OnDestroy" + +/datum + var/list/observer_events + +/datum/Destroy() + for(var/list/listeners in observer_events) + listeners.Cut() + + return ..() + +/datum/proc/register(var/event, var/procOwner, var/proc_call) + var/list/listeners = get_listener_list_from_event(event) + listeners[procOwner] = proc_call + +/datum/proc/unregister(var/event, var/procOwner) + var/list/listeners = get_listener_list_from_event(event) + listeners -= procOwner + +/datum/proc/get_listener_list_from_event(var/observer_event) + if(!observer_events) observer_events = list() + var/list/listeners = observer_events[observer_event] + if(!listeners) + listeners = list() + observer_events[observer_event] = listeners + return listeners +*/ diff --git a/code/game/objects/items/devices/hacktool.dm b/code/game/objects/items/devices/hacktool.dm new file mode 100644 index 0000000000..0cf4af6c74 --- /dev/null +++ b/code/game/objects/items/devices/hacktool.dm @@ -0,0 +1,100 @@ +/obj/item/device/multitool/hacktool + var/is_hacking = 0 + var/max_known_targets + + var/in_hack_mode = 0 + var/list/known_targets + var/list/supported_types + var/datum/topic_state/default/must_hack/hack_state + +/obj/item/device/multitool/hacktool/New() + ..() + known_targets = list() + max_known_targets = 5 + rand(1,3) + supported_types = list(/obj/machinery/door/airlock) + hack_state = new(src) + +/obj/item/device/multitool/hacktool/Destroy() + for(var/T in known_targets) + var/atom/target = T + target.unregister(OBSERVER_EVENT_DESTROY, src) + known_targets.Cut() + qdel(hack_state) + hack_state = null + return ..() + +/obj/item/device/multitool/hacktool/attackby(var/obj/W, var/mob/user) + if(isscrewdriver(W)) + in_hack_mode = !in_hack_mode + playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) + else + ..() + +/obj/item/device/multitool/hacktool/resolve_attackby(atom/A, mob/user) + sanity_check() + + if(!in_hack_mode) + return ..() + + if(!attempt_hack(user, A)) + return 0 + + A.ui_interact(user, state = hack_state) + return 1 + +/obj/item/device/multitool/hacktool/proc/attempt_hack(var/mob/user, var/atom/target) + if(is_hacking) + user << "You are already hacking!" + return 0 + if(!is_type_in_list(target, supported_types)) + user << "\icon[src] Unable to hack this target!" + return 0 + var/found = known_targets.Find(target) + if(found) + known_targets.Swap(1, found) // Move the last hacked item first + return 1 + + user << "You begin hacking \the [target]..." + is_hacking = 1 + // On average hackin takes ~30 seconds. Fairly small random span to avoid people simply aborting and trying again + var/hack_result = do_after(user, (20 SECONDS + rand(0, 10 SECONDS) + rand(0, 10 SECONDS))) + is_hacking = 0 + + if(hack_result && in_hack_mode) + user << "Your hacking attempt was succesful!" + playsound(src.loc, 'sound/piano/A#6.ogg', 75) + else + user << "Your hacking attempt failed!" + return 0 + + known_targets.Insert(1, target) // Insert the newly hacked target first, + target.register(OBSERVER_EVENT_DESTROY, src, /obj/item/device/multitool/hacktool/proc/on_target_destroy) + return 1 + +/obj/item/device/multitool/hacktool/proc/sanity_check() + if(max_known_targets < 1) max_known_targets = 1 + // Cut away the oldest items if the capacity has been reached + if(known_targets.len > max_known_targets) + for(var/i = (max_known_targets + 1) to known_targets.len) + var/atom/A = known_targets[i] + A.unregister(OBSERVER_EVENT_DESTROY, src) + known_targets.Cut(max_known_targets + 1) + +/obj/item/device/multitool/hacktool/proc/on_target_destroy(var/target) + known_targets -= target + +/datum/topic_state/default/must_hack + var/obj/item/device/multitool/hacktool/hacktool + +/datum/topic_state/default/must_hack/New(var/hacktool) + src.hacktool = hacktool + ..() + +/datum/topic_state/default/must_hack/Destroy() + hacktool = null + return ..() + +/datum/topic_state/default/must_hack/can_use_topic(var/src_object, var/mob/user) + if(!hacktool || !hacktool.in_hack_mode || !(src_object in hacktool.known_targets)) + return STATUS_CLOSE + return ..() diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index 867e64f446..e7cb6f3475 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -20,4 +20,4 @@ origin_tech = list(TECH_MAGNET = 1, TECH_ENGINEERING = 1) var/obj/machinery/telecomms/buffer // simple machine buffer for device linkage - var/obj/machinery/clonepod/connecting //same for cryopod linkage \ No newline at end of file + var/obj/machinery/clonepod/connecting //same for cryopod linkage diff --git a/code/game/objects/items/devices/uplink_items.dm b/code/game/objects/items/devices/uplink_items.dm index bc9666990b..b0ee3689a1 100644 --- a/code/game/objects/items/devices/uplink_items.dm +++ b/code/game/objects/items/devices/uplink_items.dm @@ -411,6 +411,14 @@ datum/uplink_item/dd_SortValue() item_cost = 3 path = /obj/item/weapon/card/emag +/datum/uplink_item/item/tools/hacking_tool + name = "Door Hacking Tool" + item_cost = 2 + path = /obj/item/device/multitool/hacktool + desc = "Appears and functions as a standard multitool until the mode is toggled by applying a screwdriver appropriately. \ + When in hacking mode this device will grant full access to any standard airlock within 20 to 40 seconds. \ + This device will also be able to immediately access the last 6 to 8 hacked airlocks." + /datum/uplink_item/item/tools/clerical name = "Morphic Clerical Kit" item_cost = 3 diff --git a/polaris.dme b/polaris.dme index 588cc73c5c..fa49981699 100644 --- a/polaris.dme +++ b/polaris.dme @@ -127,6 +127,8 @@ #include "code\controllers\subsystems.dm" #include "code\controllers\verbs.dm" #include "code\controllers\voting.dm" +#include "code\controllers\observer_listener\atom\observer.dm" +#include "code\controllers\observer_listener\datum\observer.dm" #include "code\controllers\Processes\air.dm" #include "code\controllers\Processes\alarm.dm" #include "code\controllers\Processes\chemistry.dm" @@ -612,6 +614,7 @@ #include "code\game\objects\items\devices\flash.dm" #include "code\game\objects\items\devices\flashlight.dm" #include "code\game\objects\items\devices\floor_painter.dm" +#include "code\game\objects\items\devices\hacktool.dm" #include "code\game\objects\items\devices\lightreplacer.dm" #include "code\game\objects\items\devices\locker_painter.dm" #include "code\game\objects\items\devices\megaphone.dm"