From 91def7da637cfe17ec3cc19da88ff56fdbfc7fed Mon Sep 17 00:00:00 2001 From: Markolie Date: Fri, 13 Feb 2015 14:25:54 +0100 Subject: [PATCH 01/13] Fix meter --- code/game/machinery/atmoalter/meter.dm | 45 ++++++++++++-------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/code/game/machinery/atmoalter/meter.dm b/code/game/machinery/atmoalter/meter.dm index 42518697027..c7bc14c65d3 100644 --- a/code/game/machinery/atmoalter/meter.dm +++ b/code/game/machinery/atmoalter/meter.dm @@ -24,23 +24,15 @@ /obj/machinery/meter/process() if(!target) icon_state = "meterX" - // Pop the meter off when the pipe we're attached to croaks. - new /obj/item/pipe_meter(src.loc) - spawn(0) del(src) return 0 if(stat & (BROKEN|NOPOWER)) icon_state = "meter0" return 0 - //use_power(5) - var/datum/gas_mixture/environment = target.return_air() if(!environment) icon_state = "meterX" - // Pop the meter off when the environment we're attached to croaks. - new /obj/item/pipe_meter(src.loc) - spawn(0) del(src) return 0 var/env_pressure = environment.return_pressure() @@ -87,28 +79,31 @@ return t /obj/machinery/meter/examine() - set src in view(3) - var/t = "A gas flow meter. " - t += status() + + if(get_dist(usr, src) > 3 && !(istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/dead))) + t += "\blue You are too far away to read it." + + else if(stat & (NOPOWER|BROKEN)) + t += "\red The display is off." + + else if(src.target) + var/datum/gas_mixture/environment = target.return_air() + if(environment) + t += "The pressure gauge reads [round(environment.return_pressure(), 0.01)] kPa; [round(environment.temperature,0.01)]K ([round(environment.temperature-T0C,0.01)]°C)" + else + t += "The sensor error light is blinking." + else + t += "The connect error light is blinking." + usr << t - - /obj/machinery/meter/Click() - - if(stat & (NOPOWER|BROKEN)) + if(istype(usr, /mob/living/silicon/ai)) // ghosts can call ..() for examine + usr.examine(src) return 1 - - var/t = null - if (get_dist(usr, src) <= 3 || istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/dead)) - t += status() - else - usr << "\blue You are too far away." - return 1 - - usr << t - return 1 + + return ..() /obj/machinery/meter/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) if (!istype(W, /obj/item/weapon/wrench)) From 71319538df5f487692d8825e64a28d8f8002c324 Mon Sep 17 00:00:00 2001 From: Markolie Date: Fri, 13 Feb 2015 15:27:42 +0100 Subject: [PATCH 02/13] Vending machine overhaul, teleporter area fix, add events to status tab --- code/datums/wires/vending.dm | 13 +- code/datums/wires/wires.dm | 7 +- code/game/machinery/teleporter.dm | 3 +- code/game/machinery/vending.dm | 615 ++++++++++++++++------------ code/modules/economy/Accounts.dm | 4 +- code/modules/mob/mob.dm | 1 + nano/templates/vending_machine.tmpl | 56 +++ 7 files changed, 418 insertions(+), 281 deletions(-) create mode 100644 nano/templates/vending_machine.tmpl diff --git a/code/datums/wires/vending.dm b/code/datums/wires/vending.dm index c0c76cd89ae..574c7961e09 100644 --- a/code/datums/wires/vending.dm +++ b/code/datums/wires/vending.dm @@ -1,3 +1,5 @@ +#define CAT_HIDDEN 2 // Also in code/game/machinery/vending.dm + /datum/wires/vending holder_type = /obj/machinery/vending wire_count = 4 @@ -17,17 +19,12 @@ var/const/VENDING_WIRE_IDSCAN = 8 return 1 return 0 -/datum/wires/vending/Interact(var/mob/living/user) - if(CanUse(user)) - var/obj/machinery/vending/V = holder - V.attack_hand(user) - /datum/wires/vending/GetInteractWindow() var/obj/machinery/vending/V = holder . += ..() . += "
The orange light is [V.seconds_electrified ? "on" : "off"].
" . += "The red light is [V.shoot_inventory ? "off" : "blinking"].
" - . += "The green light is [V.extended_inventory ? "on" : "off"].
" + . += "The green light is [(V.categories & CAT_HIDDEN) ? "on" : "off"].
" . += "A [V.scan_id ? "purple" : "yellow"] light is on.
" /datum/wires/vending/UpdatePulsed(var/index) @@ -36,7 +33,7 @@ var/const/VENDING_WIRE_IDSCAN = 8 if(VENDING_WIRE_THROW) V.shoot_inventory = !V.shoot_inventory if(VENDING_WIRE_CONTRABAND) - V.extended_inventory = !V.extended_inventory + V.categories ^= CAT_HIDDEN if(VENDING_WIRE_ELECTRIFY) V.seconds_electrified = 30 if(VENDING_WIRE_IDSCAN) @@ -48,7 +45,7 @@ var/const/VENDING_WIRE_IDSCAN = 8 if(VENDING_WIRE_THROW) V.shoot_inventory = !mended if(VENDING_WIRE_CONTRABAND) - V.extended_inventory = 0 + V.categories &= ~CAT_HIDDEN if(VENDING_WIRE_ELECTRIFY) if(mended) V.seconds_electrified = 0 diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm index c3d07013d14..04c3541dc7e 100644 --- a/code/datums/wires/wires.dm +++ b/code/datums/wires/wires.dm @@ -72,8 +72,11 @@ var/list/wireColours = list("red", "blue", "green", "black", "orange", "brown", html = GetInteractWindow() if(html) user.set_machine(holder) - //user << browse(html, "window=wires;size=[window_x]x[window_y]") - //onclose(user, "wires") + else + user.unset_machine() + // No content means no window. + user << browse(null, "window=wires") + return var/datum/browser/popup = new(user, "wires", holder.name, window_x, window_y) popup.set_content(html) popup.set_title_image(user.browse_rsc_icon(holder.icon, holder.icon_state)) diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index 1aabc4b6d6d..03a3fa2a3f6 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -80,7 +80,8 @@ data["calibrated"] = null data["accurate"] = null data["regime"] = regime_set - data["target"] = (!target) ? "None" : get_area(target) + var/area/targetarea = get_area(target) + data["target"] = (!target) ? "None" : sanitize(targetarea.name) data["calibrating"] = calibrating data["locked"] = locked diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index a2b95fed050..ff85b1321ff 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -1,17 +1,39 @@ -#define CAT_NORMAL 0 -#define CAT_HIDDEN 1 -#define CAT_COIN 2 +#define CAT_NORMAL 1 +#define CAT_HIDDEN 2 // also used in corresponding wires/vending.dm +#define CAT_COIN 4 +/** + * Datum used to hold information about a product in a vending machine + */ /datum/data/vending_product - var/product_name = "generic" + var/product_name = "generic" // Display name for the product var/product_path = null - var/amount = 0 + var/amount = 0 // Amount held in the vending machine var/max_amount = 0 - var/price = 0 - var/display_color = "blue" - var/category = CAT_NORMAL - + var/price = 0 // Price to buy one + var/display_color = null // Display color for vending machine listing + var/category = CAT_NORMAL // CAT_HIDDEN for contraband, CAT_COIN for premium + +/datum/data/vending_product/New(var/path, var/name = null, var/amount = 1, var/price = 0, var/color = null, var/category = CAT_NORMAL) + ..() + + src.product_path = path + + if(!name) + var/atom/tmp = new path + src.product_name = initial(tmp.name) + del(tmp) + else + src.product_name = name + + src.amount = amount + src.price = price + src.display_color = color + src.category = category +/** + * A vending machine + */ /obj/machinery/vending name = "Vendomat" desc = "A generic vending machine." @@ -20,39 +42,57 @@ layer = 2.9 anchored = 1 density = 1 + + var/icon_vend //Icon_state when vending + var/icon_deny //Icon_state when denying access + + // Power + use_power = 1 + idle_power_usage = 10 + var/vend_power_usage = 150 + + // Vending-related var/active = 1 //No sales pitches if off! - var/delay_product_spawn // If set, uses sleep() in product spawn proc (mostly for seeds to retrieve correct names). var/vend_ready = 1 //Are we ready to vend?? Is it time?? var/vend_delay = 10 //How long does it take to vend? - var/datum/data/vending_product/currently_vending = null // A /datum/data/vending_product instance of what we're paying for right now. + var/categories = CAT_NORMAL // Bitmask of cats we're currently showing + var/datum/data/vending_product/currently_vending = null // What we're requesting payment for right now + var/status_message = "" // Status screen messages like "insufficient funds", displayed in NanoUI + var/status_error = 0 // Set to 1 if status_message is an error // To be filled out at compile time var/list/products = list() // For each, use the following pattern: var/list/contraband = list() // list(/type/path = amount,/type/path2 = amount2) var/list/premium = list() // No specified amount = only one in stock var/list/prices = list() // Prices for each item, list(/type/path = price), items not in the list don't have a price. - - var/product_slogans = "" //String of slogans separated by semicolons, optional - var/product_ads = "" //String of small ad messages in the vending screen - random chance + + // List of vending_product items available. var/list/product_records = list() var/list/hidden_records = list() - var/list/coin_records = list() + + // // Variables used to initialize advertising + var/product_slogans = "" //String of slogans separated by semicolons, optional + var/product_ads = "" //String of small ad messages in the vending screen - random chance + + var/list/ads_list = list() + + // Stuff relating vocalizations var/list/slogan_list = list() - var/list/small_ads = list() //Small ad messages in the vending screen - random chance of popping up whenever you open it var/vend_reply //Thank you for shopping! + var/shut_up = 0 //Stop spouting those godawful pitches! var/last_reply = 0 - var/obj/item/weapon/vending_refill/refill_canister = null //The type of refill canisters used by this machine. var/last_slogan = 0 //When did we last pitch? var/slogan_delay = 6000 //How long until we can pitch again? - var/icon_vend //Icon_state when vending! - var/icon_deny //Icon_state when vending! - //var/emagged = 0 //Ignores if somebody doesn't have card access to that machine. + + var/obj/item/weapon/vending_refill/refill_canister = null //The type of refill canisters used by this machine. + + // Things that can go wrong + emagged = 0 //Ignores if somebody doesn't have card access to that machine. var/seconds_electrified = 0 //Shock customers like an airlock. var/shoot_inventory = 0 //Fire items at customers! We're broken! var/shoot_speed = 3 //How hard are we firing the items? var/shoot_chance = 2 //How often are we firing the items? - var/shut_up = 0 //Stop spouting those godawful pitches! - var/extended_inventory = 0 //can we access the hidden inventory? + var/scan_id = 1 var/obj/item/weapon/coin/coin var/datum/wires/vending/wires = null @@ -61,31 +101,56 @@ ..() wires = new(src) spawn(4) - src.slogan_list = text2list(src.product_slogans, ";") + if(src.product_slogans) + src.slogan_list += text2list(src.product_slogans, ";") - // So not all machines speak at the exact same time. - // The first time this machine says something will be at slogantime + this random value, - // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. - src.last_slogan = world.time + rand(0, slogan_delay) + // So not all machines speak at the exact same time. + // The first time this machine says something will be at slogantime + this random value, + // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. + src.last_slogan = world.time + rand(0, slogan_delay) - src.build_inventory(products) - //Add hidden inventory - src.build_inventory(contraband, 1) - src.build_inventory(premium, 0, 1) + if(src.product_ads) + src.ads_list += text2list(src.product_ads, ";") + + src.build_inventory() power_change() - - return return + +/** + * Build src.produdct_records from the products lists + * + * src.products, src.contraband, src.premium, and src.prices allow specifying + * products that the vending machine is to carry without manually populating + * src.product_records. + */ +/obj/machinery/vending/proc/build_inventory() + var/list/all_products = list( + list(src.products, CAT_NORMAL), + list(src.contraband, CAT_HIDDEN), + list(src.premium, CAT_COIN)) + for(var/current_list in all_products) + var/category = current_list[2] + + for(var/entry in current_list[1]) + var/datum/data/vending_product/product = new/datum/data/vending_product(entry) + + product.price = (entry in src.prices) ? src.prices[entry] : 0 + product.amount = (current_list[1][entry]) ? current_list[1][entry] : 1 + product.max_amount = product.amount + product.category = category + + src.product_records.Add(product) /obj/machinery/vending/Destroy() - del(wires) + del(wires) // qdel wires = null - del(coin) - coin = null + if(coin) + del(coin) // qdel + coin = null ..() /obj/machinery/vending/ex_act(severity) @@ -115,41 +180,6 @@ else del(src) - -/obj/machinery/vending/proc/build_inventory(var/list/productlist,hidden=0,req_coin=0,start_empty = null) - for(var/typepath in productlist) - var/amount = productlist[typepath] - var/price = prices[typepath] - if(isnull(amount)) amount = 1 - - var/atom/temp = new typepath(null) - var/datum/data/vending_product/R = new /datum/data/vending_product() - - R.product_path = typepath - if(!start_empty) - R.amount = amount - R.max_amount = amount - R.price = price - R.display_color = pick("red","blue","green") - if(hidden) - R.category=CAT_HIDDEN - hidden_records += R - else if(req_coin) - R.category=CAT_COIN - coin_records += R - else - R.category=CAT_NORMAL - product_records += R - - if(delay_product_spawn) - sleep(3) - R.product_name = temp.name - else - R.product_name = temp.name - -// world << "Added: [R.product_name]] - [R.amount] - [R.product_path]" - - /obj/machinery/vending/proc/refill_inventory(obj/item/weapon/vending_refill/refill, datum/data/vending_product/machine, mob/user) var/total = 0 @@ -180,10 +210,29 @@ return total /obj/machinery/vending/attackby(obj/item/weapon/W, mob/user) - if(panel_open) - if(default_unfasten_wrench(user, W, time = 60)) - return + if (currently_vending && vendor_account && !vendor_account.suspended) + var/paid = 0 + var/handled = 0 + if(istype(W, /obj/item/weapon/card/id)) + var/obj/item/weapon/card/id/C = W + paid = pay_with_card(C) + handled = 1 + else if (istype(W, /obj/item/weapon/spacecash)) + var/obj/item/weapon/spacecash/C = W + paid = pay_with_cash(C, user) + handled = 1 + if(paid) + src.vend(currently_vending, usr) + return + else if(handled) + nanomanager.update_uis(src) + return // don't smack that machine with your 2 thalers + + if(default_unfasten_wrench(user, W, time = 60)) + return + + if(panel_open) if(component_parts && istype(W, /obj/item/weapon/crowbar)) var/datum/data/vending_product/machine = product_records for(var/datum/data/vending_product/machine_content in machine) @@ -206,20 +255,19 @@ overlays.Cut() if(panel_open) overlays += image(icon, "[initial(icon_state)]-panel") - updateUsrDialog() + nanomanager.update_uis(src) // Speaker switch is on the main UI, not wires UI return else if(istype(W, /obj/item/device/multitool)||istype(W, /obj/item/weapon/wirecutters)) if(panel_open) attack_hand(user) return - else if(istype(W, /obj/item/weapon/card) && currently_vending) - var/obj/item/weapon/card/I = W - scan_card(I) else if(istype(W, /obj/item/weapon/coin) && premium.len > 0) user.drop_item() W.loc = src coin = W - user << "You insert [W] into [src]." + categories |= CAT_COIN + user << "\blue You insert the [W] into the [src]" + nanomanager.update_uis(src) return else if(istype(W, refill_canister) && refill_canister != null) if(stat & (BROKEN|NOPOWER)) @@ -240,176 +288,183 @@ user << "You should probably unscrew the service panel first." else ..() +/** + * Receive payment with cashmoney. + * + * usr is the mob who gets the change. + */ +/obj/machinery/vending/proc/pay_with_cash(var/obj/item/weapon/spacecash/cashmoney, mob/user) + if(currently_vending.price > cashmoney.worth) + // This is not a status display message, since it's something the character + // themselves is meant to see BEFORE putting the money in + usr << "\icon[cashmoney] That is not enough money." + return 0 + + // Bills (banknotes) cannot really have worth different than face value, + // so we have to eat the bill and spit out change in a bundle + // This is really dirty, but there's no superclass for all bills, so we + // just assume that all spacecash that's not something else is a bill + visible_message("[usr] inserts a credit chip into [src].") + var/left = cashmoney.worth - currently_vending.price + usr.drop_from_inventory(cashmoney) + del(cashmoney) + if(left) + dispense_cash(left, src.loc, user) -/obj/machinery/vending/proc/scan_card(var/obj/item/weapon/card/I) - if(!currently_vending) return - if (istype(I, /obj/item/weapon/card/id)) - var/obj/item/weapon/card/id/C = I - visible_message("[usr] swipes a card through [src].") - if(vendor_account) - var/datum/money_account/D = attempt_account_access_nosec(C.associated_account_number) - if(D) - var/transaction_amount = currently_vending.price - if(transaction_amount <= D.money) + // Vending machines have no idea who paid with cash + credit_purchase("(cash)") + return 1 - //transfer the money - D.money -= transaction_amount - vendor_account.money += transaction_amount +/** + * Scan a card and attempt to transfer payment from associated account. + * + * Takes payment for whatever is the currently_vending item. Returns 1 if + * successful, 0 if failed + */ +/obj/machinery/vending/proc/pay_with_card(var/obj/item/weapon/card/id/I) + visible_message("[usr] swipes a card through [src].") + var/datum/money_account/customer_account = attempt_account_access_nosec(I.associated_account_number) + if (!customer_account) + src.status_message = "Error: Unable to access account. Please contact technical support if problem persists." + src.status_error = 1 + return 0 - //create entries in the two account transaction logs - var/datum/transaction/T = new() - T.target_name = "[vendor_account.owner_name] (via [src.name])" - T.purpose = "Purchase of [currently_vending.product_name]" - if(transaction_amount > 0) - T.amount = "([transaction_amount])" - else - T.amount = "[transaction_amount]" - T.source_terminal = src.name - T.date = current_date_string - T.time = worldtime2text() - D.transaction_log.Add(T) - // - T = new() - T.target_name = D.owner_name - T.purpose = "Purchase of [currently_vending.product_name]" - T.amount = "[transaction_amount]" - T.source_terminal = src.name - T.date = current_date_string - T.time = worldtime2text() - vendor_account.transaction_log.Add(T) + if(customer_account.suspended) + src.status_message = "Unable to access account: account suspended." + src.status_error = 1 + return 0 - // Vend the item - src.vend(src.currently_vending, usr) - currently_vending = null - src.updateUsrDialog() - else - usr << "\icon[src]You don't have that much money!" - else - usr << "\icon[src]Unable to access account. Check security settings and try again." + // Have the customer punch in the PIN before checking if there's enough money. Prevents people from figuring out acct is + // empty at high security levels + if(customer_account.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2) + var/attempt_pin = input("Enter pin code", "Vendor transaction") as num + customer_account = attempt_account_access(I.associated_account_number, attempt_pin, 2) + + if(!customer_account) + src.status_message = "Unable to access account: incorrect credentials." + src.status_error = 1 + return 0 + + if(currently_vending.price > customer_account.money) + src.status_message = "Insufficient funds in account." + src.status_error = 1 + return 0 + else + // Okay to move the money at this point + + // debit money from the purchaser's account + customer_account.money -= currently_vending.price + + // create entry in the purchaser's account log + var/datum/transaction/T = new() + T.target_name = "[vendor_account.owner_name] (via [src.name])" + T.purpose = "Purchase of [currently_vending.product_name]" + if(currently_vending.price > 0) + T.amount = "([currently_vending.price])" else - usr << "\icon[src]Unable to access vendor account. Please record the machine ID and call CentComm Support." + T.amount = "[currently_vending.price]" + T.source_terminal = src.name + T.date = current_date_string + T.time = worldtime2text() + customer_account.transaction_log.Add(T) -/obj/machinery/vending/attack_paw(mob/user as mob) - return attack_hand(user) + // Give the vendor the money. We use the account owner name, which means + // that purchases made with stolen/borrowed card will look like the card + // owner made them + credit_purchase(customer_account.owner_name) + return 1 + +/** + * Add money for current purchase to the vendor account. + * + * Called after the money has already been taken from the customer. + */ +/obj/machinery/vending/proc/credit_purchase(var/target as text) + vendor_account.money += currently_vending.price + + var/datum/transaction/T = new() + T.target_name = target + T.purpose = "Purchase of [currently_vending.product_name]" + T.amount = "[currently_vending.price]" + T.source_terminal = src.name + T.date = current_date_string + T.time = worldtime2text() + vendor_account.transaction_log.Add(T) /obj/machinery/vending/attack_ai(mob/user as mob) return attack_hand(user) - -/obj/machinery/vending/proc/GetProductIndex(var/datum/data/vending_product/P) - var/list/plist - switch(P.category) - if(CAT_NORMAL) - plist=product_records - if(CAT_HIDDEN) - plist=hidden_records - if(CAT_COIN) - plist=coin_records - else - warning("UNKNOWN CATEGORY [P.category] IN TYPE [P.product_path] INSIDE [type]!") - return plist.Find(P) - -/obj/machinery/vending/proc/GetProductByID(var/pid, var/category) - switch(category) - if(CAT_NORMAL) - return product_records[pid] - if(CAT_HIDDEN) - return hidden_records[pid] - if(CAT_COIN) - return coin_records[pid] - else - warning("UNKNOWN PRODUCT: PID: [pid], CAT: [category] INSIDE [type]!") - return null + +/obj/machinery/vending/attack_paw(mob/user as mob) + return attack_hand(user) /obj/machinery/vending/attack_hand(mob/user as mob) if(stat & (BROKEN|NOPOWER)) return - user.set_machine(src) - if(seconds_electrified != 0) - if(shock(user, 100)) + if(src.seconds_electrified != 0) + if(src.shock(user, 100)) return - var/vendorname = (src.name) //import the machine's name + wires.Interact(user) + ui_interact(user) - if(src.currently_vending) - var/dat = "
[vendorname]


" //display the name, and added a horizontal rule - - // AUTOFIXED BY fix_string_idiocy.py - // C:\Users\Rob\Documents\Projects\vgstation13\code\game\machinery\vending.dm:260: dat += "You have selected [currently_vending.product_name].
Please ensure your ID is in your ID holder or hand.

" - dat += {"You have selected [currently_vending.product_name].
Please ensure your ID is in your ID holder or hand.

- Pay | - Cancel"} - // END AUTOFIX - user << browse(dat, "window=vending") - onclose(user, "") - return - - var/dat = "
[vendorname]


" //display the name, and added a horizontal rule - dat += "Select an item:

" //the rest is just general spacing and bolding - - if (premium.len > 0) - dat += "Coin slot: [coin ? coin : "No coin inserted"] (Remove)

" - - if (src.product_records.len == 0) - dat += "No product loaded!" +/** + * Display the NanoUI window for the vending machine. + * + * See NanoUI documentation for details. + */ +/obj/machinery/vending/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) + + var/list/data = list() + if(currently_vending) + data["mode"] = 1 + data["product"] = currently_vending.product_name + data["price"] = currently_vending.price + data["message_err"] = 0 + data["message"] = src.status_message + data["message_err"] = src.status_error else - var/list/display_records = list() - display_records += src.product_records + data["mode"] = 0 + var/list/listed_products = list() - if(src.extended_inventory) - display_records += src.hidden_records - if(src.coin) - display_records += src.coin_records - - for (var/datum/data/vending_product/R in display_records) - - // AUTOFIXED BY fix_string_idiocy.py - // C:\Users\Rob\Documents\Projects\vgstation13\code\game\machinery\vending.dm:285: dat += "[R.product_name]:" - dat += {"[R.product_name]: - [R.amount] "} - // END AUTOFIX - if(R.price) - dat += " (Price: [R.price])" - if (R.amount > 0) - var/idx=GetProductIndex(R) - dat += " (Vend)" - else - dat += " SOLD OUT" - dat += "
" - - dat += "
" - - if(panel_open) - dat += wires() - - if(product_slogans != "") - dat += "The speaker switch is [shut_up ? "off" : "on"]. Toggle" - - user << browse(dat, "window=vending") - onclose(user, "") - return - -// returns the wire panel text -/obj/machinery/vending/proc/wires() - return wires.GetInteractWindow() + for(var/key = 1 to src.product_records.len) + var/datum/data/vending_product/I = src.product_records[key] + + if(!(I.category & src.categories)) + continue + + listed_products.Add(list(list( + "key" = key, + "name" = sanitize(I.product_name), + "price" = I.price, + "color" = I.display_color, + "amount" = I.amount))) + + data["products"] = listed_products + + if(src.coin) + data["coin"] = src.coin.name + + if(src.panel_open) + data["panel"] = 1 + data["speaker"] = src.shut_up ? 0 : 1 + else + data["panel"] = 0 + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "vending_machine.tmpl", src.name, 440, 600) + ui.set_initial_data(data) + ui.open() /obj/machinery/vending/Topic(href, href_list) if(..()) return 1 - if(istype(usr,/mob/living/silicon)) - if(istype(usr,/mob/living/silicon/robot)) - var/mob/living/silicon/robot/R = usr - if(!(R.module && istype(R.module,/obj/item/weapon/robot_module/butler) ) ) - usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" - return - else - usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" - return - - if(href_list["remove_coin"]) + if(href_list["remove_coin"] && !istype(usr,/mob/living/silicon)) if(!coin) usr << "There is no coin in this machine." return @@ -419,67 +474,64 @@ usr.put_in_hands(coin) usr << "\blue You remove the [coin] from the [src]" coin = null - usr.set_machine(src) - + categories &= ~CAT_COIN if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) if ((href_list["vend"]) && (src.vend_ready) && (!currently_vending)) - if (!allowed(usr) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH - usr << "\red Access denied." //Unless emagged of course - flick(src.icon_deny,src) + if(istype(usr,/mob/living/silicon)) + if(istype(usr,/mob/living/silicon/robot)) + var/mob/living/silicon/robot/R = usr + if(!(R.module && istype(R.module,/obj/item/weapon/robot_module/butler) )) + usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" + return + else + usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" + return + + if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH + usr << "Access denied." //Unless emagged of course + flick(icon_deny,src) return - var/idx=text2num(href_list["vend"]) - var/cat=text2num(href_list["cat"]) - - var/datum/data/vending_product/R = GetProductByID(idx,cat) - if (!R || !istype(R) || !R.product_path || R.amount <= 0) + var/key = text2num(href_list["vend"]) + var/datum/data/vending_product/R = product_records[key] + + // This should not happen unless the request from NanoUI was bad + if(!(R.category & src.categories)) return - - if(R.price == null) + + if(R.price <= 0) src.vend(R, usr) else src.currently_vending = R - src.updateUsrDialog() + if(!vendor_account || vendor_account.suspended) + src.status_message = "This machine is currently unable to process payments due to problems with the associated account." + src.status_error = 1 + else + src.status_message = "Please swipe a card or insert cash to pay for the item." + src.status_error = 0 - return - - else if (href_list["cancel_buying"]) + else if (href_list["cancelpurchase"]) src.currently_vending = null - src.updateUsrDialog() - return - - else if (href_list["buy"]) - if(istype(usr, /mob/living/carbon/human)) - var/mob/living/carbon/human/H=usr - var/obj/item/weapon/card/card = null - if(istype(H.wear_id,/obj/item/weapon/card)) - card=H.wear_id - else if(istype(H.get_active_hand(),/obj/item/weapon/card)) - card=H.get_active_hand() - if(card) - scan_card(card) - return else if ((href_list["togglevoice"]) && (src.panel_open)) src.shut_up = !src.shut_up src.add_fingerprint(usr) - src.updateUsrDialog() - else - usr << browse(null, "window=vending") - return - return + nanomanager.update_uis(src) /obj/machinery/vending/proc/vend(datum/data/vending_product/R, mob/user) - if (!allowed(user) && !emagged && wires.IsIndexCut(VENDING_WIRE_IDSCAN)) //For SECURE VENDING MACHINES YEAH - user << "\red Access denied." //Unless emagged of course + if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH + usr << "Access denied." //Unless emagged of course flick(src.icon_deny,src) return src.vend_ready = 0 //One thing at a time!! - - if (R in coin_records) + src.status_message = "Vending..." + src.status_error = 0 + nanomanager.update_uis(src) + + if (R.category & CAT_COIN) if(!coin) user << "\blue You need to insert a coin to get this item." return @@ -489,8 +541,10 @@ else user << "\blue You weren't able to pull the coin out fast enough, the machine ate it, string and all." del(coin) + categories &= ~CAT_COIN else del(coin) + categories &= ~CAT_COIN R.amount-- @@ -499,16 +553,16 @@ src.speak(src.vend_reply) src.last_reply = world.time - use_power(5) + use_power(vend_power_usage) //actuators and stuff if (src.icon_vend) //Show the vending animation if needed flick(src.icon_vend,src) spawn(src.vend_delay) new R.product_path(get_turf(src)) + src.status_message = "" + src.status_error = 0 src.vend_ready = 1 - return - - src.updateUsrDialog() - + currently_vending = null + nanomanager.update_uis(src) /obj/machinery/vending/proc/stock(var/datum/data/vending_product/R, var/mob/user) if(src.panel_open) @@ -883,7 +937,6 @@ product_slogans = "THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!;Hands down the best seed selection on the station!;Also certain mushroom varieties available, more for experts! Get certified today!" product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!" icon_state = "seeds" - delay_product_spawn = 1 products = list(/obj/item/seeds/bananaseed = 3,/obj/item/seeds/berryseed = 3,/obj/item/seeds/carrotseed = 3,/obj/item/seeds/chantermycelium = 3,/obj/item/seeds/chiliseed = 3, /obj/item/seeds/cornseed = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/replicapod = 3,/obj/item/seeds/soyaseed = 3, @@ -895,7 +948,33 @@ contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/nettleseed = 2, /obj/item/seeds/plumpmycelium = 2,/obj/item/seeds/reishimycelium = 2) premium = list(/obj/item/weapon/reagent_containers/spray/waterflower = 1) + +/** + * Populate hydroseeds product_records + * + * This needs to be customized to fetch the actual names of the seeds, otherwise + * the machine would simply list "packet of seeds" times 20 + */ +/obj/machinery/vending/hydroseeds/build_inventory() + var/list/all_products = list( + list(src.products, CAT_NORMAL), + list(src.contraband, CAT_HIDDEN), + list(src.premium, CAT_COIN)) + for(var/current_list in all_products) + var/category = current_list[2] + + for(var/entry in current_list[1]) + var/obj/item/seeds/S = new entry(src) + var/name = S.name + var/datum/data/vending_product/product = new/datum/data/vending_product(entry, name) + + product.price = (entry in src.prices) ? src.prices[entry] : 0 + product.amount = (current_list[1][entry]) ? current_list[1][entry] : 1 + product.max_amount = product.amount + product.category = category + + src.product_records.Add(product) /obj/machinery/vending/magivend name = "MagiVend" diff --git a/code/modules/economy/Accounts.dm b/code/modules/economy/Accounts.dm index 91d8662227c..018ce78cd3a 100644 --- a/code/modules/economy/Accounts.dm +++ b/code/modules/economy/Accounts.dm @@ -125,13 +125,13 @@ var/global/list/all_money_accounts = list() var/money = 0 var/suspended = 0 var/list/transaction_log = list() - var/security_level = 1 //0 - auto-identify from worn ID, require only account number + var/security_level = 0 //0 - auto-identify from worn ID, require only account number //1 - require manual login / account number and pin //2 - require card and manual login /datum/money_account/New() ..() - security_level = pick (0,1) //Stealing is now slightly viable + //security_level = pick (0,1) //Stealing is now slightly viable /datum/transaction var/target_name = "" diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index d865cb2dde5..3b8c12cc5dc 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -883,6 +883,7 @@ var/list/slot_equipment_priority = list( \ stat(null, "PiNet-[master_controller.networks_cost]\t#[pipe_networks.len]") stat(null, "Ponet-[master_controller.powernets_cost]\t#[powernets.len]") stat(null, "NanoUI-[master_controller.nano_cost]\t#[nanomanager.processing_uis.len]") + stat(null,"Events-[master_controller.events_cost]\t#[event_manager.active_events.len]") // stat(null, "GC-[master_controller.gc_cost]\t#[garbage.queue.len]") stat(null, "Tick-[master_controller.ticker_cost]") stat(null, "ALL-[master_controller.total_cost]") diff --git a/nano/templates/vending_machine.tmpl b/nano/templates/vending_machine.tmpl new file mode 100644 index 00000000000..93d5c1007c9 --- /dev/null +++ b/nano/templates/vending_machine.tmpl @@ -0,0 +1,56 @@ + + +{{if data.mode == 0}} +

Items available

+
+ {{for data.products}} +
+
+ {{if value.price > 0}} + {{:helper.link('Buy (' + value.price + ')', 'cart', { "vend" : value.key }, value.amount > 0 ? null : 'disabled')}} + {{else}} + {{:helper.link('Vend', 'circle-arrow-s', { "vend" : value.key }, value.amount > 0 ? null : 'disabled')}} + {{/if}} +
+
+ {{if value.color}}{{:value.name}} + {{else}}{{:value.name}} + {{/if}} + ({{:value.amount ? value.amount : "NONE LEFT"}}) +
+
+ {{empty}} + No items available! + {{/for}} +
+{{if data.coin}} +

Coin

+
+
Coin deposited:
+
{{:helper.link(data.coin, 'eject', {'remove_coin' : 1})}}
+
+{{/if}} +{{else data.mode == 1}} +

Item selected

+
+
+
Item selected:
{{:data.product}}
+
Charge:
{{:data.price}}
+
+
+ {{if data.message_err}} {{/if}} {{:data.message}} +
+
+ {{:helper.link('Cancel', 'arrowreturn-1-w', {'cancelpurchase' : 1})}} +
+
+{{/if}} +{{if data.panel}} +

Maintenance panel

+
+
Speaker
{{:helper.link(data.speaker ? 'Enabled' : 'Disabled', 'gear', {'togglevoice' : 1})}}
+
+{{/if}} \ No newline at end of file From e7713a4662e7d02dc60d3f0e9e2b19e6330e5eb1 Mon Sep 17 00:00:00 2001 From: Markolie Date: Fri, 13 Feb 2015 15:40:53 +0100 Subject: [PATCH 03/13] Fax UI rework --- code/modules/paperwork/faxmachine.dm | 169 ++++++++++++++----------- code/modules/paperwork/paper.dm | 2 +- code/modules/paperwork/paper_bundle.dm | 4 +- code/modules/paperwork/photography.dm | 2 +- maps/cyberiad.dmm | 2 +- nano/templates/faxmachine.tmpl | 67 ++++++++++ 6 files changed, 168 insertions(+), 78 deletions(-) create mode 100644 nano/templates/faxmachine.tmpl diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index a727a3f59c3..7638cc2ea93 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -22,6 +22,8 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins var/department = "Unknown" // our department var/destination = "Central Command" // the department we're sending to + + var/data[0] /obj/machinery/photocopier/faxmachine/New() ..() @@ -31,60 +33,50 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins alldepartments |= department /obj/machinery/photocopier/faxmachine/attack_hand(mob/user as mob) - user.set_machine(src) - - var/dat = "Fax Machine
" - - var/scan_name + ui_interact(user) + +/obj/machinery/photocopier/faxmachine/attackby(obj/item/weapon/item, mob/user) + if(istype(item,/obj/item/weapon/card/id) && !scan) + scan(item) + else if(istype(item, /obj/item/weapon/paper) || istype(item, /obj/item/weapon/photo) || istype(item, /obj/item/weapon/paper_bundle)) + ..() + nanomanager.update_uis(src) + else + return ..() + +/obj/machinery/photocopier/faxmachine/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) if(scan) - scan_name = scan.name + data["scan_name"] = scan.name else - scan_name = "--------" - - dat += "Confirm Identity: [scan_name]
" - - if(authenticated) - dat += "{Log Out}" + data["scan_name"] = "-----" + data["authenticated"] = authenticated + if(!authenticated) + data["network"] = "Disconnected" + else if(!emagged) + data["network"] = "Central Command Quantum Entanglement Network" else - dat += "{Log In}" - - dat += "
" - - if(authenticated) - dat += "Logged in to: Central Command Quantum Entanglement Network

" - - if(copyitem) - dat += "Remove Item

" - - if(sendcooldown) - dat += "Transmitter arrays realigning. Please stand by.
" - - else - - dat += "Send
" - dat += "Currently sending: [copyitem.name]
" - dat += "Sending to: [destination]
" - - else - if(sendcooldown) - dat += "Please insert paper to send via secure connection.

" - dat += "Transmitter arrays realigning. Please stand by.
" - else - dat += "Please insert paper to send via secure connection.

" - + data["network"] = "ERR?*!!*" + if(copyitem) + data["paper"] = copyitem.name + data["paperinserted"] = 1 else - dat += "Proper authentication is required to use this device.

" + data["paper"] = "-----" + data["paperinserted"] = 0 + data["destination"] = destination + data["cooldown"] = sendcooldown - if(copyitem) - dat += "Remove Item
" - - user << browse(dat, "window=copier") - onclose(user, "copier") - return + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "faxmachine.tmpl", "Fax Machine UI", 540, 450) + ui.set_initial_data(data) + ui.open() /obj/machinery/photocopier/faxmachine/Topic(href, href_list) + if(..()) + return 1 + if(href_list["send"]) - if(copyitem) + if(copyitem && authenticated) if (destination in admin_departments) send_admin_fax(usr, destination) else @@ -93,47 +85,78 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins if (sendcooldown) spawn(sendcooldown) // cooldown time sendcooldown = 0 + nanomanager.update_uis(src) - else if(href_list["remove"]) + if(href_list["paper"]) if(copyitem) copyitem.loc = usr.loc usr.put_in_hands(copyitem) usr << "You take \the [copyitem] out of \the [src]." copyitem = null - updateUsrDialog() + else + var/obj/item/I = usr.get_active_hand() + if (istype(I, /obj/item/weapon/paper) || istype(I, /obj/item/weapon/photo) || istype(I, /obj/item/weapon/paper_bundle)) + usr.drop_item() + copyitem = I + I.loc = src + usr << "You insert \the [I] into \the [src]." + flick(insert_anim, src) if(href_list["scan"]) - if (scan) - if(ishuman(usr)) - scan.loc = usr.loc - if(!usr.get_active_hand()) - usr.put_in_hands(scan) - scan = null - else - scan.loc = src.loc - scan = null + scan() + + if(href_list["dept"]) + if(authenticated) + var/lastdestination = destination + destination = input(usr, "Which department?", "Choose a department", "") as null|anything in (alldepartments + admin_departments) + if(!destination) + destination = lastdestination + + if(href_list["auth"]) + if((!authenticated) && scan) + if(check_access(scan)) + authenticated = 1 + else if(authenticated) + authenticated = 0 + + if(href_list["rename"]) + if(copyitem) + var/n_name = copytext(sanitize(input(usr, "What would you like to label the fax?", "Fax Labelling", copyitem.name) as text), 1, MAX_MESSAGE_LEN) + if((copyitem && copyitem.loc == src && usr.stat == 0)) + if (istype(copyitem, /obj/item/weapon/paper)) + copyitem.name = "[(n_name ? text("[n_name]") : initial(copyitem.name))]" + copyitem.desc = "This is a paper titled '" + copyitem.name + "'." + else if(istype(copyitem, /obj/item/weapon/photo)) + copyitem.name = "[(n_name ? text("[n_name]") : "photo")]" + else if(istype(copyitem, /obj/item/weapon/paper_bundle)) + copyitem.name = "[(n_name ? text("[n_name]") : "paper")]" + data["name"] = copyitem.name + + nanomanager.update_uis(src) + +/obj/machinery/photocopier/faxmachine/proc/scan(var/obj/item/weapon/card/id/card = null) + if (scan) // Card is in machine + if(ishuman(usr)) + scan.loc = usr.loc + if(!usr.get_active_hand()) + usr.put_in_hands(scan) + scan = null else + scan.loc = src.loc + scan = null + else + if(!card) var/obj/item/I = usr.get_active_hand() if (istype(I, /obj/item/weapon/card/id)) usr.drop_item() I.loc = src scan = I - authenticated = 0 - - if(href_list["dept"]) - var/lastdestination = destination - destination = input(usr, "Which department?", "Choose a department", "") as null|anything in (alldepartments + admin_departments) - if(!destination) destination = lastdestination - - if(href_list["auth"]) - if ( (!( authenticated ) && (scan)) ) - if (check_access(scan)) - authenticated = 1 - - if(href_list["logout"]) - authenticated = 0 - - updateUsrDialog() + else + if(istype(card)) + usr.drop_item() + card.loc = src + scan = card + nanomanager.update_uis(src) /obj/machinery/photocopier/faxmachine/proc/sendfax(var/destination) if(stat & (BROKEN|NOPOWER)) diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index edbe96a1cdc..a1cf50822a5 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -76,7 +76,7 @@ if((M_CLUMSY in usr.mutations) && prob(50)) usr << "You cut yourself on the paper." return - var/n_name = copytext(sanitize(input(usr, "What would you like to label the paper?", "Paper Labelling", null) as text), 1, MAX_MESSAGE_LEN) + var/n_name = copytext(sanitize(input(usr, "What would you like to label the paper?", "Paper Labelling", name) as text), 1, MAX_MESSAGE_LEN) if((loc == usr && usr.stat == 0)) name = "[(n_name ? text("[n_name]") : initial(name))]" if(name != "paper") diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm index c3ddfb3cbbb..2e834fe0562 100644 --- a/code/modules/paperwork/paper_bundle.dm +++ b/code/modules/paperwork/paper_bundle.dm @@ -189,9 +189,9 @@ set category = "Object" set src in usr - var/n_name = copytext(sanitize(input(usr, "What would you like to label the bundle?", "Bundle Labelling", null) as text), 1, MAX_MESSAGE_LEN) + var/n_name = copytext(sanitize(input(usr, "What would you like to label the bundle?", "Bundle Labelling", name) as text), 1, MAX_MESSAGE_LEN) if((loc == usr && usr.stat == 0)) - name = "[(n_name ? text("[n_name]") : "paper")]" + name = "[(n_name ? text("[n_name]") : "paper bundle")]" add_fingerprint(usr) return diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index 59973b019f8..e7ee680586a 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -90,7 +90,7 @@ set category = "Object" set src in usr - var/n_name = copytext(sanitize(input(usr, "What would you like to label the photo?", "Photo Labelling", null) as text), 1, MAX_MESSAGE_LEN) + var/n_name = copytext(sanitize(input(usr, "What would you like to label the photo?", "Photo Labelling", name) as text), 1, MAX_MESSAGE_LEN) //loc.loc check is for making possible renaming photos in clipboards if(( (loc == usr || (loc.loc && loc.loc == usr)) && usr.stat == 0)) name = "[(n_name ? text("[n_name]") : "photo")]" diff --git a/maps/cyberiad.dmm b/maps/cyberiad.dmm index 8d56da4d315..1473b41ca08 100644 --- a/maps/cyberiad.dmm +++ b/maps/cyberiad.dmm @@ -1308,7 +1308,7 @@ "azh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/carpet,/area/magistrateoffice) "azi" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/structure/stool/bed/chair/comfy/black,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/carpet,/area/magistrateoffice) "azj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/table/reinforced,/obj/item/device/megaphone,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/carpet,/area/magistrateoffice) -"azk" = (/obj/structure/table/reinforced,/obj/machinery/photocopier/faxmachine{department = "Internal Affairs"},/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) +"azk" = (/obj/structure/table/reinforced,/obj/machinery/photocopier/faxmachine{department = "Internal Affairs Office"},/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) "azl" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) "azm" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/effect/landmark/start{name = "Internal Affairs Agent"},/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) "azn" = (/obj/structure/table/reinforced,/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) diff --git a/nano/templates/faxmachine.tmpl b/nano/templates/faxmachine.tmpl new file mode 100644 index 00000000000..1e00c559b28 --- /dev/null +++ b/nano/templates/faxmachine.tmpl @@ -0,0 +1,67 @@ + +
+

Authorization

+
+
+
+ Confirm identity: +
+
+ {{:helper.link(data.scan_name, 'eject', {'scan' : 1})}} +
+
+
+
+ Authorize: +
+
+ {{:helper.link(data.authenticated ? 'Log Out' : 'Log In', data.authenticated ? 'unlocked' : 'locked', {'auth' : 1})}} +
+
+
+
+

Fax Menu

+
+
+
+ Network: +
+ +
+ {{:data.network}} +
+
+
+
+ Currently sending: +
+
+ {{:helper.link(data.paper, 'eject', {'paper' : 1})}} + {{if data.paperinserted}} + {{:helper.link('Rename', 'pencil', {'rename' : 1})}} + {{/if}} +
+
+
+
+ Sending to: +
+
+ {{:helper.link(data.destination, 'print', {'dept' : 1}, !data.authenticated ? 'disabled' : '')}} +
+
+
+
+ Action: +
+
+ {{if data.authenticated}} + {{:helper.link(data.cooldown ? "Realigning" : "Send", data.cooldown ? 'clock' : "mail-closed", {'send' : 1}, data.cooldown ? 'disabled' : "")}} + {{else}} + {{:helper.link(data.cooldown ? "Realigning" : "Send", data.cooldown ? 'clock' : "mail-closed", null, !data.authenticated ? 'disabled' : "")}} + {{/if}} +
+
\ No newline at end of file From 0b937d5ace91a9d5d29735383b4ef796e325868d Mon Sep 17 00:00:00 2001 From: Markolie Date: Fri, 13 Feb 2015 16:59:20 +0100 Subject: [PATCH 04/13] Emag refactor --- code/game/atoms.dm | 2 + code/game/machinery/bots/bots.dm | 7 +- code/game/machinery/bots/mulebot.dm | 14 +- .../machinery/computer/HolodeckControl.dm | 37 +---- code/game/machinery/computer/arcade.dm | 11 +- code/game/machinery/computer/atmos_control.dm | 13 +- code/game/machinery/computer/camera.dm | 22 ++- .../game/machinery/computer/communications.dm | 7 +- code/game/machinery/computer/honkputer.dm | 6 +- code/game/machinery/computer/message.dm | 37 ++--- code/game/machinery/computer/shuttle.dm | 9 +- code/game/machinery/deployable.dm | 37 +++-- code/game/machinery/door_control.dm | 7 +- code/game/machinery/doors/door.dm | 12 +- code/game/machinery/doors/windowdoor.dm | 27 ++-- code/game/machinery/metaldetector.dm | 11 +- code/game/machinery/portable_turret.dm | 27 ++-- code/game/machinery/programmable_unloader.dm | 24 ++-- code/game/machinery/recycler.dm | 16 ++- code/game/machinery/suit_storage_unit.dm | 31 ++-- code/game/machinery/telecomms/logbrowser.dm | 8 +- code/game/machinery/telecomms/telemonitor.dm | 10 +- .../machinery/telecomms/traffic_control.dm | 8 +- code/game/machinery/teleporter.dm | 18 ++- code/game/machinery/turrets.dm | 20 +-- code/game/machinery/vending.dm | 10 +- code/game/mecha/mech_fabricator.dm | 8 +- code/game/mecha/mecha.dm | 20 ++- .../objects/items/devices/lightreplacer.dm | 9 +- code/game/objects/items/devices/megaphone.dm | 6 +- .../objects/items/devices/radio/beacon.dm | 14 +- .../objects/items/devices/taperecorder.dm | 20 ++- code/game/objects/items/devices/whistle.dm | 7 +- code/game/objects/items/weapons/cards_ids.dm | 57 +------- code/game/objects/items/weapons/defib.dm | 16 +-- .../objects/items/weapons/storage/secure.dm | 38 ++--- .../clothing/under/accessories/accessory.dm | 21 ++- code/modules/computer3/component.dm | 18 +-- .../computer3/computers/communications.dm | 4 +- code/modules/computer3/computers/shuttle.dm | 9 +- code/modules/library/lib_machines.dm | 6 +- code/modules/mining/laborcamp/laborstacker.dm | 5 +- .../mob/living/carbon/human/human_defense.dm | 25 ++-- .../modules/mob/living/silicon/mommi/mommi.dm | 124 ++++++++-------- .../mob/living/silicon/robot/drone/drone.dm | 70 ++++----- .../modules/mob/living/silicon/robot/robot.dm | 133 +++++++++--------- .../living/simple_animal/friendly/corgi.dm | 6 +- .../simple_animal/friendly/spiderbot.dm | 23 ++- code/modules/power/apc.dm | 37 ++--- code/modules/power/pacman2.dm | 13 +- code/modules/power/port_gen.dm | 7 +- code/modules/power/singularity/emitter.dm | 16 ++- code/modules/research/rdconsole.dm | 11 +- code/modules/research/server.dm | 6 +- code/modules/shuttles/escape_pods.dm | 9 +- code/modules/shuttles/shuttle_console.dm | 14 +- code/modules/shuttles/shuttle_emergency.dm | 9 +- code/modules/telesci/telepad.dm | 7 +- code/modules/telesci/telesci_computer.dm | 13 +- code/modules/vehicles/vehicle.dm | 6 +- 60 files changed, 569 insertions(+), 649 deletions(-) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 6dec5fed5c8..04f2926436d 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -242,6 +242,8 @@ its easier to just keep the beam vertical. /atom/proc/blob_act() return +/atom/proc/emag_act() + return /atom/proc/hitby(atom/movable/AM as mob|obj) if (density) diff --git a/code/game/machinery/bots/bots.dm b/code/game/machinery/bots/bots.dm index 30ed21fbede..8cf8c77c66c 100644 --- a/code/game/machinery/bots/bots.dm +++ b/code/game/machinery/bots/bots.dm @@ -237,8 +237,6 @@ user << "Maintenance panel is now [open ? "opened" : "closed"]." else user << "Maintenance panel is locked." - else if (istype(W, /obj/item/weapon/card/emag) && emagged < 2) - Emag(user) else if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != "harm") if(health >= maxhealth) @@ -267,7 +265,10 @@ ..() healthcheck() - +/obj/machinery/bot/emag_act(user as mob) + if (emagged < 2) + Emag(user) + /obj/machinery/bot/bullet_act(var/obj/item/projectile/Proj) if((Proj.damage_type == BRUTE || Proj.damage_type == BURN)) health -= Proj.damage diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm index f9016a1061f..19ef2058f43 100644 --- a/code/game/machinery/bots/mulebot.dm +++ b/code/game/machinery/bots/mulebot.dm @@ -87,12 +87,7 @@ var/global/mulebot_count = 0 // cell: insert it // other: chance to knock rider off bot /obj/machinery/bot/mulebot/attackby(var/obj/item/I, var/mob/user) - if(istype(I,/obj/item/weapon/card/emag)) - locked = !locked - user << "You [locked ? "lock" : "unlock"] the mulebot's controls!" - flick("mulebot-emagged", src) - playsound(loc, 'sound/effects/sparks1.ogg', 100, 0) - else if(istype(I, /obj/item/weapon/card/id) || istype(I, /obj/item/device/pda)) + if(istype(I, /obj/item/weapon/card/id) || istype(I, /obj/item/device/pda)) if(toggle_lock(user)) user << "Controls [(locked ? "locked" : "unlocked")]." updateUsrDialog() @@ -139,7 +134,12 @@ var/global/mulebot_count = 0 ..() return - +/obj/machinery/bot/mulebot/emag_act(user as mob) + locked = !locked + user << "You [locked ? "lock" : "unlock"] the mulebot's controls!" + flick("mulebot-emagged", src) + playsound(loc, 'sound/effects/sparks1.ogg', 100, 0) + /obj/machinery/bot/mulebot/ex_act(var/severity) unload(0) switch(severity) diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm index cd78210b41f..d8a1d7f941f 100644 --- a/code/game/machinery/computer/HolodeckControl.dm +++ b/code/game/machinery/computer/HolodeckControl.dm @@ -162,44 +162,15 @@ /obj/machinery/computer/HolodeckControl/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob) -//Warning, uncommenting this can have concequences. For example, deconstructing the computer may cause holographic eswords to never derez - -/* if(istype(D, /obj/item/weapon/screwdriver)) - playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) - if(do_after(user, 20)) - if (src.stat & BROKEN) - user << "\blue The broken glass falls out." - var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) - new /obj/item/weapon/shard( src.loc ) - var/obj/item/weapon/circuitboard/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( A ) - for (var/obj/C in src) - C.loc = src.loc - A.circuit = M - A.state = 3 - A.icon_state = "3" - A.anchored = 1 - del(src) - else - user << "\blue You disconnect the monitor." - var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) - var/obj/item/weapon/circuitboard/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( A ) - for (var/obj/C in src) - C.loc = src.loc - A.circuit = M - A.state = 4 - A.icon_state = "4" - A.anchored = 1 - del(src) - -*/ - if(istype(D, /obj/item/weapon/card/emag) && !emagged) + return + +/obj/machinery/computer/HolodeckControl/emag_act(user as mob) + if(!emagged) playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) emagged = 1 user << "\blue You vastly increase projector power and override the safety and security protocols." user << "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator." log_game("[key_name(usr)] emagged the Holodeck Control Computer") - src.updateUsrDialog() - return /obj/machinery/computer/HolodeckControl/New() ..() diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 5f0592ecf7f..d4da0df2e54 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -272,8 +272,8 @@ return -/obj/machinery/computer/arcade/battle/attackby(I as obj, user as mob) - if(istype(I, /obj/item/weapon/card/emag) && !emagged) +/obj/machinery/computer/arcade/battle/emag_act(user as mob) + if(!emagged) temp = "If you die in the game, you die for real!" player_hp = 30 player_mp = 10 @@ -287,14 +287,7 @@ enemy_name = "Cuban Pete" name = "Outbomb Cuban Pete" - src.updateUsrDialog() - else - - ..() - - - /obj/machinery/computer/arcade/orion_trail name = "The Orion Trail" diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm index fb3c74e292d..bce0006f488 100644 --- a/code/game/machinery/computer/atmos_control.dm +++ b/code/game/machinery/computer/atmos_control.dm @@ -37,15 +37,16 @@ return ui_interact(user) -/obj/machinery/computer/atmoscontrol/attackby(var/obj/item/I as obj, var/mob/user as mob) - if(istype(I, /obj/item/weapon/card/emag) && !emagged) - user.visible_message("\red \The [user] swipes \a [I] through \the [src], causing the screen to flash!",\ - "\red You swipe your [I] through \the [src], the screen flashing as you gain full control.",\ +/obj/machinery/computer/atmoscontrol/emag_act(user as mob) + if(!emagged) + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + H.visible_message("\red \The [user] swipes \a card through \the [src], causing the screen to flash!",\ + "\red You swipe your card through \the [src], the screen flashing as you gain full control.",\ "You hear the swipe of a card through a reader, and an electronic warble.") emagged = 1 overridden = 1 - return - return ..() /obj/machinery/computer/atmoscontrol/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null) if(user.stat && !isobserver(user)) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index d80b2f94bb5..3a035c3ef7d 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -55,25 +55,21 @@ // Network configuration attackby(I as obj, user as mob) access = list() - if(istype(I,/obj/item/weapon/card/emag)) // If hit by an emag. - var/obj/item/weapon/card/emag/E = I - if(!emagged) - if(E.uses) - E.uses-- - emagged = 1 - user << "\blue You have authorized full network access!" - ui_interact(user) - else - ui_interact(user) - else - ui_interact(user) - else if(istype(I,/obj/item/weapon/card/id)) // If hit by a regular ID card. + if(istype(I,/obj/item/weapon/card/id)) // If hit by a regular ID card. var/obj/item/weapon/card/id/E = I access = E.access ui_interact(user) else ..() + emag_act(user as mob) + if(!emagged) + emagged = 1 + user << "\blue You have authorized full network access!" + ui_interact(user) + else + ui_interact(user) + ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) if(src.z > 6) return if(stat & (NOPOWER|BROKEN)) return diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 3ac81dfa985..23a085675e5 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -240,12 +240,11 @@ var/shuttle_call/shuttle_calls[0] return 1 -/obj/machinery/computer/communications/attackby(var/obj/I as obj, var/mob/user as mob) - if(istype(I,/obj/item/weapon/card/emag/)) +/obj/machinery/computer/communications/emag_act(user as mob) + if(!emagged) src.emagged = 1 user << "You scramble the communication routing circuits!" - ..() - + /obj/machinery/computer/communications/attack_ai(var/mob/user as mob) return src.attack_hand(user) diff --git a/code/game/machinery/computer/honkputer.dm b/code/game/machinery/computer/honkputer.dm index 9efed74b7c9..118307839c1 100644 --- a/code/game/machinery/computer/honkputer.dm +++ b/code/game/machinery/computer/honkputer.dm @@ -57,12 +57,10 @@ src.updateUsrDialog() -/obj/machinery/computer/HONKputer/attackby(var/obj/I as obj, var/mob/user as mob) - if(istype(I,/obj/item/weapon/card/emag/)) +/obj/machinery/computer/HONKputer/emag_act(user as mob) + if(!emagged) src.emagged = 1 user << "You scramble the login circuits, allowing anyone to use the console!" - ..() - /obj/machinery/computer/HONKputer/attack_hand(var/mob/user as mob) if(..()) diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index 37ab61fc857..916b99e05c9 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -41,24 +41,6 @@ return if(!istype(user)) return - if(istype(O,/obj/item/weapon/card/emag/)) - // Will create sparks and print out the console's password. You will then have to wait a while for the console to be back online. - // It'll take more time if there's more characters in the password.. - if(!emag) - if(!isnull(src.linkedServer)) - icon_state = hack_icon // An error screen I made in the computers.dmi - emag = 1 - screen = 2 - spark_system.set_up(5, 0, src) - src.spark_system.start() - var/obj/item/weapon/paper/monitorkey/MK = new/obj/item/weapon/paper/monitorkey - MK.loc = src.loc - // Will help make emagging the console not so easy to get away with. - MK.info += "

£%@%(*$%&(£&?*(%&£/{}" - spawn(100*length(src.linkedServer.decryptkey)) UnmagConsole() - message = rebootmsg - else - user << "A no server error appears on the screen." if(isscrewdriver(O) && emag) //Stops people from just unscrewing the monitor and putting it back to get the console working again. user << "It is too hot to mess with!" @@ -66,6 +48,25 @@ ..() return + +/obj/machinery/computer/message_monitor/emag_act(user as mob) + // Will create sparks and print out the console's password. You will then have to wait a while for the console to be back online. + // It'll take more time if there's more characters in the password.. + if(!emag) + if(!isnull(src.linkedServer)) + icon_state = hack_icon // An error screen I made in the computers.dmi + emag = 1 + screen = 2 + spark_system.set_up(5, 0, src) + src.spark_system.start() + var/obj/item/weapon/paper/monitorkey/MK = new/obj/item/weapon/paper/monitorkey + MK.loc = src.loc + // Will help make emagging the console not so easy to get away with. + MK.info += "

£%@%(*$%&(£&?*(%&£/{}" + spawn(100*length(src.linkedServer.decryptkey)) UnmagConsole() + message = rebootmsg + else + user << "A no server error appears on the screen." /obj/machinery/computer/message_monitor/update_icon() ..() diff --git a/code/game/machinery/computer/shuttle.dm b/code/game/machinery/computer/shuttle.dm index 0815cf7932a..93b4c91c2c9 100644 --- a/code/game/machinery/computer/shuttle.dm +++ b/code/game/machinery/computer/shuttle.dm @@ -56,11 +56,13 @@ world << "\blue All authorizations to shortening time for shuttle launch have been revoked!" src.authorized.len = 0 src.authorized = list( ) - - else if (istype(W, /obj/item/weapon/card/emag) && !emagged) + return + + emag_act(user as mob) + if (!emagged) var/choice = alert(user, "Would you like to launch the shuttle?","Shuttle control", "Launch", "Cancel") - if(!emagged && !emergency_shuttle.location() && user.get_active_hand() == W) + if(!emagged && !emergency_shuttle.location()) switch(choice) if("Launch") world << "\blue Alert: Shuttle launch time shortened to 10 seconds!" @@ -68,4 +70,3 @@ emagged = 1 if("Cancel") return - return diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index c00668a7276..94ded8abee1 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -158,7 +158,7 @@ for reference: src.icon_state = "barrier[src.locked]" attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/card/id/)) + if (istype(W, /obj/item/weapon/card/id)) if (src.allowed(user)) if (src.emagged < 2.0) src.locked = !src.locked @@ -177,24 +177,6 @@ for reference: visible_message("\red BZZzZZzZZzZT") return return - else if (istype(W, /obj/item/weapon/card/emag)) - if (src.emagged == 0) - src.emagged = 1 - src.req_access = null - user << "You break the ID authentication lock on the [src]." - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(2, 1, src) - s.start() - visible_message("\red BZZzZZzZZzZT") - return - else if (src.emagged == 1) - src.emagged = 2 - user << "You short out the anchoring mechanism on the [src]." - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(2, 1, src) - s.start() - visible_message("\red BZZzZZzZZzZT") - return else if (istype(W, /obj/item/weapon/wrench)) if (src.health < src.maxhealth) src.health = src.maxhealth @@ -218,6 +200,23 @@ for reference: if (src.health <= 0) src.explode() ..() + + emag_act(user as mob) + if (!emagged) + emagged = 1 + req_access = null + user << "You break the ID authentication lock on the [src]." + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, src) + s.start() + visible_message("\red BZZzZZzZZzZT") + else if (src.emagged == 1) + src.emagged = 2 + user << "You short out the anchoring mechanism on the [src]." + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, src) + s.start() + visible_message("\red BZZzZZzZZzZT") ex_act(severity) switch(severity) diff --git a/code/game/machinery/door_control.dm b/code/game/machinery/door_control.dm index 2dcb0c0b2e0..84591381582 100644 --- a/code/game/machinery/door_control.dm +++ b/code/game/machinery/door_control.dm @@ -57,11 +57,14 @@ */ if(istype(W, /obj/item/device/detective_scanner)) return - if(istype(W, /obj/item/weapon/card/emag)) + return src.attack_hand(user) + +/obj/machinery/door_control/emag_act(user as mob) + if(!emagged) + emagged = 1 req_access = list() req_one_access = list() playsound(src.loc, "sparks", 100, 1) - return src.attack_hand(user) /obj/machinery/door_control/attack_hand(mob/user as mob) src.add_fingerprint(usr) diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 88d72fbf8b9..10123890da7 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -153,10 +153,7 @@ if(!src.requiresID()) user = null if(src.density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade))) - flick("door_spark", src) - sleep(6) - open() - operating = -1 + emag_act(user) return 1 if(src.allowed(user) || src.emergency == 1) if(src.density) @@ -168,6 +165,13 @@ flick("door_deny", src) return +/obj/machinery/door/emag_act(user as mob) + if(density) + flick("door_spark", src) + sleep(6) + open() + operating = -1 + return 1 /obj/machinery/door/blob_act() if(prob(40)) diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 84563748126..cbb39a73aa7 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -225,21 +225,13 @@ /obj/machinery/door/window/attack_hand(mob/user as mob) return src.attackby(user, user) -/obj/machinery/door/window/attackby(obj/item/weapon/I as obj, mob/living/user as mob) - - //If it's in the process of opening/closing, ignore the click - if (src.operating) - return - - add_fingerprint(user) - - //Emags and ninja swords? You may pass. - if (src.density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade))) +/obj/machinery/door/window/emag_act(user as mob, weapon as obj) + if(density) src.operating = -1 flick("[src.base_state]spark", src) sleep(6) desc += "
Its access panel is smoking slightly." - if(istype(I, /obj/item/weapon/melee/energy/blade)) + if(istype(weapon, /obj/item/weapon/melee/energy/blade)) var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() spark_system.set_up(5, 0, src.loc) spark_system.start() @@ -252,6 +244,19 @@ open() emagged = 1 return 1 + +/obj/machinery/door/window/attackby(obj/item/weapon/I as obj, mob/living/user as mob) + + //If it's in the process of opening/closing, ignore the click + if (src.operating) + return + + add_fingerprint(user) + + //Ninja swords? You may pass. + if (density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade))) + emag_act(user,I) + return 1 if(istype(I, /obj/item/weapon/screwdriver)) if(src.density || src.operating) diff --git a/code/game/machinery/metaldetector.dm b/code/game/machinery/metaldetector.dm index 3d7ccb4ab3b..72be4f67785 100644 --- a/code/game/machinery/metaldetector.dm +++ b/code/game/machinery/metaldetector.dm @@ -27,11 +27,6 @@ return 1 /obj/machinery/metaldetector/attackby(obj/item/W as obj, mob/user as mob) - if(istype(W, /obj/item/weapon/card/emag)) - if(!src.emagged) - src.emagged = 1 - user << "\blue You short out the circuitry." - return if(istype(W, /obj/item/weapon/card)) for(var/ID in list(user.equipped(), user:wear_id, user:belt)) if(src.check_access(ID,list("20"))) @@ -46,6 +41,12 @@ else user << "\red You lack access to the control panel!" return + +/obj/machinery/metaldetector/emag_act(user as mob) + if(!emagged) + emagged = 1 + user << "\blue You short out the circuitry." + return /obj/machinery/metaldetector/Crossed(AM as mob|obj) if(emagged) diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 31da7e13203..5196f96471f 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -307,20 +307,7 @@ Status: []
"}, del(src) - if ((istype(W, /obj/item/weapon/card/emag)) && (!src.emagged)) - // Emagging the turret makes it go bonkers and stun everyone. It also makes - // the turret shoot much, much faster. - - user << "\red You short out [src]'s threat assessment circuits." - spawn(0) - for(var/mob/O in hearers(src, null)) - O.show_message("\red [src] hums oddly...", 1) - emagged = 1 - src.on = 0 // turns off the turret temporarily - sleep(60) // 6 seconds for the traitor to gtfo of the area before the turret decides to ruin his shit - on = 1 // turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here - - else if((istype(W, /obj/item/weapon/wrench)) && (!on)) + if((istype(W, /obj/item/weapon/wrench)) && (!on)) if(raised) return // This code handles moving the turret around. After all, it's a portable turret! @@ -359,7 +346,19 @@ Status: []
"}, attacked = 0 ..() +/obj/machinery/porta_turret/emag_act(user as mob) + if(!src.emagged) + // Emagging the turret makes it go bonkers and stun everyone. It also makes + // the turret shoot much, much faster. + user << "\red You short out [src]'s threat assessment circuits." + spawn(0) + for(var/mob/O in hearers(src, null)) + O.show_message("\red [src] hums oddly...", 1) + emagged = 1 + src.on = 0 // turns off the turret temporarily + sleep(60) // 6 seconds for the traitor to gtfo of the area before the turret decides to ruin his shit + on = 1 // turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here /obj/machinery/porta_turret/bullet_act(var/obj/item/projectile/Proj) if(on) diff --git a/code/game/machinery/programmable_unloader.dm b/code/game/machinery/programmable_unloader.dm index e7039af7f64..f2aaefc03fa 100644 --- a/code/game/machinery/programmable_unloader.dm +++ b/code/game/machinery/programmable_unloader.dm @@ -196,19 +196,6 @@ return /obj/machinery/programmable/attackby(obj/item/I as obj, mob/user as mob) - if(istype(I,/obj/item/weapon/card/emag)) - if(emagged) - return - user << "You swipe the unloader with your card. After a moment's grinding, it beeps in a sinister fashion." - playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) - emagged = 1 - overrides += emag_overrides - - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(2, 1, src) - s.start() - - return if(istype(I,/obj/item/weapon/wrench)) // code borrowed from pipe dispenser if (unwrenched==0) playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) @@ -281,7 +268,18 @@ I.loc = src RefreshParts() +/obj/machinery/programmable/emag_act(user as mob) + if(emagged) + return + user << "You swipe the unloader with your card. After a moment's grinding, it beeps in a sinister fashion." + playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) + emagged = 1 + overrides += emag_overrides + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, src) + s.start() + return /obj/machinery/programmable/process() if (!output || !input) diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index 27e46c668b5..0b3301648bc 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -32,13 +32,7 @@ var/const/SAFETY_COOLDOWN = 100 /obj/machinery/recycler/attackby(var/obj/item/I, var/mob/user) - if(istype(I, /obj/item/weapon/card/emag) && !emagged) - emagged = 1 - if(safety_mode) - safety_mode = 0 - update_icon() - playsound(src.loc, "sparks", 75, 1, -1) - else if(istype(I, /obj/item/weapon/screwdriver) && emagged) + if(istype(I, /obj/item/weapon/screwdriver) && emagged) emagged = 0 update_icon() user << "You reset the crusher to its default factory settings." @@ -46,6 +40,14 @@ var/const/SAFETY_COOLDOWN = 100 ..() return add_fingerprint(user) + +/obj/machinery/recycler/emag_act(user as mob) + if(!emagged) + emagged = 1 + if(safety_mode) + safety_mode = 0 + update_icon() + playsound(src.loc, "sparks", 75, 1, -1) /obj/machinery/recycler/update_icon() ..() diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 1b05e84fe9f..0a0d9c32ebd 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -681,24 +681,6 @@ src.updateUsrDialog() return - else if(istype(I,/obj/item/weapon/card/emag)) - - if(emagged) - user << "\red The cycler has already been subverted." - return - - var/obj/item/weapon/card/emag/E = I - src.updateUsrDialog() - E.uses-- - - //Clear the access reqs, disable the safeties, and open up all paintjobs. - user << "\red You run the sequencer across the interface, corrupting the operating protocols." - departments = list("Engineering","Mining","Medical","Security","Atmos","^%###^%$") - emagged = 1 - safeties = 0 - req_access = list() - return - else if(istype(I,/obj/item/clothing/head/helmet/space)) if(locked) @@ -748,6 +730,19 @@ return ..() + +/obj/machinery/suit_cycler/emag_act(user as mob) + if(emagged) + user << "\red The cycler has already been subverted." + return + + //Clear the access reqs, disable the safeties, and open up all paintjobs. + user << "\red You run the sequencer across the interface, corrupting the operating protocols." + departments = list("Engineering","Mining","Medical","Security","Atmos","^%###^%$") + emagged = 1 + safeties = 0 + req_access = list() + return /obj/machinery/suit_cycler/attack_hand(mob/user as mob) diff --git a/code/game/machinery/telecomms/logbrowser.dm b/code/game/machinery/telecomms/logbrowser.dm index 9bd46e57ce7..ef50d3ea865 100644 --- a/code/game/machinery/telecomms/logbrowser.dm +++ b/code/game/machinery/telecomms/logbrowser.dm @@ -244,9 +244,11 @@ A.icon_state = "4" A.anchored = 1 del(src) - else if(istype(D, /obj/item/weapon/card/emag) && !emagged) + src.updateUsrDialog() + return + + emag_act(user as mob) + if(!emagged) playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) emagged = 1 user << "\blue You you disable the security protocols" - src.updateUsrDialog() - return diff --git a/code/game/machinery/telecomms/telemonitor.dm b/code/game/machinery/telecomms/telemonitor.dm index 995d0fc239f..c02ef59e1be 100644 --- a/code/game/machinery/telecomms/telemonitor.dm +++ b/code/game/machinery/telecomms/telemonitor.dm @@ -153,9 +153,11 @@ A.icon_state = "4" A.anchored = 1 del(src) - else if(istype(D, /obj/item/weapon/card/emag) && !emagged) - playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) - emagged = 1 - user << "\blue You you disable the security protocols" src.updateUsrDialog() return + + emag_act(user as mob) + if(!emagged) + playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) + emagged = 1 + user << "\blue You you disable the security protocols" \ No newline at end of file diff --git a/code/game/machinery/telecomms/traffic_control.dm b/code/game/machinery/telecomms/traffic_control.dm index fed56a35124..e2b42ddbb44 100644 --- a/code/game/machinery/telecomms/traffic_control.dm +++ b/code/game/machinery/telecomms/traffic_control.dm @@ -233,12 +233,14 @@ A.icon_state = "4" A.anchored = 1 del(src) - else if(istype(D, /obj/item/weapon/card/emag) && !emagged) + src.updateUsrDialog() + return + +/obj/machinery/computer/telecomms/traffic/emag_act(user as mob) + if(!emagged) playsound(get_turf(src), 'sound/effects/sparks4.ogg', 75, 1) emagged = 1 user << "\blue You you disable the security protocols" - src.updateUsrDialog() - return /obj/machinery/computer/telecomms/traffic/proc/canAccess(var/mob/user) if(issilicon(user) || in_range(user, src)) diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index 03a3fa2a3f6..b050fb624e1 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -31,16 +31,7 @@ return power_station /obj/machinery/computer/teleporter/attackby(I as obj, mob/living/user as mob) - if(istype(I,/obj/item/weapon/card/emag)) // If hit by an emag. - var/obj/item/weapon/card/emag/E = I - if(!emagged) - if(E.uses) - E.uses-- - emagged = 1 - user << "\blue The teleporter can now lock on to Syndicate beacons!" - else - ui_interact(user) - else if(istype(I, /obj/item/device/gps)) + if(istype(I, /obj/item/device/gps)) var/obj/item/device/gps/L = I if(L.locked_location && !(stat & (NOPOWER|BROKEN))) user.before_take_item(L) @@ -53,6 +44,13 @@ else ..() return + +/obj/machinery/computer/teleporter/emag_act(user as mob) + if(!emagged) + emagged = 1 + user << "\blue The teleporter can now lock on to Syndicate beacons!" + else + ui_interact(user) /obj/machinery/computer/teleporter/attack_paw(mob/user) usr << "You are too primitive to use this computer." diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm index 4f77d7d7c70..90dd7f27d71 100644 --- a/code/game/machinery/turrets.dm +++ b/code/game/machinery/turrets.dm @@ -364,15 +364,6 @@ if (istype(user, /mob/living/silicon)) return src.attack_hand(user) - if (istype(W, /obj/item/weapon/card/emag) && !emagged) - user << "\red You short out the turret controls' access analysis module." - emagged = 1 - locked = 0 - if(user.machine==src) - src.attack_hand(user) - - return - else if( get_dist(src, user) == 0 ) // trying to unlock the interface if (src.allowed(usr)) if(emagged) @@ -390,6 +381,17 @@ src.attack_hand(user) else user << "Access denied." + +/obj/machinery/turretid/emag_act(user as mob) + if (!emagged) + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + user << "\red You short out the turret controls' access analysis module." + emagged = 1 + locked = 0 + if(H.machine==src) + src.attack_hand(user) /obj/machinery/turretid/attack_ai(mob/user as mob) if(!ailock) diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index ff85b1321ff..a7191450c9e 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -244,10 +244,6 @@ break default_deconstruction_crowbar(W) - if(istype(W, /obj/item/weapon/card/emag)) - emagged = 1 - user << "You short out the product lock on [src]" - return else if(istype(W, /obj/item/weapon/screwdriver) && anchored) playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) panel_open = !panel_open @@ -288,6 +284,12 @@ user << "You should probably unscrew the service panel first." else ..() + +/obj/machinery/vending/emag_act(user as mob) + emagged = 1 + user << "You short out the product lock on [src]" + return + /** * Receive payment with cashmoney. * diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 5b7a50c8594..76d2c03c934 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -513,10 +513,7 @@ return 1 else user << "You can't load \the [name] while it's opened." - return 1 - - if(istype(W,/obj/item/weapon/card/emag)) - emag() + return 1 if(istype(W, /obj/item/stack)) var/material @@ -561,6 +558,9 @@ else user << "\The [src] cannot hold any more [sname] sheet\s." return + +/obj/machinery/mecha_part_fabricator/emag_act(user as mob) + emag() /obj/machinery/mecha_part_fabricator/proc/material2name(var/ID) return copytext(ID,2) \ No newline at end of file diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index e62872c9664..d37f0d0a544 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -697,17 +697,6 @@ /obj/mecha/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W, /obj/item/weapon/card/emag)) - if(istype(src, /obj/mecha/working/ripley) && emagged == 0) - emagged = 1 - usr << "\blue You slide the [W] through the [src]'s ID slot." - playsound(src.loc, "sparks", 100, 1) - src.desc += "
\red The mech's equiptment slots spark dangerously!" - else - usr <<"\red The [src]'s ID slot rejects the [W]." - return - - if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/mmi/posibrain)) if(mmi_move_inside(W,user)) user << "[src]-MMI interface initialized successfuly" @@ -862,6 +851,15 @@ */ return +/obj/mecha/emag_act(user as mob) + if(istype(src, /obj/mecha/working/ripley) && emagged == 0) + emagged = 1 + usr << "\blue You slide the card through the [src]'s ID slot." + playsound(src.loc, "sparks", 100, 1) + src.desc += "
\red The mech's equiptment slots spark dangerously!" + else + usr <<"\red The [src]'s ID slot rejects the card." + return /* diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index 63836e9ecc6..80421bac26e 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -72,10 +72,6 @@ usr << "It has [uses] lights remaining." /obj/item/device/lightreplacer/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/weapon/card/emag) && emagged == 0) - Emag() - return - if(istype(W, /obj/item/stack/sheet/glass)) var/obj/item/stack/sheet/glass/G = W if(G.amount - decrement >= 0 && uses < max_uses) @@ -104,7 +100,10 @@ user << "You need a working light." return - +/obj/item/device/lightreplacer/emag_act(user as mob) + if(!emagged) + Emag() + /obj/item/device/lightreplacer/attack_self(mob/user) /* // This would probably be a bit OP. If you want it though, uncomment the code. if(isrobot(user)) diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm index 0d12f8262b6..910e37d3a5a 100644 --- a/code/game/objects/items/devices/megaphone.dm +++ b/code/game/objects/items/devices/megaphone.dm @@ -47,10 +47,8 @@ spamcheck = 0 return -/obj/item/device/megaphone/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/weapon/card/emag) && !emagged) +/obj/item/device/megaphone/emag_act(user as mob) + if(!emagged) user << "\red You overload \the [src]'s voice synthesizer." emagged = 1 insults = rand(1, 3)//to prevent dickflooding - return - return \ No newline at end of file diff --git a/code/game/objects/items/devices/radio/beacon.dm b/code/game/objects/items/devices/radio/beacon.dm index 15f59e66dcb..628a6ee8bba 100644 --- a/code/game/objects/items/devices/radio/beacon.dm +++ b/code/game/objects/items/devices/radio/beacon.dm @@ -8,15 +8,11 @@ var/emagged = 0 var/syndicate = 0 -/obj/item/device/radio/beacon/attackby(I as obj, mob/living/user as mob) - if(istype(I,/obj/item/weapon/card/emag)) // If hit by an emag. - var/obj/item/weapon/card/emag/E = I - if(!emagged) - if(E.uses) - E.uses-- - emagged = 1 - syndicate = 1 - user << "\blue The This beacon now only be locked on to by emagged teleporters!" +/obj/item/device/radio/beacon/emag_act(user as mob) + if(!emagged) + emagged = 1 + syndicate = 1 + user << "\blue The This beacon now only be locked on to by emagged teleporters!" /obj/item/device/radio/beacon/hear_talk() return diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm index 555dbe1caea..697c5574a84 100644 --- a/code/game/objects/items/devices/taperecorder.dm +++ b/code/game/objects/items/devices/taperecorder.dm @@ -38,17 +38,15 @@ storedinfo += "\[[time2text(timerecorded*10,"mm:ss")]\] [M.name] says, \"[msg]\"" return -/obj/item/device/taperecorder/attackby(obj/item/weapon/W as obj, mob/user as mob) - ..() - if(istype(W, /obj/item/weapon/card/emag)) - if(emagged == 0) - emagged = 1 - recording = 0 - user << "PZZTTPFFFT" - icon_state = "taperecorderidle" - else - user << "It is already emagged!" - +/obj/item/device/taperecorder/emag_act(user as mob) + if(!emagged == 0) + emagged = 1 + recording = 0 + user << "PZZTTPFFFT" + icon_state = "taperecorderidle" + else + user << "It is already emagged!" + /obj/item/device/taperecorder/proc/explode() var/turf/T = get_turf(loc) if(ismob(loc)) diff --git a/code/game/objects/items/devices/whistle.dm b/code/game/objects/items/devices/whistle.dm index 3b26c943acb..3ef104cabbb 100644 --- a/code/game/objects/items/devices/whistle.dm +++ b/code/game/objects/items/devices/whistle.dm @@ -24,9 +24,8 @@ spawn(20) spamcheck = 0 -/obj/item/device/hailer/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/weapon/card/emag) && !emagged) +/obj/item/device/hailer/emag_act(user as mob) + if(!emagged) user << "\red You overload \the [src]'s voice synthesizer." emagged = 1 - return - return \ No newline at end of file + \ No newline at end of file diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index 0fb733cad2a..dd849488a3b 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -69,58 +69,15 @@ item_state = "card-id" origin_tech = "magnets=2;syndicate=2" flags = NOBLUDGEON - var/uses = 1000000 - // List of devices that cost a use to emag. - var/list/devices = list( - /obj/item/robot_parts, - /obj/item/weapon/storage/lockbox, - /obj/item/weapon/storage/secure, - /obj/item/weapon/circuitboard, - /obj/item/device/eftpos, - /obj/item/device/lightreplacer, - /obj/item/device/taperecorder, - /obj/item/device/hailer, - /obj/item/clothing/accessory/holobadge, - /obj/structure/closet/crate/secure, - /obj/structure/closet/secure_closet, - /obj/machinery/librarycomp, - /obj/machinery/computer, - /obj/machinery/power, - /obj/machinery/suspension_gen, - /obj/machinery/shield_capacitor, - /obj/machinery/shield_gen, -// /obj/machinery/zero_point_emitter, - /obj/machinery/clonepod, - /obj/machinery/deployable, - /obj/machinery/door_control, - /obj/machinery/porta_turret, - /obj/machinery/shieldgen, - /obj/machinery/turretid, - /obj/machinery/vending, - /obj/machinery/bot, - /obj/machinery/door, - /obj/machinery/telecomms, - /obj/machinery/mecha_part_fabricator, - /obj/vehicle - ) +/obj/item/weapon/card/emag/attack() + return -/obj/item/weapon/card/emag/afterattack(var/obj/item/weapon/O as obj, mob/user as mob) - - for(var/type in devices) - if(istype(O,type)) - uses-- - break - - if(uses<1) - user.visible_message("[src] fizzles and sparks - it seems it's been used once too often, and is now broken.") - user.drop_item() - var/obj/item/weapon/card/emag_broken/junk = new(user.loc) - junk.add_fingerprint(user) - del(src) +/obj/item/weapon/card/emag/afterattack(atom/target, mob/user, proximity) + var/atom/A = target + if(!proximity) return - - ..() + A.emag_act(user) /obj/item/weapon/card/id name = "identification card" @@ -444,4 +401,4 @@ decal_name = "cryptographic sequencer" decal_desc = "It's a card with a magnetic strip attached to some circuitry." decal_icon_state = "emag" - override_name = 1 + override_name = 1 diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index b65a1904116..a1ddb256d89 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -92,14 +92,6 @@ bcell = W user << "You install a cell in [src]." - if(istype(W, /obj/item/weapon/card/emag)) - if(safety) - safety = 0 - user << "You silently disable [src]'s safety protocols with the [W]." - else - safety = 1 - user << "You silently enable [src]'s safety protocols with the [W]." - if(istype(W, /obj/item/weapon/screwdriver)) if(bcell) bcell.updateicon() @@ -110,7 +102,13 @@ update_icon() return - +/obj/item/weapon/defibrillator/emag_act(user as mob) + if(safety) + safety = 0 + user << "You silently disable [src]'s safety protocols with the card." + else + safety = 1 + user << "You silently enable [src]'s safety protocols with the card." /obj/item/weapon/defibrillator/emp_act(severity) if(bcell) diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm index 2a4d03b8f0a..a33fe344e77 100644 --- a/code/game/objects/items/weapons/storage/secure.dm +++ b/code/game/objects/items/weapons/storage/secure.dm @@ -34,23 +34,8 @@ attackby(obj/item/weapon/W as obj, mob/user as mob) if(locked) - if ( (istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)) && (!src.emagged)) - emagged = 1 - src.overlays += image('icons/obj/storage.dmi', icon_sparking) - sleep(6) - src.overlays = null - overlays += image('icons/obj/storage.dmi', icon_locking) - locked = 0 - if(istype(W, /obj/item/weapon/melee/energy/blade)) - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, src.loc) - spark_system.start() - playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) - playsound(src.loc, "sparks", 50, 1) - user << "You slice through the lock on [src]." - else - user << "You short out the lock on [src]." - return + if ((istype(W, /obj/item/weapon/melee/energy/blade)) && (!src.emagged)) + emag_act(user, W) if (istype(W, /obj/item/weapon/screwdriver)) if (do_after(user, 20)) @@ -79,6 +64,25 @@ // -> storage/attackby() what with handle insertion, etc ..() + + emag_act(user as mob, weapon as obj) + if(!emagged) + emagged = 1 + src.overlays += image('icons/obj/storage.dmi', icon_sparking) + sleep(6) + src.overlays = null + overlays += image('icons/obj/storage.dmi', icon_locking) + locked = 0 + if(istype(weapon, /obj/item/weapon/melee/energy/blade)) + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, src.loc) + spark_system.start() + playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) + playsound(src.loc, "sparks", 50, 1) + user << "You slice through the lock on [src]." + else + user << "You short out the lock on [src]." + return MouseDrop(over_object, src_location, over_location) diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index 1e0682fa5f0..9ba54e57306 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -189,17 +189,7 @@ user.visible_message("\red [user] displays their NanoTrasen Internal Security Legal Authorization Badge.\nIt reads: [stored_name], NT Security.","\red You display your NanoTrasen Internal Security Legal Authorization Badge.\nIt reads: [stored_name], NT Security.") /obj/item/clothing/accessory/holobadge/attackby(var/obj/item/O as obj, var/mob/user as mob) - - if (istype(O, /obj/item/weapon/card/emag)) - if (emagged) - user << "\red [src] is already cracked." - return - else - emagged = 1 - user << "\red You swipe [O] and crack the holobadge security checks." - return - - else if(istype(O, /obj/item/weapon/card/id) || istype(O, /obj/item/device/pda)) + if(istype(O, /obj/item/weapon/card/id) || istype(O, /obj/item/device/pda)) var/obj/item/weapon/card/id/id_card = null @@ -218,6 +208,15 @@ user << "[src] rejects your insufficient access rights." return ..() + +/obj/item/clothing/accessory/holobadge/emag_act(user as mob) + if (emagged) + user << "\red [src] is already cracked." + return + else + emagged = 1 + user << "\red You swipe the card and crack the holobadge security checks." + return /obj/item/clothing/accessory/holobadge/attack(mob/living/carbon/human/M, mob/living/user) if(isliving(user)) diff --git a/code/modules/computer3/component.dm b/code/modules/computer3/component.dm index 501bbc973eb..ca4639c73bd 100644 --- a/code/modules/computer3/component.dm +++ b/code/modules/computer3/component.dm @@ -85,6 +85,15 @@ var/dualslot = 0 // faster than typechecking attackby_types = list(/obj/item/weapon/card) + emag_act(user as mob) + if(!writer) + usr << "You insert \the card, and the computer grinds, sparks, and beeps. After a moment, the card ejects itself." + computer.emagged = 1 + return 1 + else + usr << "You are unable to insert \the card, as the reader slot is occupied" + return 0 + attackby(var/obj/item/I as obj, var/mob/user as mob) if(istype(I,/obj/item/weapon/card)) insert(I) @@ -102,14 +111,6 @@ usr << "This device has only one card slot" return 0 - if(istype(card,/obj/item/weapon/card/emag)) // emag reader slot - if(!writer) - usr << "You insert \the [card], and the computer grinds, sparks, and beeps. After a moment, the card ejects itself." - computer.emagged = 1 - return 1 - else - usr << "You are unable to insert \the [card], as the reader slot is occupied" - var/mob/living/L = usr switch(slot) if(1) @@ -132,7 +133,6 @@ else usr << "There is already something in the reader slot." - // Usage of insert() preferred, as it also tells result to the user. proc/equip_to_reader(var/obj/item/weapon/card/card, var/mob/living/L) if(!reader) diff --git a/code/modules/computer3/computers/communications.dm b/code/modules/computer3/computers/communications.dm index 58c7f904f06..37437fdf6aa 100644 --- a/code/modules/computer3/computers/communications.dm +++ b/code/modules/computer3/computers/communications.dm @@ -68,9 +68,7 @@ authenticated = 1 if(access_captain in I.GetAccess()) authenticated = 2 - if(istype(I,/obj/item/weapon/card/emag)) - authenticated = 2 - computer.emagged = 1 + if("logout" in href_list) authenticated = 0 diff --git a/code/modules/computer3/computers/shuttle.dm b/code/modules/computer3/computers/shuttle.dm index 5d5fab6528b..9f0619ce321 100644 --- a/code/modules/computer3/computers/shuttle.dm +++ b/code/modules/computer3/computers/shuttle.dm @@ -60,11 +60,13 @@ world << "\blue All authorizations to shorting time for shuttle launch have been revoked!" src.authorized.len = 0 src.authorized = list( ) - - else if (istype(W, /obj/item/card/emag) && !emagged) + return + + emag_act(user as mob) + if (!emagged) var/choice = alert(user, "Would you like to launch the shuttle?","Shuttle control", "Launch", "Cancel") - if(!emagged && emergency_shuttle.location == 1 && user.get_active_hand() == W) + if(!emagged && emergency_shuttle.location == 1) switch(choice) if("Launch") world << "\blue Alert: Shuttle launch time shortened to 10 seconds!" @@ -72,4 +74,3 @@ emagged = 1 if("Cancel") return - return diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index c1fdb193485..66c19bfcda0 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -238,8 +238,6 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f onclose(user, "library") /obj/machinery/librarycomp/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (src.density && istype(W, /obj/item/weapon/card/emag)) - src.emagged = 1 if(istype(W, /obj/item/weapon/barcodescanner)) var/obj/item/weapon/barcodescanner/scanner = W scanner.computer = src @@ -248,6 +246,10 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f V.show_message("[src] lets out a low, short blip.", 2) else ..() + +/obj/machinery/librarycomp/emag_act(user as mob) + if (src.density) + src.emagged = 1 /obj/machinery/librarycomp/Topic(href, href_list) if(..()) diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm index 0e0889bc637..ed588a76482 100644 --- a/code/modules/mining/laborcamp/laborstacker.dm +++ b/code/modules/mining/laborcamp/laborstacker.dm @@ -63,9 +63,10 @@ /obj/machinery/mineral/labor_claim_console/attackby(obj/item/I as obj, mob/user as mob) if(istype(I, /obj/item/weapon/card/id)) return attack_hand(user) - else if(istype(I, /obj/item/weapon/card/emag)) - return emag(user) ..() + +/obj/machinery/mineral/labor_claim_console/emag_act(user as mob) + emag(user) /obj/machinery/mineral/labor_claim_console/proc/emag(mob/user as mob) if(!emagged) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 5b06aaa9b40..f624a94924a 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -198,7 +198,17 @@ emp_act I.emp_act(severity) ..() - +/mob/living/carbon/human/emag_act(user as mob, var/datum/organ/external/affecting) + if(!(affecting.status & ORGAN_ROBOT)) + user << "\red That limb isn't robotic." + return + if(affecting.sabotaged) + user << "\red [src]'s [affecting.display_name] is already sabotaged!" + else + user << "\red You sneakily slide the card into the dataport on [src]'s [affecting.display_name] and short out the safeties." + affecting.sabotaged = 1 + return 1 + //Returns 1 if the attack hit, 0 if it missed. /mob/living/carbon/human/proc/attacked_by(var/obj/item/I, var/mob/living/user, var/def_zone) if(!I || !user) return 0 @@ -236,17 +246,8 @@ emp_act return 0 if(istype(I,/obj/item/weapon/card/emag)) - if(!(affecting.status & ORGAN_ROBOT)) - user << "\red That limb isn't robotic." - return - if(affecting.sabotaged) - user << "\red [src]'s [affecting.display_name] is already sabotaged!" - else - user << "\red You sneakily slide [I] into the dataport on [src]'s [affecting.display_name] and short out the safeties." - var/obj/item/weapon/card/emag/emag = I - emag.uses-- - affecting.sabotaged = 1 - return 1 + emag_act(user, affecting) + if(! I.discrete) if(I.attack_verb.len) visible_message("\red [src] has been [pick(I.attack_verb)] in the [hit_area] with [I.name] by [user]!") diff --git a/code/modules/mob/living/silicon/mommi/mommi.dm b/code/modules/mob/living/silicon/mommi/mommi.dm index 91defdaedfb..9151be4369c 100644 --- a/code/modules/mob/living/silicon/mommi/mommi.dm +++ b/code/modules/mob/living/silicon/mommi/mommi.dm @@ -240,68 +240,6 @@ They can only use one tool at a time, they can't choose modules, and they have 1 else user << "\red Access denied." - else if(istype(W, /obj/item/weapon/card/emag)) // trying to unlock with an emag card - if(!opened)//Cover is closed - if(locked) - if(prob(90)) - user << "You emag the cover lock." - locked = 0 - else - user << "You fail to emag the cover lock." - if(prob(25)) - src << "Hack attempt detected." - else - user << "The cover is already unlocked." - return - - if(opened)//Cover is open - if(emagged) return//Prevents the X has hit Y with Z message also you cant emag them twice - if(wiresexposed) - user << "You must close the panel first" - return - else - sleep(6) - if(prob(50)) - emagged = 1 - lawupdate = 0 - connected_ai = null - user << "You emag [src]'s interface." -// message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.") - log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.") - clear_supplied_laws() - clear_inherent_laws() - laws = new /datum/ai_laws/syndicate_override - var/time = time2text(world.realtime,"hh:mm:ss") - lawchanges.Add("[time] : [user.name]([user.key]) emagged [name]([key])") - set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.") - src << "\red ALERT: Foreign software detected." - sleep(5) - src << "\red Initiating diagnostics..." - sleep(20) - src << "\red SynBorg v1.7 loaded." - sleep(5) - src << "\red LAW SYNCHRONISATION ERROR" - sleep(5) - src << "\red Would you like to send a report to NanoTraSoft? Y/N" - sleep(10) - src << "\red > N" - sleep(20) - src << "\red ERRORERRORERROR" - src << "Obey these laws:" - laws.show_laws(src) - src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands." - if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner)) - for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules) - del(D) - src.module.modules += new /obj/item/weapon/pickaxe/diamonddrill(src.module) - src.module.rebuild() - updateicon() - else - user << "You fail to [ locked ? "unlock" : "lock"] [src]'s interface." - if(prob(25)) - src << "Hack attempt detected." - return - else if(istype(W, /obj/item/borg/upgrade/)) var/obj/item/borg/upgrade/U = W if(!opened) @@ -322,6 +260,68 @@ They can only use one tool at a time, they can't choose modules, and they have 1 else spark_system.start() return ..() + +/mob/living/silicon/robot/mommi/emag_act(user as mob) + if(!opened)//Cover is closed + if(locked) + if(prob(90)) + user << "You emag the cover lock." + locked = 0 + else + user << "You fail to emag the cover lock." + if(prob(25)) + src << "Hack attempt detected." + else + user << "The cover is already unlocked." + return + + if(opened)//Cover is open + if(emagged) return//Prevents the X has hit Y with Z message also you cant emag them twice + if(wiresexposed) + user << "You must close the panel first" + return + else + sleep(6) + if(prob(50)) + emagged = 1 + lawupdate = 0 + connected_ai = null + user << "You emag [src]'s interface." +// message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.") + log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.") + clear_supplied_laws() + clear_inherent_laws() + laws = new /datum/ai_laws/syndicate_override + var/time = time2text(world.realtime,"hh:mm:ss") + lawchanges.Add("[time] : [user.name]([user.key]) emagged [name]([key])") + set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.") + src << "\red ALERT: Foreign software detected." + sleep(5) + src << "\red Initiating diagnostics..." + sleep(20) + src << "\red SynBorg v1.7 loaded." + sleep(5) + src << "\red LAW SYNCHRONISATION ERROR" + sleep(5) + src << "\red Would you like to send a report to NanoTraSoft? Y/N" + sleep(10) + src << "\red > N" + sleep(20) + src << "\red ERRORERRORERROR" + src << "Obey these laws:" + laws.show_laws(src) + src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands." + if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner)) + for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules) + del(D) + src.module.modules += new /obj/item/weapon/pickaxe/diamonddrill(src.module) + src.module.rebuild() + updateicon() + else + user << "You fail to [ locked ? "unlock" : "lock"] [src]'s interface." + if(prob(25)) + src << "Hack attempt detected." + return /mob/living/silicon/robot/mommi/attack_hand(mob/user) add_fingerprint(user) diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 0073729778d..e3a04f2cd0f 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -172,41 +172,6 @@ user << "The machine is hermetically sealed. You can't open the case." return - else if (istype(W, /obj/item/weapon/card/emag)) - - if(!client || stat == 2) - user << "\red There's not much point subverting this heap of junk." - return - - if(emagged) - src << "\red [user] attempts to load subversive software into you, but your hacked subroutined ignore the attempt." - user << "\red You attempt to subvert [src], but the sequencer has no effect." - return - - user << "\red You swipe the sequencer across [src]'s interface and watch its eyes flicker." - src << "\red You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script." - - var/obj/item/weapon/card/emag/emag = W - emag.uses-- - - message_admins("[key_name_admin(user)] emagged drone [key_name_admin(src)]. Laws overridden.") - log_game("[key_name(user)] emagged drone [key_name(src)]. Laws overridden.") - var/time = time2text(world.realtime,"hh:mm:ss") - lawchanges.Add("[time] : [user.name]([user.key]) emagged [name]([key])") - - emagged = 1 - lawupdate = 0 - connected_ai = null - clear_supplied_laws() - clear_inherent_laws() - laws = new /datum/ai_laws/syndicate_override - set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.") - - src << "Obey these laws:" - laws.show_laws(src) - src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands." - return - else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) if(stat == 2) @@ -242,6 +207,41 @@ return ..() + +/mob/living/silicon/robot/drone/emag_act(user as mob) + if(!client || stat == 2) + user << "\red There's not much point subverting this heap of junk." + return + + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + + if(emagged) + src << "\red [user] attempts to load subversive software into you, but your hacked subroutined ignore the attempt." + user << "\red You attempt to subvert [src], but the sequencer has no effect." + return + + user << "\red You swipe the sequencer across [src]'s interface and watch its eyes flicker." + src << "\red You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script." + + message_admins("[key_name_admin(user)] emagged drone [key_name_admin(src)]. Laws overridden.") + log_game("[key_name(user)] emagged drone [key_name(src)]. Laws overridden.") + var/time = time2text(world.realtime,"hh:mm:ss") + lawchanges.Add("[time] : [H.name]([H.key]) emagged [name]([key])") + + emagged = 1 + lawupdate = 0 + connected_ai = null + clear_supplied_laws() + clear_inherent_laws() + laws = new /datum/ai_laws/syndicate_override + set_zeroth_law("Only [H.real_name] and people he designates as being such are Syndicate Agents.") + + src << "Obey these laws:" + laws.show_laws(src) + src << "\red \b ALERT: [H.real_name] is your new master. Obey your new laws and his commands." + return //DRONE LIFE/DEATH diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 1e0a62eedb2..1b8e68dfd79 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -808,72 +808,6 @@ else user << "\red Access denied." - else if(istype(W, /obj/item/weapon/card/emag)) // trying to unlock with an emag card - if(!opened)//Cover is closed - if(locked) - if(prob(90)) - var/obj/item/weapon/card/emag/emag = W - emag.uses-- - user << "You emag the cover lock." - locked = 0 - else - user << "You fail to emag the cover lock." - if(prob(25)) - src << "Hack attempt detected." - else - user << "The cover is already unlocked." - return - - if(opened)//Cover is open - if(emagged) return//Prevents the X has hit Y with Z message also you cant emag them twice - if(wiresexposed) - user << "You must close the panel first" - return - else - sleep(6) - if(prob(50)) - emagged = 1 - if(user.hud_used) - user.hud_used.update_robot_modules_display() //Shows/hides the emag item if the inventory screen is already open. - lawupdate = 0 - connected_ai = null - user << "You emag [src]'s interface." -// message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.") - log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.") - clear_supplied_laws() - clear_inherent_laws() - laws = new /datum/ai_laws/syndicate_override - var/time = time2text(world.realtime,"hh:mm:ss") - lawchanges.Add("[time] : [user.name]([user.key]) emagged [name]([key])") - set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.") - src << "\red ALERT: Foreign software detected." - sleep(5) - src << "\red Initiating diagnostics..." - sleep(20) - src << "\red SynBorg v1.7 loaded." - sleep(5) - src << "\red LAW SYNCHRONISATION ERROR" - sleep(5) - src << "\red Would you like to send a report to NanoTraSoft? Y/N" - sleep(10) - src << "\red > N" - sleep(20) - src << "\red ERRORERRORERROR" - src << "Obey these laws:" - laws.show_laws(src) - src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands." - if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner)) - for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules) - del(D) - src.module.modules += new /obj/item/weapon/pickaxe/diamonddrill(src.module) - src.module.rebuild() - updateicon() - else - user << "You fail to [ locked ? "unlock" : "lock"] [src]'s interface." - if(prob(25)) - src << "Hack attempt detected." - return - else if(istype(W, /obj/item/borg/upgrade/)) var/obj/item/borg/upgrade/U = W if(!opened) @@ -894,6 +828,73 @@ else spark_system.start() return ..() + +/mob/living/silicon/robot/emag_act(user as mob) + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + if(!opened)//Cover is closed + if(locked) + if(prob(90)) + user << "You emag the cover lock." + locked = 0 + else + user << "You fail to emag the cover lock." + if(prob(25)) + src << "Hack attempt detected." + else + user << "The cover is already unlocked." + return + + if(opened)//Cover is open + if(emagged) return//Prevents the X has hit Y with Z message also you cant emag them twice + if(wiresexposed) + user << "You must close the panel first" + return + else + sleep(6) + if(prob(50)) + emagged = 1 + if(H.hud_used) + H.hud_used.update_robot_modules_display() //Shows/hides the emag item if the inventory screen is already open. + lawupdate = 0 + connected_ai = null + user << "You emag [src]'s interface." +// message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.") + log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.") + clear_supplied_laws() + clear_inherent_laws() + laws = new /datum/ai_laws/syndicate_override + var/time = time2text(world.realtime,"hh:mm:ss") + lawchanges.Add("[time] : [H.name]([H.key]) emagged [name]([key])") + set_zeroth_law("Only [H.real_name] and people he designates as being such are Syndicate Agents.") + src << "\red ALERT: Foreign software detected." + sleep(5) + src << "\red Initiating diagnostics..." + sleep(20) + src << "\red SynBorg v1.7 loaded." + sleep(5) + src << "\red LAW SYNCHRONISATION ERROR" + sleep(5) + src << "\red Would you like to send a report to NanoTraSoft? Y/N" + sleep(10) + src << "\red > N" + sleep(20) + src << "\red ERRORERRORERROR" + src << "Obey these laws:" + laws.show_laws(src) + src << "\red \b ALERT: [H.real_name] is your new master. Obey your new laws and his commands." + if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner)) + for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules) + del(D) + src.module.modules += new /obj/item/weapon/pickaxe/diamonddrill(src.module) + src.module.rebuild() + updateicon() + else + user << "You fail to [ locked ? "unlock" : "lock"] [src]'s interface." + if(prob(25)) + src << "Hack attempt detected." + return /mob/living/silicon/robot/verb/unlock_own_cover() set category = "Robot Commands" diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm index 9b638505e28..acf6333afce 100644 --- a/code/modules/mob/living/simple_animal/friendly/corgi.dm +++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm @@ -471,14 +471,12 @@ icon_living = "borgi" var/emagged = 0 -/mob/living/simple_animal/corgi/Ian/borgi/attackby(var/obj/item/O as obj, var/mob/user as mob) - if (istype(O, /obj/item/weapon/card/emag) && !emagged) +/mob/living/simple_animal/corgi/Ian/borgi/emag_act(user as mob) + if (!emagged) emagged = 1 visible_message("[user] swipes a card through [src].", "You overload [src]s internal reactor.") spawn (1000) src.explode() - return - ..() /mob/living/simple_animal/corgi/Ian/borgi/proc/explode() for(var/mob/M in viewers(src, null)) diff --git a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm index aa64a6fe921..73c4018e3b9 100644 --- a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm +++ b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm @@ -125,18 +125,6 @@ else user << "\red You swipe your card, with no effect." return 0 - else if (istype(O, /obj/item/weapon/card/emag)) - if (emagged) - user << "\red [src] is already overloaded - better run." - return 0 - else - var/obj/item/weapon/card/emag/emag = O - emag.uses-- - emagged = 1 - user << "\blue You short out the security protocols and overload [src]'s cell, priming it to explode in a short time." - spawn(100) src << "\red Your cell seems to be outputting a lot of power..." - spawn(200) src << "\red Internal heat sensors are spiking! Something is badly wrong with your cell!" - spawn(300) src.explode() else if(O.force) @@ -152,6 +140,17 @@ for(var/mob/M in viewers(src, null)) if ((M.client && !( M.blinded ))) M.show_message("\red [user] gently taps [src] with the [O]. ") + +/mob/living/simple_animal/spiderbot/emag_act(user as mob) + if (emagged) + user << "\red [src] is already overloaded - better run." + return 0 + else + emagged = 1 + user << "\blue You short out the security protocols and overload [src]'s cell, priming it to explode in a short time." + spawn(100) src << "\red Your cell seems to be outputting a lot of power..." + spawn(200) src << "\red Internal heat sensors are spiking! Something is badly wrong with your cell!" + spawn(300) src.explode() /mob/living/simple_animal/spiderbot/proc/transfer_personality(var/obj/item/device/mmi/M as obj) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 6de3d9cea23..15699572da4 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -458,23 +458,6 @@ update_icon() else user << "\red Access denied." - else if (istype(W, /obj/item/weapon/card/emag) && !(emagged || malfhack)) // trying to unlock with an emag card - if(opened) - user << "You must close the cover to swipe an ID card." - else if(wiresexposed) - user << "You must close the panel first" - else if(stat & (BROKEN|MAINT)) - user << "Nothing happens." - else - flick("apc-spark", src) - if (do_after(user,6)) - if(prob(50)) - emagged = 1 - locked = 0 - user << "You emag the APC interface." - update_icon() - else - user << "You fail to [ locked ? "unlock" : "lock"] the APC interface." else if (istype(W, /obj/item/stack/cable_coil) && !terminal && opened && has_electronics!=2) if (src.loc:intact) user << "\red You must remove the floor plating in front of the APC first." @@ -598,8 +581,26 @@ "\red You hit the [src.name] with your [W.name]!", \ "You hear bang") +/obj/machinery/power/apc/emag_act(user as mob) + if (!(emagged || malfhack)) // trying to unlock with an emag card + if(opened) + user << "You must close the cover to swipe an ID card." + else if(wiresexposed) + user << "You must close the panel first" + else if(stat & (BROKEN|MAINT)) + user << "Nothing happens." + else + flick("apc-spark", src) + if (do_after(user,6)) + if(prob(50)) + emagged = 1 + locked = 0 + user << "You emag the APC interface." + update_icon() + else + user << "You fail to [ locked ? "unlock" : "lock"] the APC interface." + // attack with hand - remove cell (if cover open) or interact with the APC - /obj/machinery/power/apc/attack_hand(mob/user) // if (!can_use(user)) This already gets called in interact() and in topic() // return diff --git a/code/modules/power/pacman2.dm b/code/modules/power/pacman2.dm index 89d65a6ae21..9402a4c234f 100644 --- a/code/modules/power/pacman2.dm +++ b/code/modules/power/pacman2.dm @@ -81,14 +81,6 @@ user.drop_item() O.loc = src user << "\blue You add the plasma tank to the generator." - else if (istype(O, /obj/item/weapon/card/emag)) - var/obj/item/weapon/card/emag/E = O - if(E.uses) - E.uses-- - else - return - emagged = 1 - emp_act(1) else if(!active) if(istype(O, /obj/item/weapon/wrench)) anchored = !anchored @@ -114,6 +106,11 @@ new_frame.state = 2 new_frame.icon_state = "box_1" del(src) + + emag_act(user as mob) + if(!emagged) + emagged = 1 + emp_act(1) attack_hand(mob/user as mob) ..() diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index a334782cce1..d918ec86711 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -211,9 +211,6 @@ display round(lastgen) and plasmatank amount addstack.use(amount) updateUsrDialog() return - else if (istype(O, /obj/item/weapon/card/emag)) - emagged = 1 - emp_act(1) else if(!active) if(istype(O, /obj/item/weapon/wrench)) if(!anchored && !isinspace()) @@ -239,6 +236,10 @@ display round(lastgen) and plasmatank amount else if(istype(O, /obj/item/weapon/crowbar) && panel_open) default_deconstruction_crowbar(O) +/obj/machinery/power/port_gen/pacman/emag_act(user as mob) + emagged = 1 + emp_act(1) + /obj/machinery/power/port_gen/pacman/attack_hand(mob/user as mob) ..() if (!anchored) diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 601d7191f7b..8e9e16c9943 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -222,12 +222,14 @@ user << "\red Access denied." return - - if(istype(W, /obj/item/weapon/card/emag) && !emagged) + ..() + return + +/obj/machinery/power/emitter/emag_act(user as mob) + if(!emagged) + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user locked = 0 emagged = 1 - user.visible_message("[user.name] emags the [src.name].","\red You short out the lock.") - return - - ..() - return \ No newline at end of file + H.visible_message("[H.name] emags the [src.name].","\red You short out the lock.") diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 90e7ff47ace..a0a29917995 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -165,16 +165,17 @@ won't update every console in existence) but it's more of a hassle to do. Also, user.drop_item() D.loc = src user << " You add the disk to the machine!" - else if(istype(D,/obj/item/weapon/card/emag)) - if(!emagged) - playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) - emagged = 1 - user << "You you disable the security protocols" else ..() src.updateUsrDialog() return +/obj/machinery/computer/rdconsole/emag_act(user as mob) + if(!emagged) + playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) + emagged = 1 + user << "You you disable the security protocols" + /obj/machinery/computer/rdconsole/Topic(href, href_list) if(..()) return diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index 109ab110d71..f6e00bc69b4 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -319,14 +319,12 @@ onclose(user, "server_control") return -/obj/machinery/computer/rdservercontrol/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob) - if(istype(D, /obj/item/weapon/card/emag) && !emagged) +/obj/machinery/computer/rdservercontrol/emag_act(user as mob) + if(!emagged) playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) emagged = 1 user << "\blue You you disable the security protocols" src.updateUsrDialog() - return ..() - /obj/machinery/r_n_d/server/robotics name = "Robotics R&D Server" diff --git a/code/modules/shuttles/escape_pods.dm b/code/modules/shuttles/escape_pods.dm index 0261997a9d3..17a97b79fe7 100644 --- a/code/modules/shuttles/escape_pods.dm +++ b/code/modules/shuttles/escape_pods.dm @@ -89,19 +89,14 @@ ui.open() ui.set_auto_update(1) -/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/card/emag) && !emagged) +/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/emag_act(user as mob) + if (!emagged) user << "\blue You emag the [src], arming the escape pod!" emagged = 1 if (istype(docking_program, /datum/computer/file/embedded_program/docking/simple/escape_pod)) var/datum/computer/file/embedded_program/docking/simple/escape_pod/P = docking_program if (!P.armed) P.arm() - return - - ..() - - //A docking controller program for a simple door based docking port /datum/computer/file/embedded_program/docking/simple/escape_pod diff --git a/code/modules/shuttles/shuttle_console.dm b/code/modules/shuttles/shuttle_console.dm index f1ca624e73b..e6e7a8d4112 100644 --- a/code/modules/shuttles/shuttle_console.dm +++ b/code/modules/shuttles/shuttle_console.dm @@ -97,15 +97,11 @@ return shuttle.cancel_launch(user) -/obj/machinery/computer/shuttle_control/attackby(obj/item/weapon/W as obj, mob/user as mob) - - if (istype(W, /obj/item/weapon/card/emag)) - src.req_access = list() - src.req_one_access = list() - hacked = 1 - usr << "You short out the console's ID checking system. It's now available to everyone!" - else - ..() +/obj/machinery/computer/shuttle_control/emag_act(user as mob) + src.req_access = list() + src.req_one_access = list() + hacked = 1 + usr << "You short out the console's ID checking system. It's now available to everyone!" /obj/machinery/computer/shuttle_control/bullet_act(var/obj/item/projectile/Proj) visible_message("[Proj] ricochets off [src]!") diff --git a/code/modules/shuttles/shuttle_emergency.dm b/code/modules/shuttles/shuttle_emergency.dm index b5268fd2ca5..29baa07c1b0 100644 --- a/code/modules/shuttles/shuttle_emergency.dm +++ b/code/modules/shuttles/shuttle_emergency.dm @@ -153,14 +153,15 @@ /obj/machinery/computer/shuttle_control/emergency/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/card/emag) && !emagged) + read_authorization(W) + ..() + +/obj/machinery/computer/shuttle_control/emergency/emag_act(user as mob) + if (!emagged) user << "\blue You short out the [src]'s authorization protocols." emagged = 1 return - read_authorization(W) - ..() - /obj/machinery/computer/shuttle_control/emergency/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) var/data[0] var/datum/shuttle/ferry/emergency/shuttle = shuttle_controller.shuttles[shuttle_tag] diff --git a/code/modules/telesci/telepad.dm b/code/modules/telesci/telepad.dm index 21283526863..42ee7f3786f 100644 --- a/code/modules/telesci/telepad.dm +++ b/code/modules/telesci/telepad.dm @@ -147,11 +147,12 @@ playsound(src.loc, 'sound/effects/pop.ogg', 50, 0) user << " You calibrate the telepad locator." -/obj/item/weapon/rcs/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/weapon/card/emag) && emagged == 0) +/obj/item/weapon/rcs/emag_act(user as mob) + if(!emagged) emagged = 1 var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(5, 1, src) s.start() user << " You emag the RCS. Click on it to toggle between modes." - return \ No newline at end of file + return + \ No newline at end of file diff --git a/code/modules/telesci/telesci_computer.dm b/code/modules/telesci/telesci_computer.dm index f37ec393860..e4b7986ab1a 100644 --- a/code/modules/telesci/telesci_computer.dm +++ b/code/modules/telesci/telesci_computer.dm @@ -55,12 +55,6 @@ return /obj/machinery/computer/telescience/attackby(obj/item/W, mob/user) - if(istype(W,/obj/item/weapon/card/emag)) - if (emagged == 0) - user << "\blue You scramble the Telescience authentication key to an unknown signal. You should be able to teleport to more places now!" - emagged = 1 - else - user << "\red The machine seems unaffected by the card swipe..." if(istype(W, /obj/item/bluespace_crystal)) if(crystals.len >= max_crystals) user << "There are not enough crystal slots." @@ -86,6 +80,13 @@ updateUsrDialog() else ..() + +/obj/machinery/computer/telescience/emag_act(user as mob) + if (!emagged) + user << "\blue You scramble the Telescience authentication key to an unknown signal. You should be able to teleport to more places now!" + emagged = 1 + else + user << "\red The machine seems unaffected by the card swipe..." /obj/machinery/computer/telescience/attack_ai(mob/user) src.attack_hand(user) diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm index a929e4499d9..4c62455bf07 100644 --- a/code/modules/vehicles/vehicle.dm +++ b/code/modules/vehicles/vehicle.dm @@ -87,8 +87,6 @@ user << "[src] does not need a repair." else user << "Unable to repair while [src] is off." - else if(istype(W, /obj/item/weapon/card/emag) && !emagged) - Emag(user) else if(hasvar(W,"force") && hasvar(W,"damtype")) switch(W.damtype) if("fire") @@ -99,6 +97,10 @@ healthcheck() else ..() + +/obj/vehicle/emag_act(user as mob) + if(!emagged) + Emag(user) /obj/vehicle/attack_animal(var/mob/living/simple_animal/M as mob) if(M.melee_damage_upper == 0) return From c8acddaad33530d745f34e90093f34c236dc642e Mon Sep 17 00:00:00 2001 From: Markolie Date: Fri, 13 Feb 2015 17:12:21 +0100 Subject: [PATCH 05/13] Windowdoor emag fix --- code/game/machinery/doors/windowdoor.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index cbb39a73aa7..429bc886068 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -254,7 +254,7 @@ add_fingerprint(user) //Ninja swords? You may pass. - if (density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade))) + if (src.density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade))) emag_act(user,I) return 1 From f180812abb5a551d4cd7ef7f0bfaeb864990b415 Mon Sep 17 00:00:00 2001 From: Markolie Date: Fri, 13 Feb 2015 17:14:20 +0100 Subject: [PATCH 06/13] Ensure interface updates on emag --- code/game/machinery/computer/HolodeckControl.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm index d8a1d7f941f..886f01010db 100644 --- a/code/game/machinery/computer/HolodeckControl.dm +++ b/code/game/machinery/computer/HolodeckControl.dm @@ -171,6 +171,7 @@ user << "\blue You vastly increase projector power and override the safety and security protocols." user << "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator." log_game("[key_name(usr)] emagged the Holodeck Control Computer") + src.updateUsrDialog() /obj/machinery/computer/HolodeckControl/New() ..() From 61e9fe3b28eed0e9e282111b766d265ab14f6807 Mon Sep 17 00:00:00 2001 From: Markolie Date: Fri, 13 Feb 2015 20:46:19 +0100 Subject: [PATCH 07/13] Admin fax overhaul --- code/modules/admin/admin_verbs.dm | 3 +- code/modules/admin/topic.dm | 162 ++++++++++++++++++++++----- code/modules/admin/verbs/pray.dm | 2 +- code/modules/paperwork/fax.dm | 85 ++++++++++++++ code/modules/paperwork/faxmachine.dm | 59 +++++++--- nano/templates/faxmachine.tmpl | 4 +- paradise.dme | 1 + 7 files changed, 266 insertions(+), 50 deletions(-) create mode 100644 code/modules/paperwork/fax.dm diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 727dfc58c61..6e2f9b1d4b4 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -65,7 +65,8 @@ var/list/admin_verbs_admin = list( /client/proc/global_man_up, /client/proc/delbook, /client/proc/event_manager_panel, - /client/proc/empty_ai_core_toggle_latejoin + /client/proc/empty_ai_core_toggle_latejoin, + /client/proc/fax_panel ) var/list/admin_verbs_ban = list( /client/proc/unban_panel, diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 04def53cc9f..0cb98be5ff9 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1561,11 +1561,11 @@ usr << "This can only be used on instances of type /mob/living" return - if(alert(src.owner, "Are you sure you wish to hit [key_name(M)] with Blue Space Artillery?", "Confirm Firing?" , "Yes" , "No") != "Yes") + if(alert(src.owner, "Are you sure you wish to hit [key_name(M)] with Bluespace Artillery?", "Confirm Firing?" , "Yes" , "No") != "Yes") return if(BSACooldown) - src.owner << "Standby! Reload cycle in progress! Gunnary crews ready in five seconds!" + src.owner << "Standby. Reload cycle in progress. Gunnery crews ready in five seconds!" return BSACooldown = 1 @@ -1597,6 +1597,9 @@ M.stuttering = 20 else if(href_list["CentcommReply"]) + if(!check_rights(R_ADMIN)) + return + var/mob/living/carbon/human/H = locate(href_list["CentcommReply"]) if(!istype(H)) usr << "This can only be used on instances of type /mob/living/carbon/human" @@ -1614,10 +1617,16 @@ H << "You hear something crackle in your headset for a moment before a voice speaks. \"Please stand by for a message from Central Command. Message as follows. [input]. Message ends.\"" else if(href_list["SyndicateReply"]) + if(!check_rights(R_ADMIN)) + return + var/mob/living/carbon/human/H = locate(href_list["SyndicateReply"]) if(!istype(H)) usr << "This can only be used on instances of type /mob/living/carbon/human" return + if(H.stat != 0) + usr << "The person you are trying to contact is not conscious." + return if(!istype(H.l_ear, /obj/item/device/radio/headset) && !istype(H.r_ear, /obj/item/device/radio/headset)) usr << "The person you are trying to contact is not wearing a headset" return @@ -1646,6 +1655,9 @@ H << "You hear something crackle in your headset for a moment before a voice speaks. \"Please stand by for a message from your HONKbrothers. Message as follows, HONK. [input]. Message ends, HONK.\"" else if(href_list["AdminFaxView"]) + if(!check_rights(R_ADMIN)) + return + var/obj/item/fax = locate(href_list["AdminFaxView"]) if (istype(fax, /obj/item/weapon/paper)) var/obj/item/weapon/paper/P = fax @@ -1668,6 +1680,9 @@ usr << "\red The faxed item is not viewable. This is probably a bug, and should be reported on the tracker: [fax.type]" else if (href_list["AdminFaxViewPage"]) + if(!check_rights(R_ADMIN)) + return + var/page = text2num(href_list["AdminFaxViewPage"]) var/obj/item/weapon/paper_bundle/bundle = locate(href_list["paper_bundle"]) @@ -1681,50 +1696,135 @@ H.show(src.owner) return - else if(href_list["CentcommFaxReply"]) - var/mob/sender = locate(href_list["CentcommFaxReply"]) + else if(href_list["AdminFaxCreate"]) + if(!check_rights(R_ADMIN)) + return + + var/mob/sender = locate(href_list["AdminFaxCreate"]) var/obj/machinery/photocopier/faxmachine/fax = locate(href_list["originfax"]) + var/faxtype = href_list["faxtype"] + var/reply_to = locate(href_list["replyto"]) + var/destination + var/notify - var/input = input(src.owner, "Please enter a message to reply to [key_name(sender)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use
for line breaks.", "Outgoing message from Centcomm", "") as message|null - if(!input) return + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(null) //hopefully the null loc won't cause trouble for us + + if(!fax) + var/list/departmentoptions = alldepartments + "All Departments" + destination = input(usr, "To which department?", "Choose a department", "") as null|anything in departmentoptions + if(!destination) + del(P) + return - var/customname = input(src.owner, "Pick a title for the report", "Title") as text|null + for(var/obj/machinery/photocopier/faxmachine/F in allfaxes) + if(destination != "All Departments" && F.department == destination) + fax = F + + var/input = input(src.owner, "Please enter a message to send a fax via secure connection. Use
for line breaks. Both pencode and HTML work.", "Outgoing message from Centcomm", "") as message|null + if(!input) + del(P) + return + input = P.parsepencode(input) // Encode everything from pencode to html + + var/customname = input(src.owner, "Pick a title for the fax.", "Fax Title") as text|null + + var/stamptype + var/stampvalue + var/sendername + switch(faxtype) + if("Central Command") + stamptype = "icon" + stampvalue = "cent" + sendername = command_name() + if("Syndicate") + sendername = "UNKNOWN" + if("Administrator") + stamptype = input(src.owner, "Pick a stamp type.", "Stamp Type") as null|anything in list("icon","text","none") + if(stamptype == "icon") + stampvalue = input(src.owner, "Pick a stamp icon.", "Stamp Icon") as null|anything in list("cent","ok","deny","clown") + else if(stamptype == "text") + stampvalue = input(src.owner, "What should the stamp say?.", "Stamp Text") as text|null + else + stamptype = "" + sendername = input(src.owner, "What organization does the fax come from? This determines the prefix of the paper (i.e. CentCom- Title).", "Stamp Organization") as text|null + + if(sender) + notify = alert(src.owner, "Would you like to inform the original sender that a fax has arrived?","Notify Sender","Yes","No") // Create the reply message - var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( null ) //hopefully the null loc won't cause trouble for us - P.name = "[command_name()]- [customname]" + + P.name = "[sendername]- [customname]" P.info = input P.update_icon() - P.stamps += "
" - var/image/stampoverlay = image('icons/obj/bureaucracy.dmi') P.x = rand(-2, 0) P.y = rand(-1, 2) P.offset_x += P.x P.offset_y += P.y - stampoverlay.pixel_x = P.x - stampoverlay.pixel_y = P.y + + if(stamptype) + var/image/stampoverlay = image('icons/obj/bureaucracy.dmi') + stampoverlay.pixel_x = P.x + stampoverlay.pixel_y = P.y - if(!P.ico) - P.ico = new - P.ico += "paper_stamp-cent" - stampoverlay.icon_state = "paper_stamp-cent" - - // Stamps - if(!P.stamped) - P.stamped = new - P.stamped += /obj/item/weapon/stamp/centcom - P.overlays += stampoverlay + if(!P.ico) + P.ico = new + P.ico += "paper_stamp-cent" + stampoverlay.icon_state = "paper_stamp-cent" - if(fax.recievefax(P)) - src.owner << "\blue Message reply to transmitted successfully." - log_admin("[key_name(src.owner)] replied to a fax message from [key_name(sender)]: [input]") - message_admins("[key_name_admin(src.owner)] replied to a fax message from [key_name_admin(sender)]", 1) + if(stamptype == "icon") + if(!P.stamped) + P.stamped = new + P.stamped += /obj/item/weapon/stamp/centcom + P.overlays += stampoverlay + P.stamps += "
" + + else if(stamptype == "text") + if(!P.stamped) + P.stamped = new + P.stamped += /obj/item/weapon/stamp + P.overlays += stampoverlay + P.stamps += "
[stampvalue]" + + if(destination != "All Departments") + if(!fax.receivefax(P)) + src.owner << "\red Message transmittion failed." + return else - src.owner << "\red Message reply failed." - - spawn(100) - del(P) + for(var/obj/machinery/photocopier/faxmachine/F in allfaxes) + if(F.z == 1) + if(!F.receivefax(P)) + src.owner << "\red Message transmission to [F.department] failed." + + var/datum/fax/admin/A = new /datum/fax/admin() + A.name = P.name + A.from_department = faxtype + if(destination != "All Departments") + A.to_department = fax.department + else + A.to_department = "All Departments" + A.origin = "Administrator" + A.message = P + A.reply_to = reply_to + A.sent_by = usr + + src.owner << "\blue Message transmitted successfully." + if(notify == "Yes") + var/mob/living/carbon/human/H = sender + if(istype(H) && H.stat == 1 && (istype(H.l_ear, /obj/item/device/radio/headset) || istype(H.r_ear, /obj/item/device/radio/headset))) + sender << "Your headset pings, notifying you that a reply to your fax has arrived." + if(sender) + log_admin("[key_name(src.owner)] replied to a fax message from [key_name(sender)]: [input]") + message_admins("[key_name_admin(src.owner)] replied to a fax message from [key_name_admin(sender)] (VIEW).", 1) + else + log_admin("[key_name(src.owner)] sent a fax message to [destination]: [input]") + message_admins("[key_name_admin(src.owner)] sent a fax message to [destination] (VIEW).", 1) return + + else if(href_list["refreshfaxpanel"]) + if(!check_rights(R_ADMIN)) + return + + fax_panel(usr) else if(href_list["jumpto"]) if(!check_rights(R_ADMIN)) return diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index 0494cfab89d..caab5c8b258 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -62,7 +62,7 @@ /proc/Syndicate_announce(var/text , var/mob/Sender) var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN) - msg = "\blue SYNDICATE:[key_name(Sender, 1)] (PP) (VV) (SM) (JMP) (CA) (BSA) (RPLY): [msg]" + msg = "\blue SYNDICATE: [key_name(Sender, 1)] (PP) (VV) (SM) (JMP) (CA) (BSA) (REPLY): [msg]" var/list/eventholders = list() var/list/banholders = list() diff --git a/code/modules/paperwork/fax.dm b/code/modules/paperwork/fax.dm new file mode 100644 index 00000000000..6969db88604 --- /dev/null +++ b/code/modules/paperwork/fax.dm @@ -0,0 +1,85 @@ +// Fax datum - holds all faxes sent during the round +var/list/faxes = list() +var/list/adminfaxes = list() + +/datum/fax + var/name = "fax" + var/from_department = null + var/to_department = null + var/origin = null + var/message = null + var/sent_by = null + +/datum/fax/New() + faxes += src + +/datum/fax/admin + var/list/reply_to = null + +/datum/fax/admin/New() + adminfaxes += src + +// Fax panel - lets admins check all faxes sent during the round +/client/proc/fax_panel() + set name = "Fax Panel" + set category = "Admin" + if(holder) + holder.fax_panel(usr) + feedback_add_details("admin_verb","FXP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + return + +/datum/admins/proc/fax_panel(var/mob/living/user) + var/html = "Refresh" + html += "Create Fax" + + html += "
" + html += "

Admin Faxes

" + html += "" + html += "" + for(var/datum/fax/admin/A in adminfaxes) + html += "" + html += "" + html += "" + html += "" + if(A.sent_by) + var/mob/living/S = A.sent_by + html += "" + else + html += "" + html += "" + if(!A.reply_to) + if(A.from_department == "Administrator") + html += "" + else + html += "" + html += "" + else + html += "" + html += "" + html += "" + html += "
NameFrom DepartmentTo DepartmentSent ByViewReplyOriginal
[A.name][A.from_department][A.to_department][S.name]UnknownViewN/AReplyN/AN/AOriginal
" + html += "
" + + html += "
" + html += "

Departmental Faxes

" + html += "" + html += "" + for(var/datum/fax/F in faxes) + html += "" + html += "" + html += "" + html += "" + if(F.sent_by) + var/mob/living/S = F.sent_by + html += "" + else + html += "" + html += "" + html += "" + html += "
NameFrom DepartmentTo DepartmentSent ByView
[F.name][F.from_department][F.to_department][S.name]UnknownView
" + html += "
" + + var/datum/browser/popup = new(user, "fax_panel", "Fax Panel", 900, 450) + popup.set_content(html) + popup.open() + \ No newline at end of file diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index 7638cc2ea93..6c7b0e30314 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -1,9 +1,8 @@ var/list/obj/machinery/photocopier/faxmachine/allfaxes = list() var/list/admin_departments = list("Central Command") +var/list/hidden_admin_departments = list("Syndicate") var/list/alldepartments = list() -var/list/adminfaxes = list() //cache for faxes that have been sent to admins - /obj/machinery/photocopier/faxmachine name = "fax machine" icon = 'icons/obj/library.dmi' @@ -43,6 +42,13 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins nanomanager.update_uis(src) else return ..() + +/obj/machinery/photocopier/faxmachine/emag_act(user as mob) + if(!emagged) + emagged = 1 + user << "The transmitters realign to an unknown source!" + else + user << "You swipe the card through [src], but nothing happens." /obj/machinery/photocopier/faxmachine/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) if(scan) @@ -55,7 +61,7 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins else if(!emagged) data["network"] = "Central Command Quantum Entanglement Network" else - data["network"] = "ERR?*!!*" + data["network"] = "ERR*?*%!*" if(copyitem) data["paper"] = copyitem.name data["paperinserted"] = 1 @@ -64,6 +70,10 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins data["paperinserted"] = 0 data["destination"] = destination data["cooldown"] = sendcooldown + if((destination in admin_departments) || (destination in hidden_admin_departments)) + data["respectcooldown"] = 1 + else + data["respectcooldown"] = 0 ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) @@ -77,10 +87,10 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins if(href_list["send"]) if(copyitem && authenticated) - if (destination in admin_departments) + if ((destination in admin_departments) || (destination in hidden_admin_departments)) send_admin_fax(usr, destination) else - sendfax(destination) + sendfax(destination,usr) if (sendcooldown) spawn(sendcooldown) // cooldown time @@ -108,7 +118,10 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins if(href_list["dept"]) if(authenticated) var/lastdestination = destination - destination = input(usr, "Which department?", "Choose a department", "") as null|anything in (alldepartments + admin_departments) + var/list/combineddepartments = alldepartments + admin_departments + if(emagged) + combineddepartments += hidden_admin_departments + destination = input(usr, "To which department?", "Choose a department", "") as null|anything in combineddepartments if(!destination) destination = lastdestination @@ -135,7 +148,7 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins nanomanager.update_uis(src) /obj/machinery/photocopier/faxmachine/proc/scan(var/obj/item/weapon/card/id/card = null) - if (scan) // Card is in machine + if(scan) // Card is in machine if(ishuman(usr)) scan.loc = usr.loc if(!usr.get_active_hand()) @@ -158,7 +171,7 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins scan = card nanomanager.update_uis(src) -/obj/machinery/photocopier/faxmachine/proc/sendfax(var/destination) +/obj/machinery/photocopier/faxmachine/proc/sendfax(var/destination,var/mob/sender) if(stat & (BROKEN|NOPOWER)) return @@ -167,15 +180,23 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins var/success = 0 for(var/obj/machinery/photocopier/faxmachine/F in allfaxes) if( F.department == destination ) - success = F.recievefax(copyitem) + success = F.receivefax(copyitem) if (success) + var/datum/fax/F = new /datum/fax() + F.name = copyitem.name + F.from_department = department + F.to_department = destination + F.origin = src + F.message = copyitem + F.sent_by = sender + visible_message("[src] beeps, \"Message transmitted successfully.\"") //sendcooldown = 600 else visible_message("[src] beeps, \"Error transmitting message.\"") -/obj/machinery/photocopier/faxmachine/proc/recievefax(var/obj/item/incoming) +/obj/machinery/photocopier/faxmachine/proc/receivefax(var/obj/item/incoming) if(stat & (BROKEN|NOPOWER)) return 0 @@ -218,20 +239,28 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins return rcvdcopy.loc = null //hopefully this shouldn't cause trouble - adminfaxes += rcvdcopy + + var/datum/fax/admin/A = new /datum/fax/admin() + A.name = rcvdcopy.name + A.from_department = department + A.to_department = destination + A.origin = src + A.message = rcvdcopy + A.sent_by = sender //message badmins that a fax has arrived switch(destination) if ("Central Command") - message_admins(sender, "CENTCOMM FAX", rcvdcopy, "CentcommFaxReply", "#006100") - + message_admins(sender, "CENTCOM FAX", destination, rcvdcopy, "#006100") + if ("Syndicate") + message_admins(sender, "SYNDICATE FAX", destination, rcvdcopy, "#DC143C") sendcooldown = 1800 sleep(50) visible_message("[src] beeps, \"Message transmitted successfully.\"") -/obj/machinery/photocopier/faxmachine/proc/message_admins(var/mob/sender, var/faxname, var/obj/item/sent, var/reply_type, font_colour="#006100") - var/msg = "\blue [faxname]: [key_name(sender, 1)] (PP) (VV) (SM) (JMP) (CA) (REPLY): Receiving '[sent.name]' via secure connection ... view message" +/obj/machinery/photocopier/faxmachine/proc/message_admins(var/mob/sender, var/faxname, var/faxtype, var/obj/item/sent, font_colour="#006100") + var/msg = "\blue [faxname]: [key_name(sender, 1)] (PP) (VV) (SM) (JMP) (CA) (BSA) (REPLY): Receiving '[sent.name]' via secure connection... view message" for(var/client/C in admins) if(R_ADMIN & C.holder.rights) diff --git a/nano/templates/faxmachine.tmpl b/nano/templates/faxmachine.tmpl index 1e00c559b28..9dd7b910fda 100644 --- a/nano/templates/faxmachine.tmpl +++ b/nano/templates/faxmachine.tmpl @@ -59,9 +59,9 @@ Used In File(s): \code\modules\paperwork\faxmachine.dm
{{if data.authenticated}} - {{:helper.link(data.cooldown ? "Realigning" : "Send", data.cooldown ? 'clock' : "mail-closed", {'send' : 1}, data.cooldown ? 'disabled' : "")}} + {{:helper.link(data.cooldown && data.respectcooldown ? "Realigning" : "Send", data.cooldown && data.respectcooldown ? 'clock' : "mail-closed", {'send' : 1}, data.cooldown && data.respectcooldown ? 'disabled' : "")}} {{else}} - {{:helper.link(data.cooldown ? "Realigning" : "Send", data.cooldown ? 'clock' : "mail-closed", null, !data.authenticated ? 'disabled' : "")}} + {{:helper.link(data.cooldown && data.respectcooldown ? "Realigning" : "Send", data.cooldown && data.respectcooldown ? 'clock' : "mail-closed", null, !data.authenticated ? 'disabled' : "")}} {{/if}}
\ No newline at end of file diff --git a/paradise.dme b/paradise.dme index 9339ab8b631..8b128080271 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1390,6 +1390,7 @@ #include "code\modules\organs\wound.dm" #include "code\modules\paperwork\carbonpaper.dm" #include "code\modules\paperwork\clipboard.dm" +#include "code\modules\paperwork\fax.dm" #include "code\modules\paperwork\faxmachine.dm" #include "code\modules\paperwork\filingcabinet.dm" #include "code\modules\paperwork\folders.dm" From 5fdabeda13048dcc3b1eebbc2786aba2ef6ff267 Mon Sep 17 00:00:00 2001 From: Markolie Date: Fri, 13 Feb 2015 23:28:09 +0100 Subject: [PATCH 08/13] Minor R&D search function fix --- code/modules/research/rdconsole.dm | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index a0a29917995..7aca9b588bf 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -174,7 +174,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, if(!emagged) playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) emagged = 1 - user << "You you disable the security protocols" + user << "You disable the security protocols" /obj/machinery/computer/rdconsole/Topic(href, href_list) if(..()) @@ -208,7 +208,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, t_disk = null screen = 1.0 - else if(href_list["copy_tech"]) //Copys some technology data from the research holder to the disk. + else if(href_list["copy_tech"]) //Copy some technology data from the research holder to the disk. for(var/datum/tech/T in files.known_tech) if(href_list["copy_tech_ID"] == T.id) t_disk.stored = T @@ -372,6 +372,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, if(being_built) var/power = 2000 var/amount=text2num(href_list["amount"]) + var/old_screen = screen amount = max(1, min(10, amount)) for(var/M in being_built.materials) power += round(being_built.materials[M] * amount / 5) @@ -437,7 +438,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, else new_item.loc = linked_lathe.loc linked_lathe.busy = 0 - screen = 3.15 + screen = old_screen updateUsrDialog() else if(href_list["imprint"]) //Causes the Circuit Imprinter to build something. @@ -451,6 +452,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, break if(being_built) var/power = 2000 + var/old_screen = screen for(var/M in being_built.materials) power += round(being_built.materials[M] / 5) power = max(2000, power) @@ -489,7 +491,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, new_item.reliability = R new_item.loc = linked_imprinter.loc linked_imprinter.busy = 0 - screen = 4.1 + screen = old_screen updateUsrDialog() else if(href_list["disposeI"] && linked_imprinter) //Causes the circuit imprinter to dispose of a single reagent (all of it) From 9dd99ba2400b945f4194f1c2239c6dfb05cedb89 Mon Sep 17 00:00:00 2001 From: Markolie Date: Sat, 14 Feb 2015 00:18:41 +0100 Subject: [PATCH 09/13] Stop AI's from detaching IV drips, Ultimate Chimera's alien AI fix --- code/game/machinery/iv_drip.dm | 4 ++++ icons/mob/custom-synthetic.dmi | Bin 112192 -> 112521 bytes 2 files changed, 4 insertions(+) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index 17127b65378..3522fbf9e95 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -37,6 +37,9 @@ /obj/machinery/iv_drip/MouseDrop(over_object, src_location, over_location) ..() + + if(!ishuman(usr)) + return if(attached) visible_message("[src.attached] is detached from \the [src]") @@ -133,6 +136,7 @@ /obj/machinery/iv_drip/verb/toggle_mode() set name = "Toggle Mode" + set category = "Object" set src in view(1) if(!istype(usr, /mob/living)) diff --git a/icons/mob/custom-synthetic.dmi b/icons/mob/custom-synthetic.dmi index 77cef2656fb0bf4c6beffd7b4de666f25ce35c96..1c61475e89e3a260db8f3968d2f4974a1fcf5c70 100644 GIT binary patch delta 24155 zcmagG2UJsC*DVa9pdiHtNLN8rnxOO&6cv%G^p1ic9i-O-(nUn2H)Eqq?={k;N$(w` z3!w!Fgq*vB`n=Eg-tYeZ7{QzolasUeUVE*%=A0+revyWtN#C$TcJ69gj(46q7(X|+ zb2PWLAtG{3tcsBjAHGi0)X|)p>l`kgKF$7h@{K%2Mq0hW?$OI}r#0Q!M&#>D&>su= zYr|>C^J&PZ;e@>Tx9eQk^1W(2TWhLKs1$Y{!Bd8zo z2e5PUeHw9E;yC$$7h-Rgqa{Tgvs8JP*g0j$VOAj)eU7U_YWP}zv_hn*`e{;*{$F>V zzpKAa;g_Mh(RuY<#K~tz)L@Pf-ydvw^g2Zz;}^-tSFKsbZ^1P>*<$NN8>I3ExqGKf z#y>U8?ElbrtU4XsMH{MI)7NZeEHxNg(@<`vs(V(}VDeH4Cd(3XZhJQeTdT%2UhL|N zKI_`X|GvHDrEyl@<-U_m)(i1$$&zMPR= zySw%7kvY-K%hXe9`Qk0A>8p2Q6`X#ysHJcwr5Nj<7miv|XvtFvgIs#_OnSp&U$%+C z3SSoKg;9(P`+co7#oVK5GzuD~d$q)@cBhYNo-5f)Q^ehfjdSE>eP;3e39X^~nWp}V z@0)0Za#><*Ho0=?$24+;WdmbMZkns#iy?>2YhI5&yh)OYPDIq5!D!i=%I!YTV3p4w z{aQECBf8R}F;~z+MCAARNXh3T#Fm=G=`qwg#22AcStXdnmQ$2EU2HUwbo@Sj7tSB| zZDWr!Ic@q~0#ev+dEd+)$9}`(_VWWN*4QDB?Ozi`{Vtr^9yvwXeQn$0#_sO!-&^)qSAWz3P_vne`tEHgCXWiRg%gWFT#6igPSjG8C ztHNLuv>S>#e88ofhWLfgXFbs#+}e3B_V(PlX(^zCWkXSyRi>U4MPuQ0N#kig{7f^P z!3xtaSM8X#L+g7O1$`90G7~cTW@5hSBn)FRHBN0~b4QH*dUbVm;{=|*)Zwhm&VF6y zFi$l}lam-9A0J6|HbmfKMn=Yh&<9uO4der#*62qofkB_dDLIYHN#5vwZh0 zpA38V&n(`@3>t^ee&J#voG#?fCpD87c;gY(uEn1A1zp}tD=+Av_1}+3tV0w?q*oU(1(zI5lxwVmetI|)cicq(J*{p>^9nu|u%d9a0ddEJ}wt&G&@9mXOJ zhfx0U7Kl2pmho5ClZ7mZhw8I24gNSZWm{VE^44yX+%6J{o0;?Jh~+o_MiR~}p28r_ z%*YY0KF}B{LM-VkG^FI+WTI(gQ8B^YJO; zKnxKcP%qx^!M-0V4IR$6RXxBU8~5l*9jCV5`A6OFV+^oD)|a-zCQN_mrFKT38cNI= zs})D45uFT=_M7~J2f4Px^}nn~v~c~pk&%&hli!G6 zhK4RKEghL`GSt0?owkIo7zkYkHV3LB+E8GaFEtI5r~5Q#7&PNi{XK78dDrRS%`TW48oc?j6>J>aNa&jTUOZ3f zTy~?Ni=evjc)KB0VI%%Hb+5G8M6#{tVvAPEW7dJuN~+d(MNpvsW9|HCOB(}O)t%nz zd$F_~MwGob<#(IdaRG;;flP1_*(Bq=y+=#N?y0Jtv9`A69xn{x@}*c_Dy7%jY_)w< zy~{u}?94O?`~M)$HEBM58G&V|JCf=&Z@D6=nPFjJQJdY+wXdV05!f-W+N4&wcP&UG zJGcs(RUe1+&Q^$lK)G`5+Nb2?V?_HYih9R;K~6$8;e|)-4*You>FFWfFQeqt^8=2R z-oC!P>y;5+b6i)b(E&ytrXJGy>Hbr%eJqHq$1CGD)(l?Uyi4sIZDMuYs39`t*|ULr zR0({ax%HGqa;{W&MNJv7NrPyW-t{A_6jTV|BDQ@>ii+%iem?~+gJ`hI>b$L*#ztGE z+gI$Yu)R~{k?Yn&3`E|!-jX!S)*>!V%!#DqXnN|NFt@QuDJZzHC`t%2gcB@0;c0n0#t_H(9)dEi zfq`&LeC44=AN%&aX`pBIRBF8&)NF8LC5g@9y0mubdmM*lv&js_q>-7N68>FLWWaI+ ztC11)@#7E;VH*%O-=!I3H`7{Wr9^x}LSJt6`xXJhf=m`esdiWiDtN)rr~2Lx*4CEm z3GH$nQ7_3UD9o!?glJI^MgswZk13J(O8YcNaNYo$M`?%U^8v-tBQ1uI5+PZ!zK3UH z_!2s2>EMug#20t?`+nBbM3JrTN2sD#1wR=!waF_pSwW}I!rtX3yt@4)p3!}&Lc?PL@oZZ1`H zk+G)~Yv_c#JY^6e!NPB`1HD@ZII}v$2;st~kng~Scc5k;x7GOUl`KTF3c&5h8X*Z^ zWt@zy%ID9O#;^D0%dMmKzMr!CQ0x$RLH^q_smGS5z@w8chSuyJ$Da*h=*5nc{bATn zJRs0gTvU`UI=S@&Nm82k(N~y`=aKLf0?!cn!{B89#mgksFFsf9EoGiPdzQ$q<`~^t zobb5Oe1*vp(W!%^wz(dFA^u94F zaccJW5eI{903Sa&3DwZlOf9-Kz3%$yY$YAyrwa0HstamfPH8>t4SuzCAO9d}p9Jw~(>Nn5DwYacAuW>|3G1UV$UoKl>G}Pe> zGT7@NCnr}chDIquZ%jNQB4Q(wyK_s;7o2&I`LO&O_rS?9#fl3Xq0sihnOQIf+R%Ww zoVMB(XX8ArX{iz|?$R-vN&`OHP>$^;F~#o68F#U5_R1sN7gxsPQA1W5)N-{`*LhShpRT2m7UVu^; zTfGfHX1m-c_{Ns!5e%NwI=pd3Pbsihy1q7Hp0|)wN7~d_DAJ-?AIO8{cj^Y9mauoaa(8W}ic3Q^Hs<1SJ*+z8Pl> zHhg{;9u_C#O&WI>O;YldLdNUNZDMnWtVEcon5cq2hUI#otAs5C;=oJx>${#(4HuG5 z|JnR}xSsZjqiGl1_U>46aBz68)sXquJwDWhd=9)i<`FC9H63k;yRnRX$wWnFkP}l}ECetkRS*dgYJzn~>MZ%G zkUMr2V;0YbpC!A+poD_zLh5Loa%Pzwp2-!IT+aGxunCNam zUNf37(g&c>)1O%>P2SNm%z7OXZMoFy;8V#vsTg`wVkY967(r9e3)~9&K;~Cdx>8qRn8HO*G+8w^QU-6UkJ>je zk3##`#z(4{eLz|yQ@Zoa($cu^%KZ4^K~ZCj+XlOos&-=^1+73ImY)bmhN$(}z4=y2 z+;XmM#pQjK$8!D>;!((NoDVtUFysNZuMNFwcv6GjX`+OB-Z#o{UsV)igxKBDSTnkM z=hd!*o)zU1mnTeb@B7cqfv7EE@Jj57Gkp%(-EON<+BEZQO^iR79IpTLAg16R$ zIj9<1TU%ANpN$L;yVe#YZZr(ob?;mtBA$3i#2e4-adb0FUe99x3tHw#_2H3E|aJ<{*@kG%xE^UTXNk7rqS5qFPOaKkdgA=zAX`ZaD83GVMP5 zZF%|7;qlzZGOvY7xK4){6%0MIwbg`h!d8ROn}}Z?mmW@wW@KhMuz+p!EEyI6)mzj= z^!upFF*i3ikwhgH*Gb<(H_n!2Ova8C@!A$;rW?F3Mx1+EhjGKC(#k#Vi)sr0W#@nQ(4Wu?m)n4O-M z8yrzpH3RlCm={p0iJzI9Kdi%V84S0>MtFcO(gpP{2q|>AT&^c;H;aAfd}`-w)!WJ* zvvnyLSvu$a?uaaZa&j{0k22gK;|6%6HD=0@R%vhp;3~5g7|%D+u*Zt?0q??KWVI?? z-+si;S9{VyT?TN77Cc`78x6y~JL|fw&z9alu(agziJv)llJrDS-B~(1<073IhO4^8 zRv+2XYG{UZnc*+Lvf4!{Nd0mtzRG{q%IYt5b6s3x;f@ZNO49S1&`|gO9P<&BfN$uX z%r7D%tYskpys5=;p*EfkSNcP+)^E^kxEl_=hd;=4PU!Wu)Bwlpj6fH9?*Y!Ml*=b|wuKbCB+gn>(DtdYn*CrhI;aNUg zlRoInX=oi`h(mh)3~GTJ8By1-O~e=s3t7QfF~|$+f*$Wd4LXy&AIqB^oh?<=)ex-BIhJ9Z4W zYuUQnr?08Hv3_i8E73UrGxVxil{{ACjl7GQINivPjR6$i>07=@9URD*&3a>Yz=k(} z7P&%LMC#5Q zB6rfbj$dk3l|I<*Xyw!$={)YF=WT0FhGadpYd>B^o%e^HaMwbHyQv31KfeJuZJrBq zA{ieYZTlz_5y$AfPF7+Cqg#%Wo1kxqm9WZ~J*wHP_`{=}f5Ry30V;bRM)@ z7{AGhU&r^PLNSDD4@Nft?QP|s!lEZ2BfUuI;x6@<;UDKkHC|N7G@Je;N|bOr9W3bn z+`&P8MwXFOYee)?(rqq5l{{vgbRS&u}v64w@eZ&=-SfKLddfXJvonh z`i|9?Giybmb1XS0Fnd6E)p**z_CeII{AVkZ9hoRu@Xl`ofw=Y zqgm?760yXvJL^ypt2Q7#wc$3H@-vejzp)-p5)A1wdhGNQMhuH=Pw3q+ZG{jJzH;3V zp7{>35x`g%e1V6Dr(qfMNKdbAsKD$hFK;7AJG1xSd6|8AAQ3KvzV0* z2GumbxjyMfeXof0^}uq&igQm-PXuqmnFGak5smI?t9>^_OM3ZGCFOh(CIsb ze>_oc>szc<0;4sukJ7-aHoO&IpA-6^rgZq@XB@P*gPNZYdTpA8<2X}>2QR8@>>mtT z34zA!dYnRGQBgxyNW5HBbo7yWx8)tP2RfJ9KvLN-`;>QM)V0ukAUc5mBFjH;0V>2r zjQh~h(hAs)OMu}J@^_LFSkzMNH{x-mkV{oPizWlv z`b2{(&fwj>cC~7e3ptB(FXieCg7gSQA6yx;@bmeV5(n@Mu2ykg?toBmv@spd*q|8% z6D23Vx!9M3buu;My0k`Q8pc?07X!` z8vxM_I(Tu%#X8q{U0Bm{5e^6l813z?c?ys&Xo&1dhv zYtDSS_YN}D3&))qL2Ukv4QIZw&^BrGmB0|aE>}-In_Hv*@xa=oKm}1UsScM_2 zq$b!P*vj3kj_cfc=5UaghF;3-?!=Kv4~Z8%cI*EKkh}LbJ>1%w2T<_nI~#n;qEcO1V%DWv3C5OjNSnh+?WB8BC?wgP|>!Yk^kH3$DM*7h=eJ%C_={8UDcL z8^&RED;{MWQT?S1RxA@k>ReZe zL{3c&LV3n&8XAwZw7zGy#za)!Ay7H$=T6#bpP&Ad_M1>Crex~stv%C*>O~T>NXd4@ z!!zmlphw2Wm%_rr4z|yKv~sruC@tgd)bp~F7^TSSUz=RlMBKL)*kn^XR6*zMJ58T6 z9)Ebzi^eoAB;LOU^N6V>05=1;uvgYMg^h(0`Y2t@%u@GK<#c|ncK0GC+t||@9 z3Ja^k7xbEiEWh!X_evzg`h-hi<(8J0uX1xUX)yh!Y=^dyQdK8Kq6ML<%kN+nodQ!u zH4j5IwL5GyY(v}ef|j2;BzN?53i3>QbR(ke?rj2kXd1&T{t0OSRgbPIl;)rZPYK2; z+_{+dbn&&Y&?7aqoAo94IKj3q+WAd(Agw$^PWDpn+If5hNNOf9Ju_j`e<$674c3J> zqy|^oR#vPHI|WYIqWxkhDwOTTY_FA#7)<@j7|g%1FYXa5>TtQCp`mwR05G^$4;fEr zd=Isy0r8+Qa|$Act#G&e2x}ctH9ctn=cBdO3)lvdGzSEy?vgT zls+YxZO#Xq*ZBB20dq%Z;Q97OsKW!hR4uoxnOxgF;I6j?6!YtQ?W`ZsH&>o zV>GHojLQ@9?*w5?vbEoi<|Qn?y^mCMhQ7?x|8PMT3_X$mKx{DiB4%Q$){-}QX4d5j z(WrFOkAp;Rp4rdgQct?S$X!j+1?&+#Ugh)~gt* z;@2}?;djda5FYM`Db|QJR#86!d0$9+?H@KAFxP3Qcf2x}|NY99st4sKhg34$E!=L} z8@BU^pG+W8!Srri@$k9Z=#fdks?GBB)H8c}X1}?dfNv~m*mQn=z*i$nm3JWu=u&0W zA?awiOCYpq@b(}JO&qtKMJVl3SCHwQGsux_{%CUBJ_^;Og)XHh@?yHz_`xlmwR)WL z5_tO|wJicC&~KgZgqiTOtk|sJ7hrZ`lJTa?fc#TbP)5x>_}l)r?7W|s6*0iWjyUfiuJCL zbtwETjrDdG6>Zm!pDcQR{NQ{9$V=b~sA)9=*>N5mxc%R-0vGmXjrC&oN%P7L1oSR< zk;~BKRIl}5lb~=;UA{@yg~wXaUuWYJ2D*ABi>O}!{*~?-6pz^w)U|8Z53^jg$grtQ zKruZFJD_3sXOSPNhDoJV|Ox6*#AAu@J`ChLfh?YM%Q zE8ng7Ph{fq0zwy1Pade=EVR57)E@JYHk&h1^X8=8t5@kexBxM227xDYec`XeWo#ML1Mrw#8s(Hg{6i+u<5^X=-DKCG}FYx1? zWm}IhxJ0s-V6tHa53sMo*T|-F{!YD0IX2vi%JoyoEjoR-CMHaW)5tZ<+e?Ge*7GN2 z`d{>T*7jcnj}LsjJU?D#&~4y!SsIy6LTON_4few3gq~5`84<$iM}GMGLlfA;DOkF6 z7+-6`Y~%#hV{5%5Jw07+Q5y7sl6q?f-Fdrv7mfp#BP}~y$>XW3#QQWrMvY9_X;pRj z8(v#~hQ`>hba=(YBTY>oyAnR++2_&b`80aiEKdvcvKAvNkTU_N8F1F3Ac8Nwa#8-qRJecL+ZcT-jHGS`)^te0=$~-@cH8~{xtqX4jTxw-(ODw z17!eAF#^9!?M9NVUR~ZgaLw~!ttFb?wO}am)N!TMGsuphj(L)A^P7(ghU`R`0DmQO zVHA*84FCV*9SRDH_5Fibg>sHMj04eWftfgk%Q$ZYfM(`i4=`5J zhO^7_w@h?uj8v*@ZEc$XQ3?1uKvU{v7rJu@fOW8c+P6gf#EB;4PIsg9E@uo-&UPLE z87lzwj&K18ufr`jg#g?k7%mIoj_&OIhmpz2&i>J?_VgK@mV?6$n-X10L}ycsdBE)p zfaa_*q6w<=9a%{!D=V9zzIWNPNI-|17E?%}qTEoJdVA574L9>!8T`X^F6>aiZCG-G zZU;%MgV9Qy4(aUf{!~7YnVAVW0K6O}8N)BEM*Iy>AK(zInK}o%Hy`tcd)1OBSm&I9 z&xGpde^zXd)653NHgKl3CvKo9N zL|ThN{q6V(P1m2;V!hWmadR+eAGs&xZFwG298)#7wm$YmA5Rr@sh<)>pcbytEB>V& z_N?l7raSYvPojS=?H8XuiFsDCto!znQ)HRY4FYe z5c>a0Z)9n-K|){IW0;?K0lq>n~F5kx<)Zj@VVfk zZ0IcnS?!f`XU}$yk7u`3cX%F)Sg9sY5DlWD5*;s=Nz{_nl--3@k;D}CEeSN-qb;L-AempKu zKn5ZmesnaXdpkA4ca2r&pF#j#W(O+_WKqNlCu;zhVOH}vvMS=7mBhEk9E0MKM)#~|JX8MYdK+mlri_T+JszCc9rc7P#>N%)sPYnY5d*;Oa<|VMyl)UCq*PAWb&40 zqDNk8nDP`mUOn#@!Kr-2YgW1Kcq}hzEu!o{EBRN6LMox}glXdaeh`!GsXqaln2%1Z zzDM6S=l+jpgj3D{R)rey2kskF7xwhY!shV=P&2Haw zPrmqhrfdIqf8~9tQgz7Imaqxb$RwJT>I#o_gMV?K_DbjNsk-#sQ9&LUWULl>k)z{;W4 z2H0^x%|DD@zcpprCRa>9P=sOEY2#_N$ag<|`c&GnHL^F;o%Q-Pm6(`VZ-9!X zX4A5`v&qwk+XF7Yg5wpuI`{yH-_DG23$ZswA2ROs9DGR*|n*7PFh+PfxaG5u`$h?X*mWi5x;V0X2Q=ic_n%3=#EuIJ=8`#$uR4uC z_+wGH)D;|&E9uovtLLCO6JHUZ!HAyYBhxXaA^OK10<9q;oDFxLjE+N`5*)-f&pKrT-(oBkBKQ%1@T?G zrnDWG^FgAL?!`)+*O7OM=5!_5p2O7N=Gqgk0?PHi>J|{{8{ZMDDVV^>Ws;MkT!0LL}XC= z9RYQNg7lM&e)s4}f5hJ`b|_~;q?ZnJa`+AWr3zv+Puhe|V~7kN4@S3DL_V8e*)abm znY7!^-txQ=V2vGDhGTDSN;$0z2S>5d82jZY`xt#cbG@D7KTsNUG3zOh13gKJs+ zQ7K((toEmiu_Y3(MCnyv+OZ9pIaJxVSkCJq=d3&LYL4^E9yp8@Kk)i_Tu5a^wC;`5 z!cAmuQE+b2@rBTsYre$H^nNyGw*kEYI^&3q8c<^0cQbZku`S#&hQ7q~SE=bLV;s4w zy^r5^Yf3Eiu*91dXj=!>J;q3#@lLP*Ts6>CgxJxy@Q#o9;7iOy;`x*|rqh?0mK^Af zJDH9LT;DFntby~K*DA3|x?oAP^i(JTNHe8+ytPxgFRk%I$6_wLAf`Kt^oPI4NW36s zyHZVV7`ZkqE`|83!?H>tsfhrj1*LP!ZqiQVR~P3kvD-Ew+ko~2vD8?*X? z__Ao@IrxI@H_87g9y$_Dr2JLJ>%*`BQ);4RKGFdB8er)ObZTy{omz~dA2BBhzz#7k ze#C4iHh<@Bv(cCje#ET&xB`kN;yVlY#qHD)asJmp{`&ucjxlR~#0=W^u>jt)gxn$M zPBKgc+;)aMK<&Cvf?^GIz-_C++zXsTJNG`-JE&=D&I3{v_(P3t(vJ9)eIy5mb&HM} z5AFxKe5y3a5kvMY)-PkGclIfny^nas82b}*LykB_8RlF#9X(SL4Z7Z_{(cQM4QU`K zUZ)2wi>jX9t3Hb`Kh)D!+6Nm-nC!Pg`IGP5Kmi8?oE3c|Z!T|MMks&MxL-p)umS;e zlF?$jC2$l}XRriOXCLoh63*-J47lbntI4965VMA64gH=w>YszlN z-3i(ckbc55ssBhnA#?voKdj~oS3NosMY(1GcpK`{e*3xM1Cr!%B%oBLm%NZzash2q z8vLHtzk2epKfM|SyorP!2v5!#`GA-QZ8cHUOR0y$_zh_754=lzAwQROuC%I(Iia1l zB*_Nt`$Su8Hg;+mPniPLv-4axj>Gi?eN1`3S@y#398G8w&H%`gM<7kI9jM$$3aIQ6JWoY<3dIpY1KDQb8Hq5S-DmjsAKmot~k1LE&(yX zA-8}XNGFrvki=_NSf{VAPjt^6wO5@L!y8DMK<`-92NmVEcEOUnOj_#HOxV7#o(M87UsUnH(Y)MFW+6jE5tV|sf z8%WH4vxy9jocCFt-Pz9@vI30$V}UpVS~D#;|L#<7Vc}V}AG)Z2Fq`FUM}33TXv|t5 z@dfEqV?N7$U0wXcswd@jrij&DKTn44$?qy#oq$7l{u_{e?g_R5U@XWTW!{sLXtIAJ z**E545b;$=;;5I%eoy-UgHu-CHIpSEkzbfN> z8&pmMlxJ73rq{2qlqrAVmhx}7WfV+&0s0>K8>@XPFl|5bAvrl9B_*Y_gT$8zD9d0m zGiQ(>N`?gKHbdO*mw>!HMgk-I#Gu`$F0T$8v!fP7YLg%hB0m3R-p5Vcx-bA zQM0C`r(gYy@cAD!W&n!+us}1;BwYb<+S81fWn6;*d@8*Q+F%boa`%ccB~8s3v6K%V zjM&#-iP~2E8&t6$2cQb~2UIEl4)lTj6L2huec?xcdz>5SEX~Wihk)wB{{&Qi=7VyB zzb(8W_cDR4_iNk7vmp?8I;Cr$Wb0>c0AfNv%tbQ?w)=MOTVBW|v+%Z1I7z@) z1JADKyM{B5<h;h7h-O;-T_^lQJF?mY3ln zFi+XcXy}tiDGeqJb9nm9jsW=klU%xUUGX*Sx1kV&-<&-7cW4U$IoE~eiRqGP;>mJr z^$D_jg0+s6ELrQxRW6d%*RU?#$^N7R()Lep%Xt{M1Im+9HrE&Eu5lC}G!FqHSr`{c zJOtcz(_lBIBTgo!B%y)}JtteidZGJF&CTZeB#Kp&gH_I6dyR_FWZ?3fIoTMqikFOm1jK z8#FU=PE49;(t&e*I!)o5LUWgc_UrZ&h9ySgD+!WeMwX#_+?{7H4ld24$Y-Zq>GY2!Iu|rHGdb&Sq|TUQ1}K!1%6|{Nd%Uwlk|PstU~~SfLmC%Ua}@KSDrb8Y%^0) zHY_+cFxm(FvMEcA71&nael5Q?HmL5ut+Ijs7jOmaQ>>f>I-Cwa69&ndpCCFGeZ<>& z%$Ug*p=9nYm5jv_osH5;^D@2BLkp>;CxnA*C+e}*c(A!CI_{mwiO0`>HQbh2-QPqc z|5`ze)W)s$a9`7|*W|L9PrOu?4yLx+!7$`8v_KmvwYJ9;8a>=c66T^psUS-0MF+Q6AjajGR1=CVGqP-u` z|Kh%#J19tIuj11odA2#%4vYtgU1n zawKz%!iGE4i&Zmxe8ei%b{B$nR%Y%=QG75EG#{CzpgUscIw6Hgs-Gz|p7XLL^>l(3 zHdrw%Q<^2XmuM@jP}7K?1tjBj>1jdgsb>~yRm#KOY}uMiAjF77%`Dd2_GO8@UDkGF z5=b!koic}-B(SDGMk%hj?yf+yj=PC_xYmyG055^Uo!G&>Dd#@<6m&8npe3r&C%%>) z`})2*zG(;1`15Rhg7HUufwnjFW*Pc|i6<}FP>wvgi0I0Jum{F^2h^Elxc_$Y(pWn3 zU`?$7T~8D(Uj1IX?tgaxA9k07bO>*4PM{zZLp+@%-K_ZLz^NtjQ<8KX&w1M%n%=86 z3C%?pJYR(Ls$J_Y68Oh>wviL%{9Z)>#N9OWhk+_D;ZWmWeIjZTAzUSh(1aO2O&0(6Fn_3v%?Id9}0Qs zptlRXCk7x|aUmh*$5EE&IK`CgKF!=|nME)|Vs$wa2Z9cKX-28GoT+v5xx@NPmEg0T z?lz}2Dkw6?8k)0ti{PcAi8>3HJnx+|iOV50i=wh0Dx%c0)#nut%qnnauzRfLRVghi zo|DM-Ju)zZCI{3WRIZ2a;?wmnMd^dvt17J3an}nKEUDKhpEz_;RTZB7z~}d})WHN4maWhD@rEBEiTTwNy2o4NU^XqqCa{K%U3Vp_yvVN~^Xco+R7FF` z_s^(n3YdQ;Y+!4fY>bw>vX;cDCAVk*^XUUDan;+C5YgIhHD_u1K`4mQW*4~dwQ@!F zk;yXS4*sXliHUMpq4=64NSGrXb}E@j4%DKJ($aG6qdcmsn>!pDSN!3nvX?UtHab*f zZGqoFa+h40)h(W4gZHRWf3NnPj=R_fO*kwJjR@^qogS|6z6Wxtp3A;IcjXePQl+7I z8sb|(G=<2L8kffx#`lbG_99yPEK#X*2TMUOEb79c3qq`}`;D^1xr#4o7HpEY zdv*0Z){B;6KjK`H(m4hqTR+|)8`_)N_I7xkwf&^U^fRv2v}1wUefT!`GVUs@h6Qp+ z!6P%A69GqfV{Y~@BNAqVLc9)Q+TZg}yDJ9h?#q?oXLmXV)8WS*hg2g;9%ApYC3k`@ z&{|p`@ws}c?~c^>ZDq{xJk-Wiq`j!SCAc?OTi)v_WS8^aK34gxnmNDmTGal8o%@+J z`uvk&fIzr}BOCjpw!o#+&~*I?Dc61CqJwE!xOuVje09;9E{Ky(d!g^4tX1C?Z`eLr z;jB($aCNty*uC;pmAth4mjzM0l8`-g(3EW^YfKsO{BqZsm4{8&W6P?v|D?Gvu&{8^FsIjVoh)UZO|F}$sI}xYY^ab zWOpN^@F{W;gfd{stLrzbPa)aGQeLYs0S~~TK;_#Acfix`G{iJ|&EMWM(NH#21iMe# zg)4kz|9qBy)~LgfWa5HI&D~>k$r5A_b3oa3?-Nj*aBS`a=@HodyR`iJOh`U(4%ZRt zbxSwb)%K2glT1F|ThWkn_Q&3Hs~0=RTH?=J61f^JQkR;|qf~@ENPB42h&y*}6!nZB zj<8x;e*|e?)xlU{SZpMBcIZm(S!wnnfz(G-RXcXe<{~Zk4imw_UPm!hj0HJiW8chV zo>}gIAPGkdSpofd@_E_upgPcr0^MS>gEv@EqnkS%YC2P-#SN4-T41#fZ8*JC1}v{D z&NCSIJS}eXuv?q2mlp>k*2r^%|4<8k_99G;v(JHT8K^d2L2tf-k&N_*YPtRrE3Bs2 z`3_`969W5T*g(=ta3Xe}vMq8@J{`u5n2Jwky?LX%6UC+ECvLelx*5vV2c^#7PRzfq*6~w)`m^)=- zHZN*E?2SM3Aln+3hRbYp!tbNKS4tgSmuDTtW|sQ?N_s?uso4Yfxt;GmbCJM7qR{FD zN|pN6D;R&Uk3B#`)VQNQE6}*+v=s7H$UeO6z2UGi)KeHFspzFFS?HF965sWB*>?Ar z`EZ?y!ssSy^|8QZCr@vs>OCc^XW= zW^6o$RqiTKuwmfRREI=uCYj+wd6lGJOOIMrctF-7>T5l16~-e2ouiWN6;NYk!RJm0 zsL5c>#3(kja$u`y*2~)%L_8sZUBmpRELV_uf_nrWX7**^*L1mQFTOqg_P&+pt#U@g zc;IgbZYSWn$9bcMk-Ovbn_WOEo0d;?!CF>rj*@D*Cs!IP4Oa=8V>0@Rs>$vflEp=@ zL5KIn@ezEXfosAKn)AnR!&W83)h0Q6n?MB4k-2JrK7$Uir<`52yJ>MXBT9Zg<6dt6 zu0DW8LcFkb1#HyGc`EP_H&iT0yJVO%)w_JZl%wYk z3S{EL)xNNxLro&>;UNxzum?mD2>RLQVLu~DTK=VHUcUG?IDRt~OE3%Fxp+$9@)>Uw zvbMJNAtjl@mPWT(rQ&y`1mK?pZ7cBfUye8d`u&zH!RjricjhM`e<Md(q@0PrJ@f@#`r>Hvs>Bz@!~~ZZvFZ;c|^kmv`kEE;6$=xd zPEJlrV#Zw_9f%5ut=NIuUWU5pU~yaN)g_>>j*h+>S!p~Z5~rtI3lHJkVQ%TE2iWVt zUfXW@0PQgULR@=Rr@>_|XC?-Xdl#Xvf78*~u2S-Q46=&CXPf1WE@D&(<2ylkX>Uxq zvvcT{j2W4WzB^qwI<&o67bK=|G^CIOA^0h>$Dx};UaHM35|Jp{9PjhjKywA%ShjV= z`_1?9695eg+itttZtGnqLoNAb8v(#90gP~6)7U6S3mzHEBC@Ak_=pSp@j{}1=}-MP z8$tAKzM5Y)^oHp*VS+@)K>v>fytxi`jzNw~X)45|2JRn-j;0l?x2_AM6a{l7c+W~G zVQ+?&JYW!5@Rjn>$#oS3=jx*4qala$4l?J6+9=gkz#*{K3%=-{O1hFWkojZYQ4G*e zfZUS_VtoNxuiu0KQWT#mW44Q_K$)%{JNIjA<)`B=lSYL+B@cIkq+h>71O)J=)(WqZ zvs3zkX3hZ%=p-=}$VokA|N9-HU}RsPXE6+yYHE1oS$Hbysx%ZHQ;%$aUz1+&*hxXx zjIqn1OUrq}V6lKK;c^_Ics&cbqrN>^|Gv~Wa`9LLdUHw2WUB$-76fSow%RvK zAQ%S^d#O_#kD=xNa=l+^77qZ{lUdC@5{C3`1jY;3FA!gz+C9wR5f406YWYcaA_RM< zMyB9uI2_HRt0qyDw79vwe;~s2dhmLszLEYD^{}^&?$orcK!wPzw#~eT>T2!$Tb=-| zISD+(p56zLnD13-h&$9F`)Z7g8C5=}ZUxLl^tdNi7`mS*kMz;duj(Ro0@`bTH1dC= zy)*yDqlFiI5OPZ>bP+sa%Zt2hjf!^Ud-riqDdc%em6<@xXs6gLwgggtu z5wIWYiZ|qcU-@Vcdqm5#Q5EP_;GXRMdS^ZxneP4^JW)2OB*ZlQA)jse41XA?Tc+5@ zPYhuI3&KhbRHuYQ1NM*$11KDxKN~N5ldST?2On?`P3_d+8DDVs0Pq`y|5Ur0$*mVY zW)r?N-xp9fRVu9?zd^6b(UI@NIyy3 z{*y4e|Mms5v@lSfWK-}c9+{KRmSebGN1V?V4vihw`wOs@m=-ixCn%&8x>KKReMGPZEF1mhmH_ki5%ev#iJpF3@;T6# zn+Rk?R(0t;joc!RRnj{nsZ|zL7lien3pR~}`_Vby>^Bk|3fy|{wwT%*)&{zi1_Z7S zk-N6hvEG)Yi(N(b+qbI^5RTn8mf;^(O`KP*@=W33a#kO0RWtj84AjH<^7?iDC{fp$ z{f>dFmW1>vZ>-s2T(9~Bx@(3O_6Cz3D{tl%f8tag5{%E{8a|g60 z0n$tc_xC+_28G`(Gf2KDXNTk}R;8+x+7;}4_{sBi|EX*&Yk=@1=)Rb(1K|6ZCUD!| zi*~G8ny-?nS;;I>+^1Sh!Na?-AiFyV|W>2K>u}@Lbjpv1~h3GG>Bc=twbf7*X zk4geAg@4@|kny@`gOTTd1PDl-{UaOBts}ARmjR7(qIgg3MWTtMmv73O2Z?8_Fa)|~ zCB5XhV@V^X`rD+ooovLIaMZ6F87$++yu@Q}+`SM~Tp+Fda~Uy$Pk(PFVF<@X_d-ZG z*yEdryE`Z$fQ$z>R_)a-A6oKx@-C?A=)4?QPA)Bt1vwMkCl34&m-`(By-#=ajEzzH z3|YMfJ_=xUPz5#SHE0&3b|?KZ=4H5Si~IG@{Yi?zQQC^K6*2ny@Odxf;cqy$!Bt%_ zJHlj(*4_B}vHETPP|xw3g54?;^d+oMWbBJ}I4jDDzKg07T7e^JqQS`b9+PUmP^S2Hn3I83R32+wW?gpYme z|ExRHA|8vVkN&vVwF=3q@pTR>e@))|W_w*RUg5`2CKi0#CC^Q)_+rR*Zc9}>mhOk~ z%s!*`en=6Z1&M<>j+O(s+`C;KFfmK#gu361hyeti15(sFez~I?WV9mW?!^>2ehoga(lAdK7EYx^BT&RMh*Ngp3DiDwCnP+< z$3LW$@8;vjG2gXqKA~G`H}wIpKW?L8nEx`AoOc>@m~#dyHFdTy7obO`e^??%WtPhZ zi5fv>ajHu;KbW@N1RO)|9Br=qo<%XXm|ye>Lp~0iq5PA+p0+#3CSPKc@(%vyT#W7f zaA*!k_nF6FCr%$MB$WncK>O43R}&t6>rQXI(o%3^=LI=ck|=$NKV#LM*qt;%a<`Wrth-GEaB+en?>PV}Kx%L~gatR2O2ScU{>ulRH9vkBh4;b5@W$`U5Xs$g{J#O4d?dM zp}IV1lizZQ+a_uADc*GlSysQE=N*>65kPTB@(^;~TkH3~?DF@=0rZZf>zHbcGCcC3(v@nYDu=zDB@z9DQ6O-2)kd%hy8aN* z_8J~vPcc1PO4!eY75J>rXGptP>TOTgM7DE(C*=I3W9}CX;Y;fSk>n+LKM*4rYS7)6 z&NC|>q|TC#PTA29U!nirF=bcZPQhe5F4J(hYM_!s#RvY7b7ZzF6>8^wa4EAI5z$!@ z!Y$n?|LMNa=a7W%Kr<_lSQnR6~vI_`10q^NafMG*X{H-M)g;Y`!rv?w`KZmXkKQ z(DnJVsD8_P_lbIu#>_*NkHMWcrd0)f2ZR$aATvUTMyyM4zqHY}z=!313=1fOGVp5_ zzaMY$m#T>&px&h&-Y6VqDLOuQ|6w3Su4y|%(MkD-4^I*6-`W}>+uyW|4=1o1trP57h*!#ZASm^mJN$(ei11Z#><()et(GZzvisjd-ndm@64Xr|6W0$d`SIa znC)u#&8`T5&HmqGS1;bFL$Y8=ok2Bs51xWOI1+yTcmC?dn;~|4+#c#}=5x(%NwD)y ziU#oSK+ewcA*$+z?3*aORh(8S8$Z}u!UiAwyV$63{b43U3~7T`FMDnM^pvrOxa`CU zd3Z8;rV95KU}Vp;;U=5UDe_WLB4hTw^@spRH|~<3hYwo z@Dy$p_)0GpiRoQz4Wv`?`*AFiv-?Gs`DMH4cz5(?J#1TtxWxFd|L|5?cI*95yb2Ek zN%IIGo6OK}T=o z+e7d)>>vA{Mn<4-^YWkh)cmNquMiQkh;9cr@Ulc@Iefs%RYjkT1vp`sUE{~5XH05) zRKXG#C>?iOXNigXUEbf3z|X8G5^M^5ULE(6G5YpG9z&H=Fa13DN7r#40Kar0RbFuV0CH>TxZZLrv!V& zoAB)3Wtpr-!m=d>NIRzElE-H`ULh=nx8I9;?-{n8XXyRSt9O2r-J-h&NhV~K_7i19{6I@d;y!v3mpoe&(*)b9>C0KINf?D}kHkq|E0aCO$dcU2 z`{W}COImo&cs4tQVwsTddlu3t;i4*SdFaq7ByQLFCQIJ=Dv8zkagA$lXz!C>dvlnV zE^`L3v$E34`U_!n<>xgF>029lccUwb0%T+fG`T!33O#ArcLL1SR*P*=>_HSxYwzMo z-O0ixnVLG~#id)n^ieN3Lyuz2mc5Q+!XRtw>uIT}*FN1)Z5(EJ{l%)yM05~d79O9Z zV(rTPEl>RUo%nG_Q!;@nx~xgXlxfw#8U^?wfYqXbYGODotp${!VUFYTUrj`{>pdeU zVA;p^lPqxAmJYk><9qT*`TEjNXa9zaiy?lW4L@ zP)|rny@^rC#`YuXS|qT0Qb^ga+^GrsX>0AS)Z8cgp7H@~hC%chX#A-M+Ty93ffvFL zjoB`=p4E!iRb3oiwMR@*8nGx84es`bs*MBQO`fJ69{0d5MZ9 zae`*vwig8(ac7-+b|DgDULW+~>=2HWo)>7k5^KZ8qnz=$b^48=&2CKQW88p4?fb9F zdXI>`z~cdzB=#|a;|VXC%s_&ViYnyREB z8>Q(!t)oC8?R&Emtr^)J8JfxJugpZyq0#h3GZ_b8+-}thpK#P;7Dsh;&fekusseiU zcWwXQ~k-EpFU=qUg8<#}<< zCfINd33G@AV>CQ#(fKks?jbnJcy--xg@luvTi8OlaaJ@=-7JCYSM<=zDfr-W*8CR} zhLgmYh~Jk}uOth)Ux}IQn2SDREih8-)#j+%XOv03?KP~c6T!-+>|iYf`DlAV&DQ8^ zz-1Q&tLvbz*MSnI_jU&e3RHsK9qw#GG};6sm0|}s1%1nf`n)a!9!YsVkR&HKR23SI zZGo>E;8|`pt(a25PvADv55JrpJYlY|z2wZ=L@2DMDXhm8WEbRe^4^Nb$bJywd86HP z{fCv<=Bo)N-Jc56#Gs&{PphH+K|vHA6av4@0GQq6f{Rht%ZHxfqgYT+TGve9jVPHp zjY;e+V^k8N+TzEhnO9Ko66C>iY-hS=N*95o) zHjjTi9Sw6K`u~&1v4*|sF-GaEIk%J5a)o@YlHhQ`G;aV4m;~RjnUP1-~+H&>=3497ip~Fg0asF2M9ojRbtCP#H#-PfDpU736U`sfokLWUJhTbgH zuVx7Aax$JJ!Y3<9dpJ5~8tn3jg>B%Q%rW-&v`wYfnhgQStG;AuA2-^^lb)@ZtNfBr z@q=n>VxBMqnB#!sqZ18}B0_-(;$2wCYQ{3BfwRqF5tY@Coc0Yd&wX|b{gMtR7nhI} z(I6KQpe-%+*t;5Sq$VrBOb{T!b^21sNH{4NpDmoU(2jY{=jF`hQ%gDJGh9cR*fRe( z=Jl(iG%mn|r8*po`zdLEb<0p6eL~z})P~MFUD+=3-ZHdD2TU0n;QfyDpyba=76S7m zpO!c*D(M#BW&Xtw`F`HD(MbC|M9W%k0GY@~o$oC|UM$t|!N7|jdt}3(=Rn*XlB*Uz z6u8xWW-gkPp?X??+E}7hYxYAerO`LwYr%7KvOG`f*TcQh$S*R;$%mCl**^n zo`CiK=~@^Z$l&d7WN7fy!P(l`=;k3tjq-Qum_K_~f1bRLU+P$o0^qZ#iPS%t1>BB# zeIZ)*2Jy-z?UfI)!T~HtxZ;JQ9{O&>&bQ+4wd_Yp=%@A};;qxoo#UD%)rSvVrFXe$ zn4~*e6g5jX;>2@e4du{p(_irPDR7vj%@vaAKdv-}uLfX&HB^;w!<1X@(KgzootoGa zqb|n;VlV)vq53(hxf*9wge0kZ(2dsvA(zx0xF_(F-{a!D_}YolUDPqNfl38zd0hmE zv|^E7mJwg&RAcfe4Bbr2pbUn40F)-(W&KdHRNRE3*sk%VMXEu5SJibKQ~PPWpZ_~b zfFe|vqR1I)nJ%(C|8F(gLv6yxsgMfgi+?}%UfIRQA z$>S4BmlJLF^YmFvslojvMK3vQrM$bEja{p6K5YmT7nfxyrZj@Cl8cVQBYy+u_3TgD{em?6#k+ejM<8>>v3&Pt z%w+*er83D1Niis09^YBNA0c0?GQqILF%`|c`C?_!6?nON3YKWggmmTOT8SuzicPG~ z%b0^B|F(Qwg-oa1 zH$`FI^vD@rJx>T=GEdOaqW$oBiLY((e0BVCPYlo8spg@*|IXp!nVDNdAnWM5O`u%? zipVWWPha7+gQVnq8#2S>4X;;pyH3G3RRnc#9(g9>*|W&qXs*gAxdN=W%LFG0uV;h7 zG@>i1i9CA?Z7A(USkQa9VRr+JOTKq}@X#m@Tj=Nj$k=8Llt$UdCZuCgC+Vr>S><%M zfyK7abZdm@UE8U(7{TAc04&Ne*<}5qhid4uEru{X0&9}X#AZy!U}v^{D)f-7^}oo( z%AW?herJu_fAfQIwN7O)h0|eJo5j;7T3>=O4b7<+0%B7PGjwqsveVqg0l-`N+)o#N={0U&Nm8UOtgLnyT%)Fwy4i)D z>X#cFT6~FB;;z}6jgxH9p~YyppOD=2R^_-A(e;Cw^!{lebz-}Q7FSn9$<*a^v0&q? z@dku=of{^zzTOCsUa8QAo{F)RRmL5MRps@%-bRx8f$~SJO)>$KixzX8S0&+`Vdm0p zpofnIJTpL9TJzESEy#=JbEmUR*8bWK)%-0fn=M&NK_&)EwUxS1r-;?<@9;3l_RwqL zM`a>$_uS$PoGFjV<{&xagG1<-Ra5OXKp0K`%vkq&TvxxMyJao0X88_&&kDTzZ)Ih* zZTMETL)PoCcou7b8r)S04Nbp;f-R(nE~)n{+w`$C$t4L_Os|wUxOGl1am{oW$q*PI zN)6$PgG}?zP%yuJo`^&$cUM(Rv{+~DFA(47rlc0mj#zUHn$O)|#vnKNuNDJ7@z=)? zb2k_)wGVh#!8?-2CXL^)+TRaraIGJGVqZn>Oj~vdg0guzK~Qn*chD|gUlV@uOOn3% zMI`0oceM?5P*ovOSee7^Q`3||U<3t%dXPQ1%#WN(xHqXkYxePQkEpBX$L*nxIF+n< zHFg;R`~M}RyfsH$E*h*0B0EF&Zksv_DZEMtMG`w6i_6eZHS5`IZ&{a@_=o1>*39Rk z<^qU<%9|kGVOZcfZ`83jOC*}PEi95eQn?qyx>5nVXo=z zv7NDBw^-i|nF;1%Y6QY8Kyvz-2URl;VSOOlbf0 qQ9(g{jl&1L(#1n!{|h2os}E%{1V%ft3lg&s@S~y#Qz*P|;`=`^Ux91@ delta 23795 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 GqW=%J8j>;q From e15975e008588105a38b997fac33593086af8216 Mon Sep 17 00:00:00 2001 From: Markolie Date: Sat, 14 Feb 2015 01:32:38 +0100 Subject: [PATCH 10/13] Fix typo --- code/modules/admin/topic.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 0cb98be5ff9..c5f21844bcc 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1743,7 +1743,7 @@ if(stamptype == "icon") stampvalue = input(src.owner, "Pick a stamp icon.", "Stamp Icon") as null|anything in list("cent","ok","deny","clown") else if(stamptype == "text") - stampvalue = input(src.owner, "What should the stamp say?.", "Stamp Text") as text|null + stampvalue = input(src.owner, "What should the stamp say?", "Stamp Text") as text|null else stamptype = "" sendername = input(src.owner, "What organization does the fax come from? This determines the prefix of the paper (i.e. CentCom- Title).", "Stamp Organization") as text|null From 9fed8135d425d032f8d71be0de7544d4bfb09cd7 Mon Sep 17 00:00:00 2001 From: Markolie Date: Sat, 14 Feb 2015 04:35:32 +0100 Subject: [PATCH 11/13] Handcuff refactor, IV drip fix --- code/datums/cargoprofile.dm | 2 +- code/datums/crafting/recipes.dm | 2 +- code/datums/supplypacks.dm | 6 +- code/defines/obj/weapon.dm | 59 ----- code/game/jobs/job/security.dm | 16 +- code/game/machinery/bots/ed209bot.dm | 11 +- code/game/machinery/bots/secbot.dm | 12 +- code/game/machinery/iv_drip.dm | 6 +- code/game/machinery/vending.dm | 2 +- code/game/machinery/washing_machine.dm | 2 +- code/game/objects/items.dm | 4 +- code/game/objects/items/weapons/handcuffs.dm | 220 ++++++++++++------ .../objects/items/weapons/storage/belt.dm | 4 +- .../objects/items/weapons/storage/boxes.dm | 14 +- code/game/objects/items/weapons/tools.dm | 2 +- .../crates_lockers/closets/secure/security.dm | 2 +- .../stool_bed_chair_nest/alien_nests.dm | 11 +- code/modules/admin/topic.dm | 2 +- code/modules/clothing/shoes/colour.dm | 4 +- code/modules/clothing/spacesuits/alien.dm | 4 +- code/modules/clothing/spacesuits/captain.dm | 2 +- code/modules/clothing/spacesuits/ert.dm | 2 +- .../clothing/spacesuits/miscellaneous.dm | 6 +- code/modules/clothing/spacesuits/ninja.dm | 2 +- code/modules/clothing/spacesuits/rig.dm | 4 +- code/modules/clothing/spacesuits/syndi.dm | 2 +- code/modules/clothing/suits/armor.dm | 6 +- code/modules/clothing/suits/jobs.dm | 4 +- code/modules/clothing/suits/utility.dm | 2 +- code/modules/events/event_manager.dm | 11 +- .../mob/living/carbon/human/examine.dm | 2 +- .../mob/living/carbon/human/update_icons.dm | 2 +- .../mob/living/carbon/monkey/inventory.dm | 2 +- code/modules/mob/living/living.dm | 6 +- .../modules/mob/living/silicon/mommi/mommi.dm | 2 +- .../modules/mob/living/silicon/robot/robot.dm | 2 +- .../mob/living/silicon/robot/robot_modules.dm | 2 +- code/modules/mob/mob.dm | 4 +- code/modules/paperwork/fax.dm | 4 +- code/modules/power/cable.dm | 2 +- .../research/designs/autolathe_designs.dm | 2 +- .../artifact/artifact_replicator.dm | 2 +- .../research/xenoarchaeology/finds/finds.dm | 4 +- icons/obj/items.dmi | Bin 80185 -> 80469 bytes maps/RandomZLevels/blackmarketpackers.dmm | 2 +- maps/RandomZLevels/centcomAway.dmm | 2 +- maps/RandomZLevels/spacehotel.dmm | 2 +- maps/RandomZLevels/undergroundoutpost45.dmm | 2 +- maps/cyberiad.dmm | 10 +- 49 files changed, 250 insertions(+), 230 deletions(-) diff --git a/code/datums/cargoprofile.dm b/code/datums/cargoprofile.dm index 8bf2e281bbb..d2c11e8984b 100644 --- a/code/datums/cargoprofile.dm +++ b/code/datums/cargoprofile.dm @@ -238,7 +238,7 @@ /obj/item/clothing/mask/facehugger) // NOT CLOTHING AT ALLLLL whitelist = list(/obj/item/clothing,/obj/item/weapon/storage/belt,/obj/item/weapon/storage/backpack, /obj/item/device/radio/headset,/obj/item/device/pda,/obj/item/weapon/card/id,/obj/item/weapon/tank, - /obj/item/weapon/handcuffs, /obj/item/weapon/legcuffs) + /obj/item/weapon/restraints/handcuffs, /obj/item/weapon/restraints/legcuffs) /datum/cargoprofile/trash name = "Trash" diff --git a/code/datums/crafting/recipes.dm b/code/datums/crafting/recipes.dm index 4322fcc9f4a..c2f882eec08 100644 --- a/code/datums/crafting/recipes.dm +++ b/code/datums/crafting/recipes.dm @@ -35,7 +35,7 @@ /datum/crafting_recipe/table/stunprod name = "Stunprod" result_path = /obj/item/weapon/melee/baton/cattleprod - reqs = list(/obj/item/weapon/handcuffs/cable = 1, + reqs = list(/obj/item/weapon/restraints/handcuffs/cable = 1, /obj/item/stack/rods = 1, /obj/item/weapon/wirecutters = 1, /obj/item/weapon/stock_parts/cell = 1) diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 19a01eb7a6e..85799682069 100755 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -723,9 +723,9 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/item/weapon/storage/box/flashbangs, /obj/item/weapon/storage/box/flashbangs, /obj/item/weapon/storage/box/flashbangs, - /obj/item/weapon/handcuffs, - /obj/item/weapon/handcuffs, - /obj/item/weapon/handcuffs, + /obj/item/weapon/restraints/handcuffs, + /obj/item/weapon/restraints/handcuffs, + /obj/item/weapon/restraints/handcuffs, /obj/item/clothing/head/helmet/riot, /obj/item/clothing/suit/armor/riot, /obj/item/clothing/head/helmet/riot, diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index a2bcbfdb59e..33b509fc9a0 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -154,65 +154,6 @@ item_state = "gift" w_class = 4.0 -/obj/item/weapon/legcuffs - name = "legcuffs" - desc = "Use this to keep prisoners in line." - gender = PLURAL - icon = 'icons/obj/items.dmi' - icon_state = "handcuff" - flags = FPRINT | TABLEPASS | CONDUCT - throwforce = 0 - w_class = 3.0 - origin_tech = "materials=1" - var/breakouttime = 300 //Deciseconds = 30s = 0.5 minute - -/obj/item/weapon/legcuffs/beartrap - name = "bear trap" - throw_speed = 1 - throw_range = 1 - icon_state = "beartrap0" - desc = "A trap used to catch bears and other legged creatures." - var/armed = 0 - - suicide_act(mob/user) - viewers(user) << "[user] is putting the [src.name] on \his head! It looks like \he's trying to commit suicide." - return (BRUTELOSS) - -/obj/item/weapon/legcuffs/beartrap/attack_self(mob/user as mob) - ..() - if(ishuman(user) && !user.stat && !user.restrained()) - armed = !armed - icon_state = "beartrap[armed]" - user << "[src] is now [armed ? "armed" : "disarmed"]" - - -/obj/item/weapon/legcuffs/beartrap/Crossed(AM as mob|obj) - if(armed && isturf(src.loc)) - if( (iscarbon(AM) || isanimal(AM)) && !istype(AM, /mob/living/simple_animal/parrot) && !istype(AM, /mob/living/simple_animal/construct) && !istype(AM, /mob/living/simple_animal/shade) && !istype(AM, /mob/living/simple_animal/hostile/viscerator)) - var/mob/living/L = AM - armed = 0 - icon_state = "beartrap0" - playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) - L.visible_message("[L] triggers \the [src].", \ - "You trigger \the [src]!") - - if(ishuman(AM)) - var/mob/living/carbon/H = AM - if(H.lying) - H.apply_damage(20,BRUTE,"chest") - else - H.apply_damage(20,BRUTE,(pick("l_leg", "r_leg"))) - if(!H.legcuffed) //beartrap can't cuff you leg if there's already a beartrap or legcuffs. - H.legcuffed = src - src.loc = H - H.update_inv_legcuffed(0) - feedback_add_details("handcuffs","B") //Yes, I know they're legcuffs. Don't change this, no need for an extra variable. The "B" is used to tell them apart. - - else - L.apply_damage(20,BRUTE) - ..() - - /obj/item/weapon/holosign_creator name = "holographic sign projector" desc = "A handy-dandy hologaphic projector that displays a janitorial sign." diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 2ad488ab6c4..3962f5a7b39 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -35,10 +35,10 @@ H.equip_or_collect(new /obj/item/weapon/gun/energy/gun(H), slot_s_store) if(H.backbag == 1) H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_l_store) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_l_store) else H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_in_backpack) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_in_backpack) H.equip_or_collect(new /obj/item/weapon/melee/telebaton(H.back), slot_in_backpack) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H @@ -81,10 +81,10 @@ H.equip_or_collect(new /obj/item/weapon/gun/energy/advtaser(H), slot_s_store) if(H.backbag == 1) H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_l_hand) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_l_hand) else H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_in_backpack) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_in_backpack) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 @@ -180,10 +180,10 @@ H.equip_or_collect(new /obj/item/device/flash(H), slot_l_store) if(H.backbag == 1) H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_l_hand) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_l_hand) else H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_in_backpack) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_in_backpack) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 @@ -255,10 +255,10 @@ H.equip_or_collect(new /obj/item/device/flash(H), slot_l_store) if(H.backbag == 1) H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_l_hand) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_l_hand) else H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_in_backpack) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_in_backpack) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm index 8e6855a8dbf..089b7261515 100644 --- a/code/game/machinery/bots/ed209bot.dm +++ b/code/game/machinery/bots/ed209bot.dm @@ -299,16 +299,15 @@ Auto Patrol[]"}, if(!arrest_type) if(!target.handcuffed) //he's not cuffed? Try to cuff him! mode = BOT_ARREST - playsound(loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2) - target.visible_message("[src] is trying to put handcuffs on [target]!",\ - "[src] is trying to put handcuffs on [target]!") - + playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) + target.visible_message("[src] is trying to put zipties on [target]!",\ + "[src] is trying to put zipties on [target]!") spawn(30) if( !Adjacent(target) || !isturf(target.loc) ) //if he's in a closet or not adjacent, we cancel cuffing. return if(!target.handcuffed) - target.handcuffed = new /obj/item/weapon/handcuffs(target) - target.update_inv_handcuffed(0) //update the handcuffs overlay + target.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(target) + target.update_inv_handcuffed(1) //update the handcuffs overlay back_to_idle() else back_to_idle() diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm index fecf5cdcb26..a612560ff80 100644 --- a/code/game/machinery/bots/secbot.dm +++ b/code/game/machinery/bots/secbot.dm @@ -286,15 +286,15 @@ Auto Patrol: []"}, if(!arrest_type) if(!target.handcuffed) //he's not cuffed? Try to cuff him! mode = BOT_ARREST - playsound(loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2) - target.visible_message("[src] is trying to put handcuffs on [target]!",\ - "[src] is trying to put handcuffs on [target]!") - spawn(60) + playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) + target.visible_message("[src] is trying to put zipties on [target]!",\ + "[src] is trying to put zipties on [target]!") + spawn(30) if( !Adjacent(target) || !isturf(target.loc) ) //if he's in a closet or not adjacent, we cancel cuffing. return if(!target.handcuffed) - target.handcuffed = new /obj/item/weapon/handcuffs(target) - target.update_inv_handcuffed(0) //update the handcuffs overlay + target.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(target) + target.update_inv_handcuffed(1) //update the handcuffs overlay playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0) back_to_idle() else diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index 3522fbf9e95..4063396f5c5 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -38,7 +38,11 @@ /obj/machinery/iv_drip/MouseDrop(over_object, src_location, over_location) ..() - if(!ishuman(usr)) + if(!ishuman(usr) && !isrobot(usr)) + return + + var/turf/T = get_turf(src) + if(!usr in range(1, T)) return if(attached) diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index a7191450c9e..6e4966f1296 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -916,7 +916,7 @@ icon_state = "sec" icon_deny = "sec-deny" req_access_txt = "1" - products = list(/obj/item/weapon/handcuffs = 8,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash = 5, + products = list(/obj/item/weapon/restraints/handcuffs = 8,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash = 5, /obj/item/weapon/reagent_containers/food/snacks/donut/normal = 12,/obj/item/weapon/storage/box/evidence = 6,/obj/item/device/flashlight/seclite = 4) contraband = list(/obj/item/clothing/glasses/sunglasses = 2,/obj/item/weapon/storage/fancy/donut_box = 2,/obj/item/device/hailer = 5) diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index c72b2338cba..c48d5e3a89c 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -151,7 +151,7 @@ if (S.chained == 1) S.chained = 0 S.slowdown = SHOES_SLOWDOWN - new /obj/item/weapon/handcuffs( src ) + new /obj/item/weapon/restraints/handcuffs( src ) S.icon_state = new_shoe_icon_state S._color = _color S.name = new_shoe_name diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 21179bd93dd..f523e2fef1e 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -465,13 +465,13 @@ if(slot_handcuffed) if(H.handcuffed) return 0 - if(!istype(src, /obj/item/weapon/handcuffs)) + if(!istype(src, /obj/item/weapon/restraints/handcuffs)) return 0 return 1 if(slot_legcuffed) if(H.legcuffed) return 0 - if(!istype(src, /obj/item/weapon/legcuffs)) + if(!istype(src, /obj/item/weapon/restraints/legcuffs)) return 0 return 1 if(slot_in_backpack) diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index 813e9fd4517..9c0df304acd 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -1,4 +1,4 @@ -/obj/item/weapon/handcuffs +/obj/item/weapon/restraints/handcuffs name = "handcuffs" desc = "Use this to keep prisoners in line." gender = PLURAL @@ -12,132 +12,117 @@ throw_range = 5 m_amt = 500 origin_tech = "materials=1" - var/dispenser = 0 var/breakouttime = 600 //Deciseconds = 60s = 1 minutes + var/cuffsound = 'sound/weapons/handcuffs.ogg' + var/trashtype = null //For disposable cuffs -/obj/item/weapon/handcuffs/attack(mob/living/carbon/C, mob/user) +/obj/item/weapon/restraints/handcuffs/attack(mob/living/carbon/C, mob/user) if(M_CLUMSY in user.mutations && prob(50)) user << "Uh... how do those things work?!" - if(!C.handcuffed) - user.drop_item() - loc = C - C.handcuffed = src - C.update_inv_handcuffed() - return - - var/cable = 0 - if(istype(src, /obj/item/weapon/handcuffs/cable)) - cable = 1 + apply_cuffs(user,user) if(!C.handcuffed) - C.visible_message("[user] is trying to put handcuffs on [C]!", \ - "[user] is trying to put handcuffs on [C]!") - - if(cable) - playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) - else - playsound(loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2) + C.visible_message("[user] is trying to put [src.name] on [C]!", \ + "[user] is trying to put [src.name] on [C]!") + playsound(loc, cuffsound, 30, 1, -2) if(do_mob(user, C, 30)) - if(C.handcuffed) - return - user.drop_item() - loc = C - C.handcuffed = src - C.update_inv_handcuffed() - if(cable) + apply_cuffs(C,user) + user << "You handcuff [C]." + if(istype(src, /obj/item/weapon/restraints/handcuffs/cable)) feedback_add_details("handcuffs","C") else feedback_add_details("handcuffs","H") - add_logs(C, user, "handcuffed") + add_logs(user, C, "handcuffed") + else + user << "You fail to handcuff [C]." + +/obj/item/weapon/restraints/handcuffs/proc/apply_cuffs(mob/living/carbon/target, mob/user) + if(!target.handcuffed) + user.drop_item() + if(trashtype) + target.handcuffed = new trashtype(target) + qdel(src) + else + loc = target + target.handcuffed = src + target.update_inv_handcuffed(1) + return var/last_chew = 0 /mob/living/carbon/human/RestrainedClickOn(var/atom/A) - if (A != src) return ..() - if (last_chew + 26 > world.time) return + if (A != src) + return ..() + if (last_chew + 26 > world.time) + return var/mob/living/carbon/human/H = A - if (!H.handcuffed) return - if (H.a_intent != "harm") return - if (H.zone_sel.selecting != "mouth") return - if (H.wear_mask) return - if (istype(H.wear_suit, /obj/item/clothing/suit/straight_jacket)) return + if (!H.handcuffed) + return + if (H.a_intent != "harm") + return + if (H.zone_sel.selecting != "mouth") + return + if (H.wear_mask) + return + if (istype(H.wear_suit, /obj/item/clothing/suit/straight_jacket)) + return - var/datum/organ/external/O = H.organs_by_name[H.hand?"l_hand":"r_hand"] - if (!O) return + var/datum/organ/external/O = H.organs_by_name[H.hand ? "l_hand" : "r_hand"] + if (!O) + return - var/s = "\red [H.name] chews on \his [O.display_name]!" - H.visible_message(s, "\red You chew on your [O.display_name]!") + var/s = "[H.name] chews on \his [O.display_name]!" + H.visible_message(s, "You chew on your [O.display_name]!") H.attack_log += text("\[[time_stamp()]\] [s] ([H.ckey])") log_attack("[s] ([H.ckey])") if(O.take_damage(3,0,1,1,"teeth marks")) - H:UpdateDamageIcon() + H.UpdateDamageIcon() if(prob(10)) O.droplimb() last_chew = world.time -/obj/item/weapon/handcuffs/cable +/obj/item/weapon/restraints/handcuffs/cable name = "cable restraints" desc = "Looks like some cables tied together. Could be used to tie something up." icon_state = "cuff_red" + item_state = "coil_red" breakouttime = 300 //Deciseconds = 30s + cuffsound = 'sound/weapons/cablecuff.ogg' -/obj/item/weapon/handcuffs/cable/red +/obj/item/weapon/restraints/handcuffs/cable/red icon_state = "cuff_red" -/obj/item/weapon/handcuffs/cable/yellow +/obj/item/weapon/restraints/handcuffs/cable/yellow icon_state = "cuff_yellow" -/obj/item/weapon/handcuffs/cable/blue +/obj/item/weapon/restraints/handcuffs/cable/blue icon_state = "cuff_blue" -/obj/item/weapon/handcuffs/cable/green +/obj/item/weapon/restraints/handcuffs/cable/green icon_state = "cuff_green" -/obj/item/weapon/handcuffs/cable/pink +/obj/item/weapon/restraints/handcuffs/cable/pink icon_state = "cuff_pink" -/obj/item/weapon/handcuffs/cable/orange +/obj/item/weapon/restraints/handcuffs/cable/orange icon_state = "cuff_orange" -/obj/item/weapon/handcuffs/cable/cyan +/obj/item/weapon/restraints/handcuffs/cable/cyan icon_state = "cuff_cyan" -/obj/item/weapon/handcuffs/cable/white +/obj/item/weapon/restraints/handcuffs/cable/white icon_state = "cuff_white" - -/obj/item/weapon/handcuffs/cyborg - dispenser = 1 - -/obj/item/weapon/handcuffs/cyborg/attack(mob/living/carbon/C as mob, mob/user as mob) - if(!C.handcuffed) - var/turf/p_loc = user.loc - var/turf/p_loc_m = C.loc - playsound(src.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2) - user.visible_message("\red [user] is trying to put handcuffs on [C]!") - - if (ishuman(C)) - var/mob/living/carbon/human/H = C - if (!H.has_organ_for_slot(slot_handcuffed)) - user << "\red \The [H] needs at least two wrists before you can cuff them together!" - return - - spawn(30) - if(!C) return - if(p_loc == user.loc && p_loc_m == C.loc) - C.handcuffed = new /obj/item/weapon/handcuffs(C) - C.update_inv_handcuffed() - -/obj/item/weapon/handcuffs/pinkcuffs +/obj/item/weapon/restraints/handcuffs/pinkcuffs name = "fluffy pink handcuffs" desc = "Use this to keep prisoners in line. Or you know, your significant other." icon_state = "pinkcuffs" -/obj/item/weapon/handcuffs/cable/attackby(var/obj/item/I, mob/user as mob) +/obj/item/weapon/restraints/handcuffs/cable/attackby(var/obj/item/I, mob/user as mob) ..() if(istype(I, /obj/item/stack/rods)) var/obj/item/stack/rods/R = I @@ -146,7 +131,92 @@ var/last_chew = 0 user.u_equip(src) user.put_in_hands(W) user << "You wrap the cable restraint around the top of the rod." - del(src) + qdel(src) else user << "You need one rod to make a wired rod." return + +/obj/item/weapon/restraints/handcuffs/cable/zipties + name = "zipties" + desc = "Plastic, disposable zipties that can be used to restrain temporarily but are destroyed after use." + icon_state = "cuff_white" + breakouttime = 450 //Deciseconds = 45s + trashtype = /obj/item/weapon/restraints/handcuffs/cable/zipties/used + +/obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg/attack(mob/living/carbon/C, mob/user) + if(isrobot(user)) + if(!C.handcuffed) + playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) + C.visible_message("[user] is trying to put zipties on [C]!", \ + "[user] is trying to put zipties on [C]!") + if(do_mob(user, C, 30)) + if(!C.handcuffed) + C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C) + C.update_inv_handcuffed(1) + user << "You handcuff [C]." + add_logs(user, C, "handcuffed") + else + user << "You fail to handcuff [C]." + +/obj/item/weapon/restraints/handcuffs/cable/zipties/used/attack() + return + +//Legcuffs +/obj/item/weapon/restraints/legcuffs + name = "leg cuffs" + desc = "Use this to keep prisoners in line." + gender = PLURAL + icon = 'icons/obj/items.dmi' + icon_state = "handcuff" + flags = CONDUCT + throwforce = 0 + w_class = 3.0 + origin_tech = "materials=1" + slowdown = 7 + var/breakouttime = 300 //Deciseconds = 30s = 0.5 minute + +/obj/item/weapon/restraints/legcuffs/beartrap + name = "bear trap" + throw_speed = 1 + throw_range = 1 + icon_state = "beartrap0" + desc = "A trap used to catch bears and other legged creatures." + var/armed = 0 + +/obj/item/weapon/restraints/legcuffs/beartrap/suicide_act(mob/user) + user.visible_message("[user] is sticking \his head in the [src.name]! It looks like \he's trying to commit suicide.") + playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1) + return (BRUTELOSS) + +/obj/item/weapon/restraints/legcuffs/beartrap/attack_self(mob/user as mob) + ..() + if(ishuman(user) && !user.stat && !user.restrained()) + armed = !armed + icon_state = "beartrap[armed]" + user << "[src] is now [armed ? "armed" : "disarmed"]" + +/obj/item/weapon/restraints/legcuffs/beartrap/Crossed(AM as mob|obj) + if(armed && isturf(src.loc)) + if( (iscarbon(AM) || isanimal(AM)) && !istype(AM, /mob/living/simple_animal/parrot) && !istype(AM, /mob/living/simple_animal/construct) && !istype(AM, /mob/living/simple_animal/shade) && !istype(AM, /mob/living/simple_animal/hostile/viscerator)) + var/mob/living/L = AM + armed = 0 + icon_state = "beartrap0" + playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) + L.visible_message("[L] triggers \the [src].", \ + "You trigger \the [src]!") + + if(ishuman(AM)) + var/mob/living/carbon/H = AM + if(H.lying) + H.apply_damage(20,BRUTE,"chest") + else + H.apply_damage(20,BRUTE,(pick("l_leg", "r_leg"))) + if(!H.legcuffed) //beartrap can't cuff you leg if there's already a beartrap or legcuffs. + H.legcuffed = src + src.loc = H + H.update_inv_legcuffed(0) + feedback_add_details("handcuffs","B") //Yes, I know they're legcuffs. Don't change this, no need for an extra variable. The "B" is used to tell them apart. + + else + L.apply_damage(20,BRUTE) + ..() diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index eb7bc3fb8d6..938f9da5e72 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -110,7 +110,7 @@ "/obj/item/weapon/grenade/flashbang", "/obj/item/weapon/grenade/chem_grenade/teargas", "/obj/item/weapon/reagent_containers/spray/pepper", - "/obj/item/weapon/handcuffs", + "/obj/item/weapon/restraints/handcuffs", "/obj/item/device/flash", "/obj/item/clothing/glasses", "/obj/item/ammo_casing/shotgun", @@ -413,7 +413,7 @@ new /obj/item/device/multitool(src) new /obj/item/stack/cable_coil(src) - new /obj/item/weapon/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) new /obj/item/weapon/dnainjector/xraymut(src) new /obj/item/weapon/dnainjector/firemut(src) new /obj/item/weapon/dnainjector/telemut(src) diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 628d287e7c5..9d4e083a6f9 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -445,13 +445,13 @@ New() ..() - new /obj/item/weapon/handcuffs(src) - new /obj/item/weapon/handcuffs(src) - new /obj/item/weapon/handcuffs(src) - new /obj/item/weapon/handcuffs(src) - new /obj/item/weapon/handcuffs(src) - new /obj/item/weapon/handcuffs(src) - new /obj/item/weapon/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) /obj/item/weapon/storage/box/fakesyndiesuit name = "boxed space suit and helmet" diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 9691f3213ba..747fc89183e 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -118,7 +118,7 @@ item_state = "cutters_yellow" /obj/item/weapon/wirecutters/attack(mob/living/carbon/C as mob, mob/user as mob) - if((C.handcuffed) && (istype(C.handcuffed, /obj/item/weapon/handcuffs/cable))) + if((C.handcuffed) && (istype(C.handcuffed, /obj/item/weapon/restraints/handcuffs/cable))) usr.visible_message("\The [usr] cuts \the [C]'s restraints with \the [src]!",\ "You cut \the [C]'s restraints with \the [src]!",\ "You hear cable being cut.") diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 282afb599e2..97e17507472 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -240,7 +240,7 @@ new /obj/item/weapon/storage/belt/security(src) new /obj/item/weapon/grenade/flashbang(src) new /obj/item/device/flash(src) - new /obj/item/weapon/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) new /obj/item/weapon/melee/baton/loaded(src) new /obj/item/clothing/glasses/sunglasses(src) new /obj/item/clothing/glasses/hud/health_advanced diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm index f1322e17ad3..bb18855ece2 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm @@ -1,4 +1,5 @@ //Alium nests. Essentially beds with an unbuckle delay that only aliums can buckle mobs to. +#define NEST_RESIST_TIME 1200 /obj/structure/stool/bed/nest name = "alien nest" @@ -16,15 +17,20 @@ "[user.name] pulls you free from the gelatinous resin.",\ "You hear squelching...") buckled_mob.pixel_y = 0 + buckled_mob.old_y = 0 unbuckle() else + if(world.time <= buckled_mob.last_special+NEST_RESIST_TIME) + return buckled_mob.visible_message(\ "[buckled_mob.name] struggles to break free of the gelatinous resin...",\ "You struggle to break free from the gelatinous resin...",\ "You hear squelching...") - spawn(600) + spawn(NEST_RESIST_TIME) if(user && buckled_mob && user.buckled == src) + buckled_mob.last_special = world.time buckled_mob.pixel_y = 0 + buckled_mob.old_y = 0 unbuckle() src.add_fingerprint(user) return @@ -70,8 +76,7 @@ var/aforce = W.force health = max(0, health - aforce) playsound(loc, 'sound/effects/attackblob.ogg', 100, 1) - for(var/mob/M in viewers(src, 7)) - M.show_message("[user] hits [src] with [W]!", 1) + visible_message("[user] hits [src] with [W]!", 1) healthcheck() /obj/structure/stool/bed/nest/proc/healthcheck() diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index c5f21844bcc..be27e8b22d3 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1746,7 +1746,7 @@ stampvalue = input(src.owner, "What should the stamp say?", "Stamp Text") as text|null else stamptype = "" - sendername = input(src.owner, "What organization does the fax come from? This determines the prefix of the paper (i.e. CentCom- Title).", "Stamp Organization") as text|null + sendername = input(src.owner, "What organization does the fax come from? This determines the prefix of the paper (i.e. Central Command- Title).", "Organization") as text|null if(sender) notify = alert(src.owner, "Would you like to inform the original sender that a fax has arrived?","Notify Sender","Yes","No") diff --git a/code/modules/clothing/shoes/colour.dm b/code/modules/clothing/shoes/colour.dm index ad1ebc9a96d..2b64c59906b 100644 --- a/code/modules/clothing/shoes/colour.dm +++ b/code/modules/clothing/shoes/colour.dm @@ -93,13 +93,13 @@ if (src.chained) src.chained = null src.slowdown = SHOES_SLOWDOWN - new /obj/item/weapon/handcuffs( user.loc ) + new /obj/item/weapon/restraints/handcuffs( user.loc ) src.icon_state = "orange" return /obj/item/clothing/shoes/orange/attackby(H as obj, loc) ..() - if ((istype(H, /obj/item/weapon/handcuffs) && !( src.chained ))) + if ((istype(H, /obj/item/weapon/restraints/handcuffs) && !( src.chained ))) //H = null if (src.icon_state != "orange") return del(H) diff --git a/code/modules/clothing/spacesuits/alien.dm b/code/modules/clothing/spacesuits/alien.dm index d1d9962393b..f697432485f 100644 --- a/code/modules/clothing/spacesuits/alien.dm +++ b/code/modules/clothing/spacesuits/alien.dm @@ -83,7 +83,7 @@ // Can't be equipped by any other species due to bone structure and vox cybernetics. /obj/item/clothing/suit/space/vox w_class = 3 - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank) + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank) slowdown = 2 armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) siemens_coefficient = 0.6 @@ -259,7 +259,7 @@ /obj/item/clothing/suit/space/plasmaman w_class = 3 - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box/magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank) + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box/magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank) slowdown = 2 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 0) heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS diff --git a/code/modules/clothing/spacesuits/captain.dm b/code/modules/clothing/spacesuits/captain.dm index 62d21b3688d..fc25ace5154 100644 --- a/code/modules/clothing/spacesuits/captain.dm +++ b/code/modules/clothing/spacesuits/captain.dm @@ -20,7 +20,7 @@ permeability_coefficient = 0.02 flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE | ONESIZEFITSALL body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS - allowed = list(/obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy, /obj/item/weapon/gun/projectile, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs) + allowed = list(/obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy, /obj/item/weapon/gun/projectile, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs) slowdown = 1.5 armor = list(melee = 65, bullet = 50, laser = 50, energy = 25, bomb = 50, bio = 100, rad = 50) flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT||HIDETAIL diff --git a/code/modules/clothing/spacesuits/ert.dm b/code/modules/clothing/spacesuits/ert.dm index 1dd56938504..0d39a13a7b1 100644 --- a/code/modules/clothing/spacesuits/ert.dm +++ b/code/modules/clothing/spacesuits/ert.dm @@ -28,7 +28,7 @@ icon_state = "ert_commander" item_state = "suit-command" w_class = 3 - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank) + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank) slowdown = 1 armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 60) allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank, /obj/item/device/t_scanner, /obj/item/weapon/rcd, /obj/item/weapon/crowbar, \ diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index b47cca56802..75d24d2d781 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -14,7 +14,7 @@ icon_state = "caparmor" item_state = "capspacesuit" w_class = 4 - allowed = list(/obj/item/weapon/tank, /obj/item/device/flashlight,/obj/item/weapon/gun/energy, /obj/item/weapon/gun/projectile, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs) + allowed = list(/obj/item/weapon/tank, /obj/item/device/flashlight,/obj/item/weapon/gun/energy, /obj/item/weapon/gun/projectile, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs) slowdown = 1 armor = list(melee = 65, bullet = 50, laser = 50, energy = 25, bomb = 50, bio = 100, rad = 50) siemens_coefficient = 0.7 @@ -35,7 +35,7 @@ desc = "A heavily armored, advanced space suit that protects against most forms of damage." icon_state = "deathsquad" item_state = "swat_suit" - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank) + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank) armor = list(melee = 80, bullet = 80, laser = 50,energy = 50, bomb = 100, bio = 100, rad = 100) slowdown = 1 max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT @@ -92,7 +92,7 @@ icon_state = "pirate" item_state = "pirate" w_class = 3 - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank) + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank) slowdown = 0 armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) siemens_coefficient = 0.9 diff --git a/code/modules/clothing/spacesuits/ninja.dm b/code/modules/clothing/spacesuits/ninja.dm index b1b51684ee0..34df11c3f2c 100644 --- a/code/modules/clothing/spacesuits/ninja.dm +++ b/code/modules/clothing/spacesuits/ninja.dm @@ -14,7 +14,7 @@ desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins." icon_state = "s-ninja" item_state = "s-ninja_suit" - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank,/obj/item/weapon/stock_parts/cell,/obj/item/device/suit_cooling_unit) + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank,/obj/item/weapon/stock_parts/cell,/obj/item/device/suit_cooling_unit) slowdown = 0 unacidable = 1 armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) diff --git a/code/modules/clothing/spacesuits/rig.dm b/code/modules/clothing/spacesuits/rig.dm index ce7e86c94ca..4c593b49866 100644 --- a/code/modules/clothing/spacesuits/rig.dm +++ b/code/modules/clothing/spacesuits/rig.dm @@ -398,7 +398,7 @@ slowdown = 1 w_class = 3 armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 50) - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box/magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank) + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box/magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank) siemens_coefficient = 0.6 species_restricted = list("exclude","Unathi","Tajaran","Skrell","Vox") sprite_sheets = null @@ -469,7 +469,7 @@ desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor." item_state = "sec_hardsuit" armor = list(melee = 30, bullet = 15, laser = 30, energy = 10, bomb = 10, bio = 100, rad = 50) - allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/melee/baton,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/handcuffs) + allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/melee/baton,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/restraints/handcuffs) siemens_coefficient = 0.7 diff --git a/code/modules/clothing/spacesuits/syndi.dm b/code/modules/clothing/spacesuits/syndi.dm index a7797fcdc48..894e9ed1cf1 100644 --- a/code/modules/clothing/spacesuits/syndi.dm +++ b/code/modules/clothing/spacesuits/syndi.dm @@ -14,7 +14,7 @@ item_state = "space_suit_syndicate" desc = "Has a tag on it: Totally not property of of a hostile corporation, honest!" w_class = 3 - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank) + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank) slowdown = 1 armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) siemens_coefficient = 0.8 diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index d92dabb8535..217f35eb4ed 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -1,6 +1,6 @@ /obj/item/clothing/suit/armor - allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/device/flashlight/seclite,/obj/item/weapon/melee/telebaton) + allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/device/flashlight/seclite,/obj/item/weapon/melee/telebaton) body_parts_covered = UPPER_TORSO|LOWER_TORSO flags = FPRINT | TABLEPASS cold_protection = UPPER_TORSO|LOWER_TORSO @@ -147,7 +147,7 @@ item_state = "armor" blood_overlay_type = "armor" flags = FPRINT | TABLEPASS | ONESIZEFITSALL - allowed = list(/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/device/flashlight,/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/device/detective_scanner,/obj/item/device/taperecorder) + allowed = list(/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/device/flashlight,/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/device/detective_scanner,/obj/item/device/taperecorder) //Reactive armor @@ -199,7 +199,7 @@ item_state = "centcom" w_class = 4//bulky item body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS - allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank/emergency_oxygen) + allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank/emergency_oxygen) flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index 7f4b11ef8b2..6972095334d 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -132,7 +132,7 @@ item_state = "det_suit" blood_overlay_type = "coat" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS - allowed = list(/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/device/flashlight,/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/device/detective_scanner,/obj/item/device/taperecorder) + allowed = list(/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/device/flashlight,/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/device/detective_scanner,/obj/item/device/taperecorder) armor = list(melee = 50, bullet = 10, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0) cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS @@ -148,7 +148,7 @@ desc = "A forensics technician jacket." item_state = "det_suit" body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS - allowed = list(/obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy,/obj/item/weapon/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/device/detective_scanner,/obj/item/device/taperecorder) + allowed = list(/obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy,/obj/item/weapon/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/device/detective_scanner,/obj/item/device/taperecorder) armor = list(melee = 10, bullet = 10, laser = 15, energy = 10, bomb = 0, bio = 0, rad = 0) /obj/item/clothing/suit/storage/forensics/red diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index 4896840ab1e..c50030e5a86 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -94,7 +94,7 @@ /obj/item/clothing/suit/bomb_suit/security icon_state = "bombsuitsec" item_state = "bombsuitsec" - allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs) + allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs) /* * Radiation protection diff --git a/code/modules/events/event_manager.dm b/code/modules/events/event_manager.dm index caff07fb8cc..604a4007ab9 100644 --- a/code/modules/events/event_manager.dm +++ b/code/modules/events/event_manager.dm @@ -3,6 +3,7 @@ var/window_y = 600 var/report_at_round_end = 0 var/table_options = " align='center'" + var/head_options = " style='font-weight:bold;'" var/row_options1 = " width='85px'" var/row_options2 = " width='260px'" var/row_options3 = " width='150px'" @@ -87,7 +88,7 @@ html += "
" html += "

Available [severity_to_string[selected_event_container.severity]] Events (queued & running events will not be displayed)

" html += "" - html += "Name Weight MinWeight MaxWeight OneShot Enabled CurrWeight Remove" + html += "Name Weight MinWeight MaxWeight OneShot Enabled CurrWeight Remove" for(var/datum/event_meta/EM in selected_event_container.available_events) html += "" html += "[EM.name]" @@ -105,7 +106,7 @@ html += "
" html += "

Add Event

" html += "" - html += "NameTypeWeightOneShot" + html += "NameTypeWeightOneShot" html += "" html += "[new_event.name ? new_event.name : "Enter Event"]" html += "[new_event.event_type ? new_event.event_type : "Select Type"]" @@ -121,7 +122,7 @@ html += "

Event Start

" html += "" - html += "SeverityStarts AtStarts InAdjust StartPauseInterval Mod" + html += "SeverityStarts AtStarts InAdjust StartPauseInterval Mod" for(var/severity = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR) var/datum/event_container/EC = event_containers[severity] var/next_event_at = max(0, EC.next_event_time - world.time) @@ -148,7 +149,7 @@ html += "
" html += "

Next Event

" html += "" - html += "SeverityNameEvent RotationClear" + html += "SeverityNameEvent RotationClear" for(var/severity = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR) var/datum/event_container/EC = event_containers[severity] var/datum/event_meta/EM = EC.next_event @@ -165,7 +166,7 @@ html += "

Running Events

" html += "Estimated times, affected by master controller delays." html += "" - html += "SeverityNameEnds AtEnds InStop" + html += "SeverityNameEnds AtEnds InStop" for(var/datum/event/E in active_events) if(!E.event_meta) continue diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index f763179550e..cf5f2cedea5 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -130,7 +130,7 @@ //handcuffed? if(handcuffed) - if(istype(handcuffed, /obj/item/weapon/handcuffs/cable)) + if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/cable)) msg += "[t_He] [t_is] \icon[handcuffed] restrained with cable!\n" else msg += "[t_He] [t_is] \icon[handcuffed] handcuffed!\n" diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 4b9f4f1e107..5745751e219 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -918,7 +918,7 @@ proc/get_damage_icon_part(damage_state, body_part) var/obj/screen/inventory/L = hud_used.adding[8] R.overlays += image("icon"='icons/mob/screen_gen.dmi', "icon_state"="markus") L.overlays += image("icon"='icons/mob/screen_gen.dmi', "icon_state"="gabrielle") - if(istype(handcuffed, /obj/item/weapon/handcuffs/pinkcuffs)) + if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/pinkcuffs)) overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "pinkcuff1") else overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff1") diff --git a/code/modules/mob/living/carbon/monkey/inventory.dm b/code/modules/mob/living/carbon/monkey/inventory.dm index cfb4029609f..1ce1c4019a9 100644 --- a/code/modules/mob/living/carbon/monkey/inventory.dm +++ b/code/modules/mob/living/carbon/monkey/inventory.dm @@ -164,7 +164,7 @@ W.layer = initial(W.layer) W.add_fingerprint(source) else - if (istype(item, /obj/item/weapon/handcuffs)) + if (istype(item, /obj/item/weapon/restraints/handcuffs)) source.drop_item() target.handcuffed = item item.loc = target diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 737a44342b0..de1cd283e44 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -658,8 +658,8 @@ CM.handcuffed = null CM.update_inv_handcuffed() else - var/obj/item/weapon/handcuffs/HC = CM.handcuffed - var/breakouttime = 1200 //A default in case you are somehow handcuffed with something that isn't an obj/item/weapon/handcuffs type + var/obj/item/weapon/restraints/handcuffs/HC = CM.handcuffed + var/breakouttime = 1200 //A default in case you are somehow handcuffed with something that isn't an obj/item/weapon/restraints/handcuffs type var/displaytime = 2 //Minutes to display in the "this will take X minutes." if(istype(HC)) //If you are handcuffed with actual handcuffs... Well what do I know, maybe someone will want to handcuff you with toilet paper in the future... breakouttime = HC.breakouttime @@ -695,7 +695,7 @@ CM.legcuffed = null CM.update_inv_legcuffed() else - var/obj/item/weapon/legcuffs/HC = CM.legcuffed + var/obj/item/weapon/restraints/legcuffs/HC = CM.legcuffed var/breakouttime = 1200 //A default in case you are somehow legcuffed with something that isn't an obj/item/weapon/legcuffs type var/displaytime = 2 //Minutes to display in the "this will take X minutes." if(istype(HC)) //If you are legcuffed with actual legcuffs... Well what do I know, maybe someone will want to legcuff you with toilet paper in the future... diff --git a/code/modules/mob/living/silicon/mommi/mommi.dm b/code/modules/mob/living/silicon/mommi/mommi.dm index 9151be4369c..b6e508d9d3a 100644 --- a/code/modules/mob/living/silicon/mommi/mommi.dm +++ b/code/modules/mob/living/silicon/mommi/mommi.dm @@ -149,7 +149,7 @@ They can only use one tool at a time, they can't choose modules, and they have 1 name = real_name /mob/living/silicon/robot/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do + if (istype(W, /obj/item/weapon/restraints/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do return if (istype(W, /obj/item/weapon/weldingtool)) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 1b8e68dfd79..dbbf6744701 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -643,7 +643,7 @@ /mob/living/silicon/robot/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do + if (istype(W, /obj/item/weapon/restraints/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do return if(opened) // Are they trying to insert something? diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 92a8f1fd557..7a14f816197 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -220,7 +220,7 @@ New() src.modules += new /obj/item/device/flashlight/seclite(src) src.modules += new /obj/item/device/flash/cyborg(src) - src.modules += new /obj/item/weapon/handcuffs/cyborg(src) + src.modules += new /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg(src) src.modules += new /obj/item/weapon/melee/baton/robot(src) src.modules += new /obj/item/weapon/gun/energy/disabler/cyborg(src) src.modules += new /obj/item/taperoll/police(src) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 3b8c12cc5dc..d2d705ee960 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -399,13 +399,13 @@ var/list/slot_equipment_priority = list( \ if(slot_handcuffed) if(H.handcuffed) return 0 - if(!istype(src, /obj/item/weapon/handcuffs)) + if(!istype(src, /obj/item/weapon/restraints/handcuffs)) return 0 return 1 if(slot_legcuffed) if(H.legcuffed) return 0 - if(!istype(src, /obj/item/weapon/legcuffs)) + if(!istype(src, /obj/item/weapon/restraints/legcuffs)) return 0 return 1 if(slot_in_backpack) diff --git a/code/modules/paperwork/fax.dm b/code/modules/paperwork/fax.dm index 6969db88604..b8bc551deb7 100644 --- a/code/modules/paperwork/fax.dm +++ b/code/modules/paperwork/fax.dm @@ -35,7 +35,7 @@ var/list/adminfaxes = list() html += "
" html += "

Admin Faxes

" html += "" - html += "" + html += "" for(var/datum/fax/admin/A in adminfaxes) html += "" html += "" @@ -63,7 +63,7 @@ var/list/adminfaxes = list() html += "
" html += "

Departmental Faxes

" html += "
NameFrom DepartmentTo DepartmentSent ByViewReplyOriginal
NameFrom DepartmentTo DepartmentSent ByViewReplyReplied To
[A.name]
" - html += "" + html += "" for(var/datum/fax/F in faxes) html += "" html += "" diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index c688127ad2b..ea0e85080d6 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -270,7 +270,7 @@ if(src.amount <= 14) usr << "\red You need at least 15 lengths to make restraints!" return - var/obj/item/weapon/handcuffs/cable/B = new /obj/item/weapon/handcuffs/cable(usr.loc) + var/obj/item/weapon/restraints/handcuffs/cable/B = new /obj/item/weapon/restraints/handcuffs/cable(usr.loc) B.icon_state = "cuff_[_color]" usr << "\blue You wind some cable together to make some restraints." src.use(15) diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index a129dde7472..5620f5dcd7a 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -440,7 +440,7 @@ id = "handcuffs" build_type = AUTOLATHE materials = list("$metal" = 500) - build_path = /obj/item/weapon/handcuffs + build_path = /obj/item/weapon/restraints/handcuffs category = list("hacked", "Security") /datum/design/incendiary_slug diff --git a/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm b/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm index d770c0def1d..566e2382947 100644 --- a/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm +++ b/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm @@ -51,7 +51,7 @@ /obj/item/weapon/stock_parts/cell,\ /obj/item/weapon/circular_saw,\ /obj/item/weapon/hatchet,\ - /obj/item/weapon/handcuffs,\ + /obj/item/weapon/restraints/handcuffs,\ /obj/item/weapon/hemostat,\ /obj/item/weapon/kitchenknife,\ /obj/item/weapon/lighter,\ diff --git a/code/modules/research/xenoarchaeology/finds/finds.dm b/code/modules/research/xenoarchaeology/finds/finds.dm index e2b4215128b..6b07fbb16a9 100644 --- a/code/modules/research/xenoarchaeology/finds/finds.dm +++ b/code/modules/research/xenoarchaeology/finds/finds.dm @@ -183,12 +183,12 @@ apply_image_decorations = 1 if(8) item_type = "handcuffs" - new_item = new /obj/item/weapon/handcuffs(src.loc) + new_item = new /obj/item/weapon/restraints/handcuffs(src.loc) additional_desc = "[pick("They appear to be for securing two things together","Looks kinky","Doesn't seem like a children's toy")]." if(9) item_type = "[pick("wicked","evil","byzantine","dangerous")] looking [pick("device","contraption","thing","trap")]" apply_prefix = 0 - new_item = new /obj/item/weapon/legcuffs/beartrap(src.loc) + new_item = new /obj/item/weapon/restraints/legcuffs/beartrap(src.loc) additional_desc = "[pick("It looks like it could take a limb off",\ "Could be some kind of animal trap",\ "There appear to be [pick("dark red","dark purple","dark green","dark blue")] stains along part of it")]." diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index 9d85238456b3c67cf18d38e2b7e00c1745211b54..b85721bcc271505cbf3a819cc39874770875a10c 100644 GIT binary patch delta 3116 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 delta 2828 zcmV+n3-k2V^aQ!`1dt?uzj{&+%6b+N-@t z(x&Yma#^&y=mIVF4+M_H8L`$#T1w-I^Ywce+i}tiM0Jf^THukCI21)ve%t)<<*%>b zo6q0Au6D?Yf^Y7d_rG1Qt|l_sHuufD+trmt>TRC?lQLv%?wdD%J$3ob>dFwO=DxXE zU3Clt&i{S}-H51L5%sP}rOe=ajEo6=d4Ur{R1qR_5jE&&hrItsL~E7D7K>P?fsGB$ zAYa$OWv9{*9r&yv;ijzmoGx$foNlFb1S4Na1hZM#lJ_s2;mcwQejQH$8Tp+M{z}lCeD_dKntYmmR9du2X@*_rk^MJqYbj zmU3As0uN)?r6TA@?GV^dTG-X?(>c6ZpJ(6*8Z{(a&ecbM@}?X%C-%02y{lkvuB#SN zwTilBl<6J@R9h;a^c?mUhCz_ITH2zrfy=?xf(H*mOhrUjWFINUAfv*<0^dK2#`Uv^ zbky67yy=T3PUL3E&MR=)xhJwl?OsmSsMT^(qLzax=aNiLPztdUahV*do*~KXZZvR2 z!BHWHn<<2U@^#ZYNJ&k^!nKw$2EA1gI19D}twSL@gM)}f4NB;VBtIEpEgppH0# zqU-zw$C0BTAWr-bFcoy`Bo$EWMvP2e;EiMvvn+&WbifSdT=_#C?kpKR-y?d=S+Ir)oe^UT z6OyyO`}W+q^AeJvZ#a=zzs8ow&u6e;3jGAX zuYvDs;14zMM?v*(l;$wCAee3oxsDhWK4kL!NXd$Z+%HASgF*)xA6jrOc-2bojAsHP zr!478o@B~?4-iF=U|5?1M1yV=B*PRSroA^LubP%imJ>RVr$4`xKitffzg7;D;If=G zZ+{J2LHCSCMJs7Zz_o(@Ali`2C8CA_8B`Dq$7fU!`L4V;UGZ|ED;`9i*o9PhcYf_0 z{*zGz6Mx_^?Z{xzPrX$8f+l+WRndw8%YQ(Fq(}2xEqX;epEcEt*=7mhWRA6f zfyd?d=5znO9K%J5s5(Y`lvLD%tZCALyiyiH@OUt@8ORCQd01DY{UA|cqYuv1Sm=W@ zHTn;;%o-C%kqRqwl+_qHNL1J$4!*_$aqu9~|S;@~f)>=^Wy(szpP zODQ}H;!CMKhU+Et%@YshfCXiF9~?opO7w!^aY`DJWPbQJjDC^(uzLQ(xb=&l$1$eh zLGrV+fjs$M?ZT)RA9xn5y=}gH|J;23_6v3OAI_(B9uRWRz=QJzxAO%7ZXf~@$+u%B z0i+EVAxIe=?F#fE2tv>j66gaE1VIo4K?pXL@c|uw{W9T?j&}8UPo`sa&P=i<@q;_Q zAP9mW40U{-hN8D0UxnR2!V*8Y<6GxlIT_Eqy@&MEQYo)*7f~n(y&$6?1tDKmsbQ*+QWM z_S6!8@K%vR&!v};q6aOQ2wqGMB8V8$URsZZim`{Hlo|>iM({A{iY>U3(3TpSVvsEj z)Pt;t&1`luvrBh&=6!c|z8?s?n@#$AUly8&XWx0&_Wo_W{(j*#J2|GQxh36syiKV=7|46UDJFTg?rPS5|06-FdVijPf3aw`HQfM_}d;hjx|JlhgU2*RQ zzqxmB{cgG9>A43FQ_FwS?pvIR$mEmX?fC$b#UXrT#ufLj&U|yL{>R1fu1hN`_2)=Qls<4472A8q)Eu>(`A>G)434TWIGXAjy0!y{oF zuH3&tw)YPpIkB&ToPOtxz~h-8Zg#vF^2u-Ja%rv5SbUwFn9%w8dA<6yltQU5f92-%7Qq;b}|+Z|p#N{9H`*y@7*(oAF-}#bsV|h(Cme(Yy{;^8J2cW?j2=vA0QvdMcfIxc=Ry|uziBKt@+vfg z2cVng8^Zqcy?+47>9_zpGVK=16)$=)p#kLQGk^O~R#PIcLi0xe*q#Gr0Q=AP{sAPX zqXNu-JIYoEhWz~IH-0dGw@EE0p_5O3kLLqOPTK|8k!d${*2ZK9g#3Kx`?{tBW~lSg zG~ck69T)>65!k=o{R2o&tPa@CQus6YO#X*Je!lai+Tr_Sn}gv~QR z2H8G?#Qy1k0llK|;L(4ve(|g0`>OsdsEvE4B}r56DI-^+k)Q8>e82GWnHWDIDRK&b zlr-j#kxzaa`Mdj`ioYNL9f@6lNn3w}Z!OG7lHU9AfUyFAeDVQwh5`(*C-z4XH8ME| zihS|`0LZ#T3b0+Te7$+^R1*Ij`Q!rt(9=443sMT6OGxYN1Nr0wNFHxN0`_!VfB^uq ei2@9;=YL`}H>VX3X$VyS0000
NameFrom DepartmentTo DepartmentSent ByView
NameFrom DepartmentTo DepartmentSent ByView
[F.name]
" - html += "" + html += "" for(var/datum/fax/admin/A in adminfaxes) html += "" html += "" html += "" html += "" + html += "" if(A.sent_by) var/mob/living/S = A.sent_by html += "" @@ -63,12 +65,13 @@ var/list/adminfaxes = list() html += "
" html += "

Departmental Faxes

" html += "
NameFrom DepartmentTo DepartmentSent ByViewReplyReplied To
NameFrom DepartmentTo DepartmentSent AtSent ByViewReplyReplied To
[A.name][A.from_department][A.to_department][worldtime2text(A.sent_at)][S.name]
" - html += "" + html += "" for(var/datum/fax/F in faxes) html += "" html += "" html += "" html += "" + html += "" if(F.sent_by) var/mob/living/S = F.sent_by html += "" @@ -79,7 +82,7 @@ var/list/adminfaxes = list() html += "
NameFrom DepartmentTo DepartmentSent ByView
NameFrom DepartmentTo DepartmentSent AtSent ByView
[F.name][F.from_department][F.to_department][worldtime2text(F.sent_at)][S.name]
" html += "
" - var/datum/browser/popup = new(user, "fax_panel", "Fax Panel", 900, 450) + var/datum/browser/popup = new(user, "fax_panel", "Fax Panel", 950, 450) popup.set_content(html) popup.open() \ No newline at end of file diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index 6c7b0e30314..98726004ea4 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -190,6 +190,7 @@ var/list/alldepartments = list() F.origin = src F.message = copyitem F.sent_by = sender + F.sent_at = world.time visible_message("[src] beeps, \"Message transmitted successfully.\"") //sendcooldown = 600 @@ -247,6 +248,7 @@ var/list/alldepartments = list() A.origin = src A.message = rcvdcopy A.sent_by = sender + A.sent_at = world.time //message badmins that a fax has arrived switch(destination) From 165f8118afb3c8220c0a8882f8a05c7407bc7237 Mon Sep 17 00:00:00 2001 From: Markolie Date: Sat, 14 Feb 2015 14:54:32 +0100 Subject: [PATCH 13/13] Add box of zipties, give zipties to nuke ops and Vox raiders --- .../game/objects/items/weapons/storage/boxes.dm | 17 ++++++++++++++++- maps/cyberiad.dmm | 4 ++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 9d4e083a6f9..c33150fae7e 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -423,7 +423,7 @@ new /obj/item/weapon/card/id/prisoner/seven(src) /obj/item/weapon/storage/box/seccarts - name = "Spare R.O.B.U.S.T. Cartridges" + name = "spare R.O.B.U.S.T. Cartridges" desc = "A box full of R.O.B.U.S.T. Cartridges, used by Security." icon_state = "pda" @@ -452,6 +452,21 @@ new /obj/item/weapon/restraints/handcuffs(src) new /obj/item/weapon/restraints/handcuffs(src) new /obj/item/weapon/restraints/handcuffs(src) + +/obj/item/weapon/storage/box/zipties + name = "box of spare zipties" + desc = "A box full of zipties." + icon_state = "handcuff" + + New() + ..() + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) /obj/item/weapon/storage/box/fakesyndiesuit name = "boxed space suit and helmet" diff --git a/maps/cyberiad.dmm b/maps/cyberiad.dmm index 656c627396b..a541da06805 100644 --- a/maps/cyberiad.dmm +++ b/maps/cyberiad.dmm @@ -8199,7 +8199,7 @@ "dbI" = (/turf/space/transit/north/shuttlespace_ns8,/area/shuttle/escape_pod2/transit) "dbJ" = (/obj/structure/AIcore,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "dbK" = (/obj/item/weapon/spacecash/c200,/obj/item/weapon/spacecash/c50,/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"dbL" = (/obj/structure/jungle_plant,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) +"dbL" = (/obj/item/weapon/storage/box/zipties,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "dbM" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"},/area/syndicate_mothership) "dbN" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/syndicate_station/start) "dbO" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/syndicate_station/start) @@ -8245,7 +8245,7 @@ "dcC" = (/obj/machinery/door/airlock/centcom{name = "Study"; opacity = 1; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "dcD" = (/turf/unsimulated/floor{icon_state = "grimy"},/area/syndicate_mothership) "dcE" = (/obj/structure/table,/obj/item/stack/cable_coil,/obj/item/weapon/crowbar/red,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) -"dcF" = (/obj/structure/table,/obj/item/weapon/storage/box/handcuffs,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) +"dcF" = (/obj/structure/table,/obj/item/weapon/storage/box/zipties,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) "dcG" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/unsimulated/floor{tag = "icon-gravsnow_surround (WEST)"; icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_surround"; dir = 8},/area/syndicate_mothership) "dcH" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/unsimulated/floor{tag = "icon-gravsnow_corner (SOUTHEAST)"; icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"; dir = 6},/area/syndicate_mothership) "dcI" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/cans/beer{pixel_x = -2; pixel_y = 5},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership)