diff --git a/baystation12.dme b/baystation12.dme index 3682d724958..7031dd98066 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -632,9 +632,11 @@ #include "code\game\objects\items\weapons\circuitboards\computer\research.dm" #include "code\game\objects\items\weapons\circuitboards\computer\supply.dm" #include "code\game\objects\items\weapons\circuitboards\computer\telecomms.dm" +#include "code\game\objects\items\weapons\circuitboards\machinery\biogenerator.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\cloning.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\pacman.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\power.dm" +#include "code\game\objects\items\weapons\circuitboards\machinery\recharge_station.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\research.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\shieldgen.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\telecomms.dm" @@ -789,6 +791,7 @@ #include "code\modules\admin\verbs\debug.dm" #include "code\modules\admin\verbs\diagnostics.dm" #include "code\modules\admin\verbs\getlogs.dm" +#include "code\modules\admin\verbs\icarus.dm" #include "code\modules\admin\verbs\mapping.dm" #include "code\modules\admin\verbs\massmodvar.dm" #include "code\modules\admin\verbs\modifyvariables.dm" @@ -898,7 +901,10 @@ #include "code\modules\clothing\under\miscellaneous.dm" #include "code\modules\clothing\under\shorts.dm" #include "code\modules\clothing\under\syndicate.dm" -#include "code\modules\clothing\under\ties.dm" +#include "code\modules\clothing\under\accessories\accessory.dm" +#include "code\modules\clothing\under\accessories\armband.dm" +#include "code\modules\clothing\under\accessories\holster.dm" +#include "code\modules\clothing\under\accessories\storage.dm" #include "code\modules\clothing\under\jobs\civilian.dm" #include "code\modules\clothing\under\jobs\engineering.dm" #include "code\modules\clothing\under\jobs\medsci.dm" @@ -1147,6 +1153,7 @@ #include "code\modules\mob\living\silicon\pai\recruit.dm" #include "code\modules\mob\living\silicon\pai\say.dm" #include "code\modules\mob\living\silicon\pai\software.dm" +#include "code\modules\mob\living\silicon\pai\software_modules.dm" #include "code\modules\mob\living\silicon\robot\analyzer.dm" #include "code\modules\mob\living\silicon\robot\component.dm" #include "code\modules\mob\living\silicon\robot\death.dm" diff --git a/code/ATMOSPHERICS/components/unary/cold_sink.dm b/code/ATMOSPHERICS/components/unary/cold_sink.dm index 766279a6302..82d7d41b7b8 100644 --- a/code/ATMOSPHERICS/components/unary/cold_sink.dm +++ b/code/ATMOSPHERICS/components/unary/cold_sink.dm @@ -7,52 +7,47 @@ icon = 'icons/obj/Cryogenic2.dmi' icon_state = "freezer_0" density = 1 - - anchored = 1.0 - - var/heatsink_temperature = T20C //the constant temperature resevoir into which the freezer pumps heat. Probably the hull of the station or something. - var/internal_volume = 600 //L - + anchored = 1 use_power = 0 - idle_power_usage = 5 //5 Watts for thermostat related circuitry + idle_power_usage = 5 // 5 Watts for thermostat related circuitry - var/max_power_rating = 20000 //power rating when the usage is turned up to 100 + var/heatsink_temperature = T20C // The constant temperature reservoir into which the freezer pumps heat. Probably the hull of the station or something. + var/internal_volume = 600 // L + + var/max_power_rating = 20000 // Power rating when the usage is turned up to 100 var/power_setting = 100 - var/set_temperature = T20C //thermostat + var/set_temperature = T20C // Thermostat var/cooling = 0 - var/opened = 0 //for deconstruction /obj/machinery/atmospherics/unary/freezer/New() ..() - air_contents.volume = internal_volume initialize_directions = dir - component_parts = list() component_parts += new /obj/item/weapon/circuitboard/unary_atmos/cooler(src) component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) component_parts += new /obj/item/weapon/stock_parts/capacitor(src) component_parts += new /obj/item/weapon/stock_parts/capacitor(src) component_parts += new /obj/item/weapon/stock_parts/manipulator(src) - - power_rating = max_power_rating * (power_setting/100) + component_parts += new /obj/item/stack/cable_coil(src, 2) + RefreshParts() /obj/machinery/atmospherics/unary/freezer/initialize() - if(node) return + if(node) + return var/node_connect = dir - for(var/obj/machinery/atmospherics/target in get_step(src,node_connect)) - if(target.initialize_directions & get_dir(target,src)) + for(var/obj/machinery/atmospherics/target in get_step(src, node_connect)) + if(target.initialize_directions & get_dir(target, src)) node = target break update_icon() - /obj/machinery/atmospherics/unary/freezer/update_icon() - if(src.node) - if(src.use_power && cooling) + if(node) + if(use_power && cooling) icon_state = "freezer_1" else icon_state = "freezer" @@ -61,10 +56,10 @@ return /obj/machinery/atmospherics/unary/freezer/attack_ai(mob/user as mob) - src.ui_interact(user) + ui_interact(user) /obj/machinery/atmospherics/unary/freezer/attack_hand(mob/user as mob) - src.ui_interact(user) + ui_interact(user) /obj/machinery/atmospherics/unary/freezer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) // this is the data which will be sent to the ui @@ -78,15 +73,15 @@ data["powerSetting"] = power_setting var/temp_class = "good" - if (air_contents.temperature > (T0C - 20)) + if(air_contents.temperature > (T0C - 20)) temp_class = "bad" - else if (air_contents.temperature < (T0C - 20) && air_contents.temperature > (T0C - 100)) + else if(air_contents.temperature < (T0C - 20) && air_contents.temperature > (T0C - 100)) temp_class = "average" data["gasTemperatureClass"] = temp_class // update the ui if it exists, returns null if no ui is passed/found ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) + if(!ui) // the ui does not exist, so we'll create a new() one // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm ui = new(user, src, ui_key, "freezer.tmpl", "Gas Cooling System", 440, 300) @@ -98,30 +93,31 @@ ui.set_auto_update(1) /obj/machinery/atmospherics/unary/freezer/Topic(href, href_list) - if (href_list["toggleStatus"]) - src.use_power = !src.use_power + if(href_list["toggleStatus"]) + use_power = !use_power update_icon() if(href_list["temp"]) var/amount = text2num(href_list["temp"]) if(amount > 0) - src.set_temperature = min(src.set_temperature+amount, 1000) + set_temperature = min(set_temperature + amount, 1000) else - src.set_temperature = max(src.set_temperature+amount, 0) + set_temperature = max(set_temperature + amount, 0) if(href_list["setPower"]) //setting power to 0 is redundant anyways var/new_setting = between(0, text2num(href_list["setPower"]), 100) set_power_level(new_setting) - src.add_fingerprint(usr) + add_fingerprint(usr) return 1 /obj/machinery/atmospherics/unary/freezer/process() ..() + if(stat & (NOPOWER|BROKEN) || !use_power) cooling = 0 update_icon() return - if (network && air_contents.temperature > set_temperature) + if(network && air_contents.temperature > set_temperature) cooling = 1 var/heat_transfer = max( -air_contents.get_thermal_energy_change(set_temperature - 5), 0 ) @@ -132,7 +128,7 @@ heat_transfer = min(heat_transfer, cop * power_rating) //limit heat transfer by available power var/removed = -air_contents.add_thermal_energy(-heat_transfer) //remove the heat - if (debug) + if(debug) visible_message("[src]: Removing [removed] W.") use_power(power_rating) @@ -147,49 +143,37 @@ /obj/machinery/atmospherics/unary/freezer/RefreshParts() ..() var/cap_rating = 0 - var/cap_count = 0 var/manip_rating = 0 - var/manip_count = 0 var/bin_rating = 0 - var/bin_count = 0 for(var/obj/item/weapon/stock_parts/P in component_parts) if(istype(P, /obj/item/weapon/stock_parts/capacitor)) cap_rating += P.rating - cap_count++ if(istype(P, /obj/item/weapon/stock_parts/manipulator)) manip_rating += P.rating - manip_count++ if(istype(P, /obj/item/weapon/stock_parts/matter_bin)) bin_rating += P.rating - bin_count++ - cap_rating /= cap_count - bin_rating /= bin_count - manip_rating /= manip_count - power_rating = initial(power_rating)*cap_rating //more powerful - heatsink_temperature = initial(heatsink_temperature)/((manip_rating+bin_rating)/2) //more efficient - air_contents.volume = max(initial(internal_volume) - 200, 0) + 200*bin_rating + power_rating = initial(power_rating) * cap_rating / 2 //more powerful + heatsink_temperature = initial(heatsink_temperature) / ((manip_rating + bin_rating) / 2) //more efficient + air_contents.volume = max(initial(internal_volume) - 200, 0) + 200 * bin_rating set_power_level(power_setting) /obj/machinery/atmospherics/unary/freezer/proc/set_power_level(var/new_power_setting) power_setting = new_power_setting power_rating = max_power_rating * (power_setting/100) -//dismantling code. copied from autolathe /obj/machinery/atmospherics/unary/freezer/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(istype(O, /obj/item/weapon/screwdriver)) - opened = !opened - user << "You [opened ? "open" : "close"] the maintenance hatch of [src]." + if(default_deconstruction_screwdriver(user, O)) return - - if (opened && istype(O, /obj/item/weapon/crowbar)) - dismantle() + if(default_deconstruction_crowbar(user, O)) + return + if(default_part_replacement(user, O)) return ..() /obj/machinery/atmospherics/unary/freezer/examine(mob/user) ..(user) - if (opened) + if(panel_open) user << "The maintenance hatch is open." diff --git a/code/ATMOSPHERICS/components/unary/heat_source.dm b/code/ATMOSPHERICS/components/unary/heat_source.dm index 891a19cc74f..829f06f4202 100644 --- a/code/ATMOSPHERICS/components/unary/heat_source.dm +++ b/code/ATMOSPHERICS/components/unary/heat_source.dm @@ -7,25 +7,21 @@ icon = 'icons/obj/Cryogenic2.dmi' icon_state = "heater_0" density = 1 - - anchored = 1.0 - - var/set_temperature = T20C //thermostat - var/max_temperature = T20C + 680 - var/internal_volume = 600 //L - + anchored = 1 use_power = 0 idle_power_usage = 5 //5 Watts for thermostat related circuitry + var/max_temperature = T20C + 680 + var/internal_volume = 600 //L + var/max_power_rating = 20000 //power rating when the usage is turned up to 100 var/power_setting = 100 + var/set_temperature = T20C //thermostat var/heating = 0 //mainly for icon updates - var/opened = 0 //for deconstruction /obj/machinery/atmospherics/unary/heater/New() ..() - air_contents.volume = internal_volume initialize_directions = dir component_parts = list() @@ -33,16 +29,18 @@ component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) component_parts += new /obj/item/weapon/stock_parts/capacitor(src) component_parts += new /obj/item/weapon/stock_parts/capacitor(src) + component_parts += new /obj/item/stack/cable_coil(src, 5) - power_rating = max_power_rating * (power_setting/100) + RefreshParts() /obj/machinery/atmospherics/unary/heater/initialize() - if(node) return + if(node) + return var/node_connect = dir - for(var/obj/machinery/atmospherics/target in get_step(src,node_connect)) - if(target.initialize_directions & get_dir(target,src)) + for(var/obj/machinery/atmospherics/target in get_step(src, node_connect)) + if(target.initialize_directions & get_dir(target, src)) node = target break @@ -50,8 +48,8 @@ /obj/machinery/atmospherics/unary/heater/update_icon() - if(src.node) - if(src.use_power && src.heating) + if(node) + if(use_power && heating) icon_state = "heater_1" else icon_state = "heater" @@ -68,7 +66,7 @@ update_icon() return - if (network && air_contents.total_moles && air_contents.temperature < set_temperature) + if(network && air_contents.total_moles && air_contents.temperature < set_temperature) air_contents.add_thermal_energy(power_rating * HEATER_PERF_MULT) use_power(power_rating) @@ -80,10 +78,10 @@ update_icon() /obj/machinery/atmospherics/unary/heater/attack_ai(mob/user as mob) - src.ui_interact(user) + ui_interact(user) /obj/machinery/atmospherics/unary/heater/attack_hand(mob/user as mob) - src.ui_interact(user) + ui_interact(user) /obj/machinery/atmospherics/unary/heater/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) // this is the data which will be sent to the ui @@ -97,13 +95,13 @@ data["powerSetting"] = power_setting var/temp_class = "normal" - if (air_contents.temperature > (T20C+40)) + if(air_contents.temperature > (T20C+40)) temp_class = "bad" data["gasTemperatureClass"] = temp_class // update the ui if it exists, returns null if no ui is passed/found ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) + if(!ui) // the ui does not exist, so we'll create a new() one // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm ui = new(user, src, ui_key, "freezer.tmpl", "Gas Heating System", 440, 300) @@ -115,63 +113,54 @@ ui.set_auto_update(1) /obj/machinery/atmospherics/unary/heater/Topic(href, href_list) - if (href_list["toggleStatus"]) - src.use_power = !src.use_power + if(href_list["toggleStatus"]) + use_power = !use_power update_icon() if(href_list["temp"]) var/amount = text2num(href_list["temp"]) if(amount > 0) - src.set_temperature = min(src.set_temperature+amount, max_temperature) + set_temperature = min(set_temperature + amount, max_temperature) else - src.set_temperature = max(src.set_temperature+amount, 0) + set_temperature = max(set_temperature + amount, 0) if(href_list["setPower"]) //setting power to 0 is redundant anyways var/new_setting = between(0, text2num(href_list["setPower"]), 100) set_power_level(new_setting) - src.add_fingerprint(usr) + add_fingerprint(usr) return 1 //upgrading parts /obj/machinery/atmospherics/unary/heater/RefreshParts() ..() - var/cap_rating = 0 - var/cap_count = 0 var/bin_rating = 0 - var/bin_count = 0 + for(var/obj/item/weapon/stock_parts/P in component_parts) if(istype(P, /obj/item/weapon/stock_parts/capacitor)) cap_rating += P.rating - cap_count++ if(istype(P, /obj/item/weapon/stock_parts/matter_bin)) bin_rating += P.rating - bin_count++ - cap_rating /= cap_count - bin_rating /= bin_count - max_power_rating = initial(max_power_rating)*cap_rating - max_temperature = max(initial(max_temperature) - T20C, 0)*((bin_rating*2 + cap_rating)/3) + T20C - air_contents.volume = max(initial(internal_volume) - 200, 0) + 200*bin_rating + max_power_rating = initial(max_power_rating) * cap_rating / 2 + max_temperature = max(initial(max_temperature) - T20C, 0) * ((bin_rating * 4 + cap_rating) / 5) + T20C + air_contents.volume = max(initial(internal_volume) - 200, 0) + 200 * bin_rating set_power_level(power_setting) /obj/machinery/atmospherics/unary/heater/proc/set_power_level(var/new_power_setting) power_setting = new_power_setting power_rating = max_power_rating * (power_setting/100) -//dismantling code. copied from autolathe /obj/machinery/atmospherics/unary/heater/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(istype(O, /obj/item/weapon/screwdriver)) - opened = !opened - user << "You [opened ? "open" : "close"] the maintenance hatch of [src]." + if(default_deconstruction_screwdriver(user, O)) return - - if (opened && istype(O, /obj/item/weapon/crowbar)) - dismantle() + if(default_deconstruction_crowbar(user, O)) + return + if(default_part_replacement(user, O)) return ..() /obj/machinery/atmospherics/unary/heater/examine(mob/user) ..(user) - if (opened) + if(panel_open) user << "The maintenance hatch is open." diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 3042a6c0b1e..d96f3364a17 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -898,10 +898,9 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/item/weapon/reagent_containers/glass/paint/green, /obj/item/weapon/reagent_containers/glass/paint/blue, /obj/item/weapon/reagent_containers/glass/paint/yellow, - /obj/item/weapon/reagent_containers/glass/paint/violet, + /obj/item/weapon/reagent_containers/glass/paint/purple, /obj/item/weapon/reagent_containers/glass/paint/black, /obj/item/weapon/reagent_containers/glass/paint/white, - /obj/item/weapon/reagent_containers/glass/paint/remover, /obj/item/weapon/contraband/poster, /obj/item/weapon/wrapping_paper, /obj/item/weapon/wrapping_paper, @@ -1395,10 +1394,10 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /datum/supply_packs/randomised/webbing name = "Webbing crate" num_contained = 1 - contains = list(/obj/item/clothing/tie/holster, - /obj/item/clothing/tie/storage/brown_vest, - /obj/item/clothing/tie/storage/webbing, - /obj/item/clothing/tie/storage) + contains = list(/obj/item/clothing/accessory/holster, + /obj/item/clothing/accessory/storage/brown_vest, + /obj/item/clothing/accessory/storage/webbing, + /obj/item/clothing/accessory/storage) cost = 15 containertype = /obj/structure/closet/crate containername = "Webbing crate" diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index ab7b57cb422..634121b08c9 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -395,6 +395,22 @@ ///////////////////////////////////////Stock Parts ///////////////////////////////// +/obj/item/weapon/storage/part_replacer + name = "rapid part exchange device" + desc = "Special mechanical module made to store, sort, and apply standard machine parts." + icon_state = "RPED" + item_state = "RPED" + w_class = 5 + can_hold = list("/obj/item/weapon/stock_parts") + storage_slots = 50 + use_to_pickup = 1 + allow_quick_gather = 1 + allow_quick_empty = 1 + collection_mode = 1 + display_contents_with_number = 1 + max_w_class = 3 + max_combined_w_class = 100 + /obj/item/weapon/stock_parts name = "stock part" desc = "What?" diff --git a/code/game/atoms.dm b/code/game/atoms.dm index df288f2cc40..bd0c9cdb541 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -409,6 +409,7 @@ its easier to just keep the beam vertical. /atom/proc/clean_blood() + src.color = initial(src.color) //paint src.germ_level = 0 if(istype(blood_DNA, /list)) del(blood_DNA) diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm index fce27f393ce..1edb533daaa 100644 --- a/code/game/gamemodes/meteor/meteors.dm +++ b/code/game/gamemodes/meteor/meteors.dm @@ -85,6 +85,9 @@ density = 1 anchored = 1.0 var/hits = 1 + var/detonation_chance = 15 + var/power = 4 + var/power_step = 1 var/dest pass_flags = PASSTABLE @@ -92,6 +95,7 @@ name = "small meteor" icon_state = "smallf" pass_flags = PASSTABLE | PASSGRILLE + power = 2 /obj/effect/meteor/Bump(atom/A) spawn(0) @@ -105,8 +109,8 @@ //Changing emitter and generator ex_act would result in them being bomb and C4 proof. if(!istype(A,/obj/machinery/power/emitter) && \ !istype(A,/obj/machinery/field_generator) && \ - prob(15)) - explosion(src.loc, 4, 5, 6, 7, 0) + prob(detonation_chance)) + explosion(loc, power, power + power_step, power + power_step * 2, power + power_step * 3, 0) del(src) return @@ -120,6 +124,7 @@ /obj/effect/meteor/big name = "big meteor" hits = 5 + power = 1 ex_act(severity) return @@ -143,8 +148,8 @@ explosion(src.loc, 0, 1, 2, 3, 0) if (--src.hits <= 0) - if(prob(15) && !istype(A, /obj/structure/grille)) - explosion(src.loc, 1, 2, 3, 4, 0) + if(prob(detonation_chance) && !istype(A, /obj/structure/grille)) + explosion(loc, power, power + power_step, power + power_step * 2, power + power_step * 3, 0) del(src) return diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm index a43056fa96f..06513c05f9f 100644 --- a/code/game/jobs/job/captain.dm +++ b/code/game/jobs/job/captain.dm @@ -24,7 +24,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) var/obj/item/clothing/under/U = new /obj/item/clothing/under/rank/captain(H) if(H.age>49) - U.hastie = new /obj/item/clothing/tie/medal/gold/captain(U) + U.accessories += new /obj/item/clothing/accessory/medal/gold/captain(U) H.equip_to_slot_or_del(U, slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/device/pda/captain(H), slot_belt) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes) diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm index a63363f779c..13702911528 100644 --- a/code/game/jobs/job/medical.dm +++ b/code/game/jobs/job/medical.dm @@ -196,3 +196,44 @@ else H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/labcoat(H), slot_wear_suit) + + +/datum/job/Paramedic + title = "Paramedic" + flag = PARAMEDIC + department_flag = MEDSCI + faction = "Station" + total_positions = 2 + spawn_positions = 2 + supervisors = "the chief medical officer" + selection_color = "#ffeef0" + access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_eva, access_maint_tunnels, access_external_airlocks, access_psychiatrist) + minimal_access = list(access_medical, access_morgue, access_eva, access_maint_tunnels, access_external_airlocks) + alt_titles = list("Emergency Medical Technician") + + equip(var/mob/living/carbon/human/H) + if(!H) return 0 + H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_med(H), slot_l_ear) + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/jackboots(H), slot_shoes) + H.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/adv(H), slot_l_hand) + switch(H.backbag) + if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/medic(H), slot_back) + if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_med(H), slot_back) + if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if (H.mind.role_alt_title) + switch(H.mind.role_alt_title) + if("Emergency Medical Technician") + H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical/fluff/short(H), slot_w_uniform) + H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/fr_jacket(H), slot_wear_suit) + if("Paramedic") + H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical/black(H), slot_w_uniform) + H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/fr_jacket(H), slot_wear_suit) + else + H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical(H), slot_w_uniform) + H.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/medical/emt(H), slot_belt) + H.equip_to_slot_or_del(new /obj/item/device/pda/medical(H), slot_l_store) + if(H.backbag == 1) + H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(H), slot_r_hand) + else + H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(H.back), slot_in_backpack) + return 1 diff --git a/code/game/jobs/jobs.dm b/code/game/jobs/jobs.dm index a90f3ad716d..e1c42254a65 100644 --- a/code/game/jobs/jobs.dm +++ b/code/game/jobs/jobs.dm @@ -25,6 +25,7 @@ var/const/VIROLOGIST =(1<<6) var/const/PSYCHIATRIST =(1<<7) var/const/ROBOTICIST =(1<<8) var/const/XENOBIOLOGIST =(1<<9) +var/const/PARAMEDIC =(1<<10) var/const/CIVILIAN =(1<<2) diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 7b44e443c4d..5361bea23a7 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -13,14 +13,30 @@ var/list/storage_capacity = list("metal" = 0, "glass" = 0) var/show_category = "All" - var/panel_open = 0 var/hacked = 0 var/disabled = 0 var/shocked = 0 var/busy = 0 + var/mat_efficiency = 1 + var/build_time = 50 + var/datum/wires/autolathe/wires = null +/obj/machinery/autolathe/New() + + ..() + wires = new(src) + //Create parts for lathe. + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/autolathe(src) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + component_parts += new /obj/item/weapon/stock_parts/console_screen(src) + RefreshParts() + /obj/machinery/autolathe/proc/update_recipe_list() if(!machine_recipes) machine_recipes = autolathe_recipes @@ -33,8 +49,8 @@ user << "\The [src] is disabled!" return - if (shocked) - shock(user,50) + if(shocked) + shock(user, 50) var/dat = "

Autolathe Control Panel


" @@ -65,16 +81,16 @@ else //Make sure it's buildable and list requires resources. for(var/material in R.resources) - var/sheets = round(stored_material[material]/R.resources[material]) + var/sheets = round(stored_material[material]/round(R.resources[material]*mat_efficiency)) if(isnull(max_sheets) || max_sheets > sheets) max_sheets = sheets - if(!isnull(stored_material[material]) && stored_material[material] < R.resources[material]) + if(!isnull(stored_material[material]) && stored_material[material] < round(R.resources[material]*mat_efficiency)) can_make = 0 if(!comma) comma = 1 else material_string += ", " - material_string += "[R.resources[material]] [material]" + material_string += "[round(R.resources[material] * mat_efficiency)] [material]" material_string += ".
" //Build list of multipliers for sheets. if(R.is_stack) @@ -99,31 +115,27 @@ /obj/machinery/autolathe/attackby(var/obj/item/O as obj, var/mob/user as mob) - if (stat) - return - - if (busy) + if(busy) user << "\The [src] is busy. Please wait for completion of previous operation." return - if(istype(O, /obj/item/weapon/screwdriver)) - panel_open = !panel_open - icon_state = (panel_open ? "autolathe_t": "autolathe") - user << "You [panel_open ? "open" : "close"] the maintenance hatch of [src]." + if(default_deconstruction_screwdriver(user, O)) updateUsrDialog() return + if(default_deconstruction_crowbar(user, O)) + return + if(default_part_replacement(user, O)) + return - if (panel_open) + if(stat) + return + + if(panel_open) //Don't eat multitools or wirecutters used on an open lathe. if(istype(O, /obj/item/device/multitool) || istype(O, /obj/item/weapon/wirecutters)) attack_hand(user) return - //Dismantle the frame. - if(istype(O, /obj/item/weapon/crowbar)) - dismantle() - return - if(O.loc != user && !(istype(O,/obj/item/stack))) return 0 @@ -170,11 +182,11 @@ else user << "You fill \the [src] with \the [eating]." - flick("autolathe_o",src) // Plays metal insertion animation. Work out a good way to work out a fitting animation. ~Z + flick("autolathe_o", src) // Plays metal insertion animation. Work out a good way to work out a fitting animation. ~Z if(istype(eating,/obj/item/stack)) var/obj/item/stack/stack = eating - stack.use(max(1,round(total_used/mass_per_sheet))) // Always use at least 1 to prevent infinite materials. + stack.use(max(1, round(total_used/mass_per_sheet))) // Always use at least 1 to prevent infinite materials. else user.drop_item(O) del(O) @@ -227,18 +239,18 @@ //Check if we still have the materials. for(var/material in making.resources) if(!isnull(stored_material[material])) - if(stored_material[material] < (making.resources[material]*multiplier)) + if(stored_material[material] < round(making.resources[material] * mat_efficiency) * multiplier) return //Consume materials. for(var/material in making.resources) if(!isnull(stored_material[material])) - stored_material[material] = max(0,stored_material[material]-(making.resources[material]*multiplier)) + stored_material[material] = max(0, stored_material[material] - round(making.resources[material] * mat_efficiency) * multiplier) //Fancy autolathe animation. - flick("autolathe_n",src) + flick("autolathe_n", src) - sleep(50) + sleep(build_time) busy = 0 @@ -247,39 +259,31 @@ //Create the desired item. var/obj/item/I = new making.path(get_step(loc, get_dir(src,usr))) - if(multiplier>1 && istype(I,/obj/item/stack)) + if(multiplier > 1 && istype(I, /obj/item/stack)) var/obj/item/stack/S = I S.amount = multiplier updateUsrDialog() - -/obj/machinery/autolathe/New() - - ..() - wires = new(src) - //Create parts for lathe. - component_parts = list() - component_parts += new /obj/item/weapon/circuitboard/autolathe(src) - component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) - component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) - component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) - component_parts += new /obj/item/weapon/stock_parts/manipulator(src) - component_parts += new /obj/item/weapon/stock_parts/console_screen(src) - RefreshParts() +/obj/machinery/autolathe/update_icon() + icon_state = (panel_open ? "autolathe_t" : "autolathe") //Updates overall lathe storage size. /obj/machinery/autolathe/RefreshParts() ..() - var/tot_rating = 0 + var/mb_rating = 0 + var/man_rating = 0 for(var/obj/item/weapon/stock_parts/matter_bin/MB in component_parts) - tot_rating += MB.rating + mb_rating += MB.rating + for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) + man_rating += M.rating - storage_capacity["metal"] = tot_rating * 25000 - storage_capacity["glass"] = tot_rating * 12500 + storage_capacity["metal"] = mb_rating * 25000 + storage_capacity["glass"] = mb_rating * 12500 + build_time = 50 / man_rating + mat_efficiency = 1.1 - man_rating * 0.1// Normally, price is 1.25 the amount of material, so this shouldn't go higher than 0.8. Maximum rating of parts is 3 /obj/machinery/autolathe/dismantle() - ..() var/list/sheets = list("metal" = /obj/item/stack/sheet/metal, "glass" = /obj/item/stack/sheet/glass) for(var/mat in stored_material) @@ -288,3 +292,4 @@ if(stored_material[mat] > S.perunit) S.amount = round(stored_material[mat] / S.perunit) S.loc = loc + ..() diff --git a/code/game/machinery/autolathe_datums.dm b/code/game/machinery/autolathe_datums.dm index c7d592c1d0d..ec6713085a4 100644 --- a/code/game/machinery/autolathe_datums.dm +++ b/code/game/machinery/autolathe_datums.dm @@ -15,7 +15,7 @@ if(I.matter && !recipe.resources) //This can be overidden in the datums. recipe.resources = list() for(var/material in I.matter) - recipe.resources[material] = round(I.matter[material]*1.25) // More expensive to produce than they are to recycle. + recipe.resources[material] = I.matter[material]*1.25 // More expensive to produce than they are to recycle. del(I) /datum/autolathe/recipe diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index d631ca46dff..3b3104201f5 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -13,7 +13,6 @@ var/c_tag_order = 999 var/status = 1 anchored = 1.0 - var/panel_open = 0 // 0 = Closed / 1 = Open var/invuln = null var/bugged = 0 var/obj/item/weapon/camera_assembly/assembly = null @@ -57,7 +56,7 @@ /obj/machinery/camera/Del() if(!alarm_on) triggerCameraAlarm() - + cancelCameraAlarm() ..() @@ -70,7 +69,7 @@ kick_viewers() triggerCameraAlarm() update_icon() - + spawn(900) stat &= ~EMPED cancelCameraAlarm() @@ -85,11 +84,11 @@ /obj/machinery/camera/ex_act(severity) if(src.invuln) return - + //camera dies if an explosion touches it! if(severity <= 2 || prob(50)) destroy() - + ..() //and give it the regular chance of being deleted outright @@ -174,7 +173,7 @@ if (S.current == src) O << "[U] holds \a [itemname] up to one of the cameras ..." O << browse(text("[][]", itemname, info), text("window=[]", itemname)) - + else if (istype(W, /obj/item/weapon/camera_bug)) if (!src.can_use()) user << "\blue Camera non-functional" @@ -185,7 +184,7 @@ else user << "\blue Camera bugged." src.bugged = 1 - + else if(W.damtype == BRUTE || W.damtype == BURN) //bashing cameras if (W.force >= src.toughness) visible_message("[src] has been [pick(W.attack_verb)] with [W] by [user]!") @@ -194,7 +193,7 @@ if (I.hitsound) playsound(loc, I.hitsound, 50, 1, -1) take_damage(W.force) - + else ..() @@ -221,14 +220,14 @@ if (force >= toughness && (force > toughness*4 || prob(25))) destroy() -//Used when someone breaks a camera +//Used when someone breaks a camera /obj/machinery/camera/proc/destroy() invalidateCameraCache() stat |= BROKEN kick_viewers() triggerCameraAlarm() update_icon() - + //sparks var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() spark_system.set_up(5, 0, loc) @@ -266,7 +265,7 @@ alarm_on = 1 if(!get_area(src)) return - + for(var/mob/living/silicon/S in mob_list) S.triggerAlarm("Camera", get_area(src), list(src), src) @@ -275,7 +274,7 @@ alarm_on = 0 if(!get_area(src)) return - + for(var/mob/living/silicon/S in mob_list) S.cancelAlarm("Camera", get_area(src), src) @@ -355,7 +354,7 @@ /obj/machinery/camera/interact(mob/living/user as mob) if(!panel_open || istype(user, /mob/living/silicon/ai)) return - + if(stat & BROKEN) user << "\The [src] is broken." return diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 454e6e44fc7..343c8ab2db1 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -3,18 +3,41 @@ //Potential replacement for genetics revives or something I dunno (?) +//Find a dead mob with a brain and client. +/proc/find_dead_player(var/find_key) + if(isnull(find_key)) + return + + var/mob/selected = null + for(var/mob/living/M in player_list) + //Dead people only thanks! + if((M.stat != 2) || (!M.client)) + continue + //They need a brain! + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + if(H.species.has_organ["brain"] && !H.has_brain()) + continue + if(M.ckey == find_key) + selected = M + break + return selected + #define CLONE_BIOMASS 150 /obj/machinery/clonepod - anchored = 1 name = "cloning pod" desc = "An electronically-lockable pod for growing organic tissue." density = 1 + anchored = 1 icon = 'icons/obj/cloning.dmi' icon_state = "pod_0" req_access = list(access_genetics) //For premature unlocking. + var/mob/living/occupant - var/heal_level = 90 //The clone is released once its health reaches this level. + var/heal_level = 20 //The clone is released once its health reaches this level. + var/heal_rate = 1 + var/notoxin = 0 var/locked = 0 var/obj/machinery/computer/cloning/connected = null //So we remember the connected clone machine. var/mess = 0 //Need to clean out it if it's full of exploded clone. @@ -22,6 +45,366 @@ var/eject_wait = 0 //Don't eject them as soon as they are created fuckkk var/biomass = CLONE_BIOMASS * 3 +/obj/machinery/clonepod/New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/clonepod(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + component_parts += new /obj/item/weapon/stock_parts/scanning_module(src) + component_parts += new /obj/item/weapon/stock_parts/scanning_module(src) + component_parts += new /obj/item/weapon/stock_parts/console_screen(src) + component_parts += new /obj/item/stack/cable_coil(src, 2) + + RefreshParts() + +/obj/machinery/clonepod/attack_ai(mob/user as mob) + add_hiddenprint(user) + return attack_hand(user) + +/obj/machinery/clonepod/attack_hand(mob/user as mob) + if((isnull(occupant)) || (stat & NOPOWER)) + return + if((!isnull(occupant)) && (occupant.stat != 2)) + var/completion = (100 * ((occupant.health + 50) / (heal_level + 100))) // Clones start at -150 health + user << "Current clone cycle is [round(completion)]% complete." + return + +//Clonepod + +//Start growing a human clone in the pod! +/obj/machinery/clonepod/proc/growclone(var/datum/dna2/record/R) + if(mess || attempting) + return 0 + var/datum/mind/clonemind = locate(R.mind) + if(!istype(clonemind, /datum/mind)) //not a mind + return 0 + if(clonemind.current && clonemind.current.stat != DEAD) //mind is associated with a non-dead body + return 0 + if(clonemind.active) //somebody is using that mind + if(ckey(clonemind.key) != R.ckey) + return 0 + else + for(var/mob/dead/observer/G in player_list) + if(G.ckey == R.ckey) + if(G.can_reenter_corpse) + break + else + return 0 + + attempting = 1 //One at a time!! + locked = 1 + + eject_wait = 1 + spawn(30) + eject_wait = 0 + + var/mob/living/carbon/human/H = new /mob/living/carbon/human(src, R.dna.species) + occupant = H + + if(!R.dna.real_name) //to prevent null names + R.dna.real_name = "clone ([rand(0,999)])" + H.real_name = R.dna.real_name + + icon_state = "pod_1" + //Get the clone body ready + H.adjustCloneLoss(150) // New damage var so you can't eject a clone early then stab them to abuse the current damage system --NeoFite + H.adjustBrainLoss(80) // Even if healed to full health, it will have some brain damage + H.Paralyse(4) + + //Here let's calculate their health so the pod doesn't immediately eject them!!! + H.updatehealth() + + clonemind.transfer_to(H) + H.ckey = R.ckey + H << "Consciousness slowly creeps over you as your body regenerates.
So this is what cloning feels like?
" + + // -- Mode/mind specific stuff goes here + callHook("clone", list(H)) + + switch(ticker.mode.name) + if("revolution") + if((H.mind in ticker.mode:revolutionaries) || (H.mind in ticker.mode:head_revolutionaries)) + ticker.mode.update_all_rev_icons() //So the icon actually appears + if("mercenary") + if(H.mind in ticker.mode.syndicates) + ticker.mode.update_all_synd_icons() + if("cult") + if(H.mind in ticker.mode.cult) + ticker.mode.add_cultist(occupant.mind) + ticker.mode.update_all_cult_icons() //So the icon actually appears + + // -- End mode specific stuff + + if(!R.dna) + H.dna = new /datum/dna() + H.dna.real_name = H.real_name + else + H.dna = R.dna + H.UpdateAppearance() + if(heal_level < 60) + randmutb(H) //Sometimes the clones come out wrong. + H.dna.UpdateSE() + H.dna.UpdateUI() + + H.set_cloned_appearance() + + for(var/datum/language/L in R.languages) + H.add_language(L.name) + H.flavor_texts = R.flavor.Copy() + H.suiciding = 0 + attempting = 0 + return 1 + +//Grow clones to maturity then kick them out. FREELOADERS +/obj/machinery/clonepod/process() + + if(stat & NOPOWER) //Autoeject if power is lost + if(occupant) + locked = 0 + go_out() + return + + if((occupant) && (occupant.loc == src)) + if((occupant.stat == DEAD) || (occupant.suiciding) || !occupant.key) //Autoeject corpses and suiciding dudes. + locked = 0 + go_out() + connected_message("Clone Rejected: Deceased.") + return + + else if(occupant.health < heal_level && occupant.getCloneLoss() > 0) + occupant.Paralyse(4) + + //Slowly get that clone healed and finished. + occupant.adjustCloneLoss(-2 * heal_rate) + + //Premature clones may have brain damage. + occupant.adjustBrainLoss(-1 * heal_rate) + + //So clones don't die of oxyloss in a running pod. + if(occupant.reagents.get_reagent_amount("inaprovaline") < 30) + occupant.reagents.add_reagent("inaprovaline", 60) + + //So clones will remain asleep for long enough to get them into cryo (Bay RP edit) + if(occupant.reagents.get_reagent_amount("stoxin") < 10) + occupant.reagents.add_reagent("stoxin", 5) + if(occupant.reagents.get_reagent_amount("chloralhydrate") < 1) + occupant.reagents.add_reagent("chloralhydrate", 1) + + //Also heal some oxyloss ourselves because inaprovaline is so bad at preventing it!! + occupant.adjustOxyLoss(-4) + if(notoxin) + occupant.adjustToxLoss(-2) // If sufficiently upgraded - remove toxin damage from chloral + + use_power(7500) //This might need tweaking. + return + + else if((occupant.health >= heal_level) && (!eject_wait)) + connected_message("Cloning Process Complete.") + locked = 0 + go_out() + return + + else if((!occupant) || (occupant.loc != src)) + occupant = null + if(locked) + locked = 0 + if(!mess) + icon_state = "pod_0" + //use_power(200) + return + + return + +//Let's unlock this early I guess. Might be too early, needs tweaking. +/obj/machinery/clonepod/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(isnull(occupant)) + if(default_deconstruction_screwdriver(user, W)) + return + if(default_deconstruction_crowbar(user, W)) + return + if(default_part_replacement(user, W)) + return + if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) + if(!check_access(W)) + user << "Access Denied." + return + if((!locked) || (isnull(occupant))) + return + if((occupant.health < -20) && (occupant.stat != 2)) + user << "Access Refused." + return + else + locked = 0 + user << "System unlocked." + else if(istype(W, /obj/item/weapon/card/emag)) + if(isnull(occupant)) + return + user << "You force an emergency ejection." + locked = 0 + go_out() + return + else if(istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat)) + user << "\The [src] processes \the [W]." + biomass += 50 + user.drop_item() + del(W) + return + else if(istype(W, /obj/item/weapon/wrench)) + if(locked && (anchored || occupant)) + user << "Can not do that while [src] is in use." + else + if(anchored) + anchored = 0 + connected.pod1 = null + connected = null + else + anchored = 1 + playsound(loc, 'sound/items/Ratchet.ogg', 100, 1) + if(anchored) + user.visible_message("[user] secures [src] to the floor.", "You secure [src] to the floor.") + else + user.visible_message("[user] unsecures [src] from the floor.", "You unsecure [src] from the floor.") + else + ..() + +//Put messages in the connected computer's temp var for display. +/obj/machinery/clonepod/proc/connected_message(var/message) + if((isnull(connected)) || (!istype(connected, /obj/machinery/computer/cloning))) + return 0 + if(!message) + return 0 + + connected.temp = message + connected.updateUsrDialog() + return 1 + +/obj/machinery/clonepod/RefreshParts() + ..() + var/rating = 0 + for(var/obj/item/weapon/stock_parts/P in component_parts) + if(istype(P, /obj/item/weapon/stock_parts/scanning_module) || istype(P, /obj/item/weapon/stock_parts/manipulator)) + rating += P.rating + + heal_level = rating * 10 - 20 + heal_rate = round(rating / 4) + if(rating >= 8) + notoxin = 1 + else + notoxin = 0 + +/obj/machinery/clonepod/verb/eject() + set name = "Eject Cloner" + set category = "Object" + set src in oview(1) + + if(usr.stat != 0) + return + go_out() + add_fingerprint(usr) + return + +/obj/machinery/clonepod/proc/go_out() + if(locked) + return + + if(mess) //Clean that mess and dump those gibs! + mess = 0 + gibs(loc) + icon_state = "pod_0" + + /* + for(var/obj/O in src) + O.loc = loc + */ + return + + if(!(occupant)) + return + + /* + for(var/obj/O in src) + O.loc = loc + */ + + if(occupant.client) + occupant.client.eye = occupant.client.mob + occupant.client.perspective = MOB_PERSPECTIVE + occupant.loc = loc + icon_state = "pod_0" + eject_wait = 0 //If it's still set somehow. + domutcheck(occupant) //Waiting until they're out before possible monkeyizing. +// occupant.add_side_effect("Bad Stomach") // Give them an extra side-effect for free. + occupant = null + + biomass -= CLONE_BIOMASS + + return + +/obj/machinery/clonepod/proc/malfunction() + if(occupant) + connected_message("Critical Error!") + mess = 1 + icon_state = "pod_g" + occupant.ghostize() + spawn(5) + del(occupant) + return + +/obj/machinery/clonepod/relaymove(mob/user as mob) + if(user.stat) + return + go_out() + return + +/obj/machinery/clonepod/emp_act(severity) + if(prob(100/severity)) + malfunction() + ..() + +/obj/machinery/clonepod/ex_act(severity) + switch(severity) + if(1.0) + for(var/atom/movable/A as mob|obj in src) + A.loc = loc + ex_act(severity) + del(src) + return + if(2.0) + if(prob(50)) + for(var/atom/movable/A as mob|obj in src) + A.loc = loc + ex_act(severity) + del(src) + return + if(3.0) + if(prob(25)) + for(var/atom/movable/A as mob|obj in src) + A.loc = loc + ex_act(severity) + del(src) + return + else + return + +//Health Tracker Implant + +/obj/item/weapon/implant/health + name = "health implant" + var/healthstring = "" + +/obj/item/weapon/implant/health/proc/sensehealth() + if(!implanted) + return "ERROR" + else + if(isliving(implanted)) + var/mob/living/L = implanted + healthstring = "[round(L.getOxyLoss())] - [round(L.getFireLoss())] - [round(L.getToxLoss())] - [round(L.getBruteLoss())]" + if(!healthstring) + healthstring = "ERROR" + return healthstring + +//Disk stuff. //The return of data disks?? Just for transferring between genetics machine/cloning machine. //TO-DO: Make the genetics machine accept them. /obj/item/weapon/disk/data @@ -30,7 +413,7 @@ icon_state = "datadisk0" //Gosh I hope syndies don't mistake them for the nuke disk. item_state = "card-id" w_class = 2.0 - var/datum/dna2/record/buf=null + var/datum/dna2/record/buf = null var/read_only = 0 //Well,it's still a floppy disk /obj/item/weapon/disk/data/proc/initializeDisk() @@ -65,363 +448,18 @@ buf.dna.SE=new_SE buf.dna.SetSEValueRange(MONKEYBLOCK,0xDAC, 0xFFF) - -//Find a dead mob with a brain and client. -/proc/find_dead_player(var/find_key) - if (isnull(find_key)) - return - - var/mob/selected = null - for(var/mob/living/M in player_list) - //Dead people only thanks! - if ((M.stat != 2) || (!M.client)) - continue - //They need a brain! - if(istype(M, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - if(H.species.has_organ["brain"] && !H.has_brain()) - continue - if (M.ckey == find_key) - selected = M - break - return selected - -//Disk stuff. /obj/item/weapon/disk/data/New() ..() var/diskcolor = pick(0,1,2) - src.icon_state = "datadisk[diskcolor]" + icon_state = "datadisk[diskcolor]" /obj/item/weapon/disk/data/attack_self(mob/user as mob) - src.read_only = !src.read_only - user << "You flip the write-protect tab to [src.read_only ? "protected" : "unprotected"]." + read_only = !read_only + user << "You flip the write-protect tab to [read_only ? "protected" : "unprotected"]." /obj/item/weapon/disk/data/examine(mob/user) ..(user) - user << text("The write-protect tab is set to [src.read_only ? "protected" : "unprotected"].") - return - -//Health Tracker Implant - -/obj/item/weapon/implant/health - name = "health implant" - var/healthstring = "" - -/obj/item/weapon/implant/health/proc/sensehealth() - if (!src.implanted) - return "ERROR" - else - if(isliving(src.implanted)) - var/mob/living/L = src.implanted - src.healthstring = "[round(L.getOxyLoss())] - [round(L.getFireLoss())] - [round(L.getToxLoss())] - [round(L.getBruteLoss())]" - if (!src.healthstring) - src.healthstring = "ERROR" - return src.healthstring - -/obj/machinery/clonepod/attack_ai(mob/user as mob) - src.add_hiddenprint(user) - return attack_hand(user) - -/obj/machinery/clonepod/attack_hand(mob/user as mob) - if ((isnull(src.occupant)) || (stat & NOPOWER)) - return - if ((!isnull(src.occupant)) && (src.occupant.stat != 2)) - var/completion = (100 * ((src.occupant.health + 100) / (src.heal_level + 100))) - user << "Current clone cycle is [round(completion)]% complete." - return - -//Clonepod - -//Start growing a human clone in the pod! -/obj/machinery/clonepod/proc/growclone(var/datum/dna2/record/R) - if(mess || attempting) - return 0 - var/datum/mind/clonemind = locate(R.mind) - if(!istype(clonemind,/datum/mind)) //not a mind - return 0 - if( clonemind.current && clonemind.current.stat != DEAD ) //mind is associated with a non-dead body - return 0 - if(clonemind.active) //somebody is using that mind - if( ckey(clonemind.key)!=R.ckey ) - return 0 - else - for(var/mob/dead/observer/G in player_list) - if(G.ckey == R.ckey) - if(G.can_reenter_corpse) - break - else - return 0 - - - src.heal_level = rand(10,40) //Randomizes what health the clone is when ejected - src.attempting = 1 //One at a time!! - src.locked = 1 - - src.eject_wait = 1 - spawn(30) - src.eject_wait = 0 - - var/mob/living/carbon/human/H = new /mob/living/carbon/human(src, R.dna.species) - occupant = H - - if(!R.dna.real_name) //to prevent null names - R.dna.real_name = "clone ([rand(0,999)])" - H.real_name = R.dna.real_name - - src.icon_state = "pod_1" - //Get the clone body ready - H.adjustCloneLoss(150) //new damage var so you can't eject a clone early then stab them to abuse the current damage system --NeoFite - H.adjustBrainLoss(src.heal_level + 50 + rand(10, 30)) // The rand(10, 30) will come out as extra brain damage - H.Paralyse(4) - - //Here let's calculate their health so the pod doesn't immediately eject them!!! - H.updatehealth() - - clonemind.transfer_to(H) - H.ckey = R.ckey - H << "Consciousness slowly creeps over you as your body regenerates.
So this is what cloning feels like?
" - - // -- Mode/mind specific stuff goes here - callHook("clone", list(H)) - - switch(ticker.mode.name) - if("revolution") - if((H.mind in ticker.mode:revolutionaries) || (H.mind in ticker.mode:head_revolutionaries)) - ticker.mode.update_all_rev_icons() //So the icon actually appears - if("mercenary") - if(H.mind in ticker.mode.syndicates) - ticker.mode.update_all_synd_icons() - if("cult") - if (H.mind in ticker.mode.cult) - ticker.mode.add_cultist(src.occupant.mind) - ticker.mode.update_all_cult_icons() //So the icon actually appears - - // -- End mode specific stuff - - if(!R.dna) - H.dna = new /datum/dna() - H.dna.real_name = H.real_name - else - H.dna=R.dna - H.UpdateAppearance() - randmutb(H) //Sometimes the clones come out wrong. - H.dna.UpdateSE() - H.dna.UpdateUI() - - H.set_cloned_appearance() - - for(var/datum/language/L in R.languages) - H.add_language(L.name) - H.flavor_texts = R.flavor.Copy() - H.suiciding = 0 - src.attempting = 0 - return 1 - -//Grow clones to maturity then kick them out. FREELOADERS -/obj/machinery/clonepod/process() - - if(stat & NOPOWER) //Autoeject if power is lost - if (src.occupant) - src.locked = 0 - src.go_out() - return - - if((src.occupant) && (src.occupant.loc == src)) - if((src.occupant.stat == DEAD) || (src.occupant.suiciding) || !occupant.key) //Autoeject corpses and suiciding dudes. - src.locked = 0 - src.go_out() - src.connected_message("Clone Rejected: Deceased.") - return - - else if(src.occupant.health < src.heal_level) - src.occupant.Paralyse(4) - - //Slowly get that clone healed and finished. - src.occupant.adjustCloneLoss(-2) - - //Premature clones may have brain damage. - src.occupant.adjustBrainLoss(-1) - - //So clones don't die of oxyloss in a running pod. - if (src.occupant.reagents.get_reagent_amount("inaprovaline") < 30) - src.occupant.reagents.add_reagent("inaprovaline", 60) - - //So clones will remain asleep for long enough to get them into cryo (Bay RP edit) - if (src.occupant.reagents.get_reagent_amount("stoxin") < 10) - src.occupant.reagents.add_reagent("stoxin", 5) - if (src.occupant.reagents.get_reagent_amount("chloralhydrate") < 1) - src.occupant.reagents.add_reagent("chloralhydrate", 1) - - //Also heal some oxyloss ourselves because inaprovaline is so bad at preventing it!! - src.occupant.adjustOxyLoss(-4) - - use_power(7500) //This might need tweaking. - return - - else if((src.occupant.health >= src.heal_level) && (!src.eject_wait)) - src.connected_message("Cloning Process Complete.") - src.locked = 0 - src.go_out() - return - - else if ((!src.occupant) || (src.occupant.loc != src)) - src.occupant = null - if (src.locked) - src.locked = 0 - if (!src.mess) - icon_state = "pod_0" - //use_power(200) - return - - return - -//Let's unlock this early I guess. Might be too early, needs tweaking. -/obj/machinery/clonepod/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) - if (!src.check_access(W)) - user << "\red Access Denied." - return - if ((!src.locked) || (isnull(src.occupant))) - return - if ((src.occupant.health < -20) && (src.occupant.stat != 2)) - user << "\red Access Refused." - return - else - src.locked = 0 - user << "System unlocked." - else if (istype(W, /obj/item/weapon/card/emag)) - if (isnull(src.occupant)) - return - user << "You force an emergency ejection." - src.locked = 0 - src.go_out() - return - else if (istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat)) - user << "\blue \The [src] processes \the [W]." - biomass += 50 - user.drop_item() - del(W) - return - else if (istype(W, /obj/item/weapon/wrench)) - if(src.locked && (src.anchored || src.occupant)) - user << "\red Can not do that while [src] is in use." - else - if(src.anchored) - src.anchored = 0 - connected.pod1 = null - connected = null - else - src.anchored = 1 - playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1) - if(anchored) - user.visible_message("[user] secures [src] to the floor.", "You secure [src] to the floor.") - else - user.visible_message("[user] unsecures [src] from the floor.", "You unsecure [src] from the floor.") - else - ..() - -//Put messages in the connected computer's temp var for display. -/obj/machinery/clonepod/proc/connected_message(var/message) - if ((isnull(src.connected)) || (!istype(src.connected, /obj/machinery/computer/cloning))) - return 0 - if (!message) - return 0 - - src.connected.temp = message - src.connected.updateUsrDialog() - return 1 - -/obj/machinery/clonepod/verb/eject() - set name = "Eject Cloner" - set category = "Object" - set src in oview(1) - - if (usr.stat != 0) - return - src.go_out() - add_fingerprint(usr) - return - -/obj/machinery/clonepod/proc/go_out() - if (src.locked) - return - - if (src.mess) //Clean that mess and dump those gibs! - src.mess = 0 - gibs(src.loc) - src.icon_state = "pod_0" - - /* - for(var/obj/O in src) - O.loc = src.loc - */ - return - - if (!(src.occupant)) - return - - /* - for(var/obj/O in src) - O.loc = src.loc - */ - - if (src.occupant.client) - src.occupant.client.eye = src.occupant.client.mob - src.occupant.client.perspective = MOB_PERSPECTIVE - src.occupant.loc = src.loc - src.icon_state = "pod_0" - src.eject_wait = 0 //If it's still set somehow. - domutcheck(src.occupant) //Waiting until they're out before possible monkeyizing. -// src.occupant.add_side_effect("Bad Stomach") // Give them an extra side-effect for free. - src.occupant = null - - src.biomass -= CLONE_BIOMASS - - return - -/obj/machinery/clonepod/proc/malfunction() - if(src.occupant) - src.connected_message("Critical Error!") - src.mess = 1 - src.icon_state = "pod_g" - src.occupant.ghostize() - spawn(5) - del(src.occupant) - return - -/obj/machinery/clonepod/relaymove(mob/user as mob) - if (user.stat) - return - src.go_out() - return - -/obj/machinery/clonepod/emp_act(severity) - if(prob(100/severity)) malfunction() - ..() - -/obj/machinery/clonepod/ex_act(severity) - switch(severity) - if(1.0) - for(var/atom/movable/A as mob|obj in src) - A.loc = src.loc - ex_act(severity) - del(src) - return - if(2.0) - if (prob(50)) - for(var/atom/movable/A as mob|obj in src) - A.loc = src.loc - ex_act(severity) - del(src) - return - if(3.0) - if (prob(25)) - for(var/atom/movable/A as mob|obj in src) - A.loc = src.loc - ex_act(severity) - del(src) - return - else + user << text("The write-protect tab is set to [read_only ? "protected" : "unprotected"].") return /* diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 68009eec609..2d5b9394d05 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -114,6 +114,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ hologram.anchored = 1//So space wind cannot drag it. hologram.name = "[A.name] (Hologram)"//If someone decides to right click. hologram.SetLuminosity(2) //hologram lighting + hologram.color = color //painted holopad gives coloured holograms SetLuminosity(2) //pad lighting icon_state = "holopad1" A.holo = src diff --git a/code/game/machinery/kitchen/smartfridge.dm b/code/game/machinery/kitchen/smartfridge.dm index 8e86678ef22..7b186bcc9c6 100644 --- a/code/game/machinery/kitchen/smartfridge.dm +++ b/code/game/machinery/kitchen/smartfridge.dm @@ -19,7 +19,6 @@ var/seconds_electrified = 0; var/shoot_inventory = 0 var/locked = 0 - var/panel_open = 0 //Hacking a smartfridge var/scan_id = 1 var/is_secure = 0 var/datum/wires/smartfridge/wires = null diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index c5eaf354973..819cc05632c 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -28,6 +28,9 @@ Class Variables: component_parts (list) A list of component parts of machine used by frame based machines. + panel_open (num) + Whether the panel is open + uid (num) Unique id of machine across all machines. @@ -43,9 +46,6 @@ Class Variables: MAINT:8 -- machine is currently under going maintenance. EMPED:16 -- temporary broken by EMP pulse - manual (num) - Currently unused. - Class Procs: New() 'game/machinery/machine.dm' @@ -104,13 +104,12 @@ Class Procs: //2 = run auto, use active var/idle_power_usage = 0 var/active_power_usage = 0 - var/power_channel = EQUIP - //EQUIP,ENVIRON or LIGHT - var/list/component_parts = list() //list of all the parts used to build it, if made from certain kinds of frames. + var/power_channel = EQUIP //EQUIP, ENVIRON or LIGHT + var/list/component_parts = null //list of all the parts used to build it, if made from certain kinds of frames. var/uid - var/manual = 0 - var/interact_offline = 0 // Can the machine be interacted with while de-powered. + var/panel_open = 0 var/global/gl_uid = 1 + var/interact_offline = 0 // Can the machine be interacted with while de-powered. /obj/machinery/New(l, d=0) ..(l) @@ -238,15 +237,15 @@ Class Procs: gl_uid++ /obj/machinery/proc/state(var/msg) - for(var/mob/O in hearers(src, null)) - O.show_message("\icon[src] [msg]", 2) + for(var/mob/O in hearers(src, null)) + O.show_message("\icon[src] [msg]", 2) /obj/machinery/proc/ping(text=null) - if (!text) - text = "\The [src] pings." + if (!text) + text = "\The [src] pings." - state(text, "blue") - playsound(src.loc, 'sound/machines/ping.ogg', 50, 0) + state(text, "blue") + playsound(src.loc, 'sound/machines/ping.ogg', 50, 0) /obj/machinery/proc/shock(mob/user, prb) if(inoperable()) @@ -267,6 +266,54 @@ Class Procs: else return 0 +/obj/machinery/proc/default_deconstruction_crowbar(var/mob/user, var/obj/item/weapon/crowbar/C) + if(!istype(C)) + return 0 + if(!panel_open) + return 0 + . = dismantle() + +/obj/machinery/proc/default_deconstruction_screwdriver(var/mob/user, var/obj/item/weapon/screwdriver/S) + if(!istype(S)) + return 0 + playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) + panel_open = !panel_open + user << "You [panel_open ? "open" : "close"] the maintenance hatch of [src]." + update_icon() + return 1 + +/obj/machinery/proc/default_part_replacement(var/mob/user, var/obj/item/weapon/storage/part_replacer/R) + if(!istype(R)) + return 0 + if(!component_parts) + return 0 + if(panel_open) + var/obj/item/weapon/circuitboard/CB = locate(/obj/item/weapon/circuitboard) in component_parts + var/P + for(var/obj/item/weapon/stock_parts/A in component_parts) + for(var/D in CB.req_components) + var/T = text2path(D) + if(ispath(A.type, T)) + P = T + break + for(var/obj/item/weapon/stock_parts/B in R.contents) + if(istype(B, P) && istype(A, P)) + if(B.rating > A.rating) + R.remove_from_storage(B, src) + R.handle_item_insertion(A, 1) + component_parts -= A + component_parts += B + B.loc = null + user << "[A.name] replaced with [B.name]." + break + update_icon() + RefreshParts() + else + user << "Following parts detected in the machine:" + for(var/var/obj/item/C in component_parts) + user << " [C.name]" + return 1 + /obj/machinery/proc/dismantle() playsound(loc, 'sound/items/Crowbar.ogg', 50, 1) var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(loc) diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 3049a6f6943..e4d29467e03 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -3,187 +3,227 @@ icon = 'icons/obj/objects.dmi' icon_state = "borgcharger0" density = 1 - anchored = 1.0 + anchored = 1 use_power = 1 idle_power_usage = 50 active_power_usage = 50 var/mob/occupant = null - var/max_internal_charge = 15000 // Two charged borgs in a row with default cell - var/current_internal_charge = 15000 // Starts charged, to prevent power surges on round start - var/charging_cap_active = 25000 // Active Cap - When cyborg is inside - var/charging_cap_passive = 2500 // Passive Cap - Recharging internal capacitor when no cyborg is inside + var/obj/item/weapon/cell/cell = null + //var/max_internal_charge = 15000 // Two charged borgs in a row with default cell + //var/current_internal_charge = 15000 // Starts charged, to prevent power surges on round start + var/charging_cap_active = 1000 // Active Cap - When cyborg is inside + var/charging_cap_passive = 250 // Passive Cap - Recharging internal capacitor when no cyborg is inside var/icon_update_tick = 0 // Used to update icon only once every 10 ticks + var/charge_rate = 250 // How much charge is restored per tick + var/weld_rate = 0 // How much brute damage is repaired per tick + var/wire_rate = 0 // How much burn damage is repaired per tick +/obj/machinery/recharge_station/New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/recharge_station(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + component_parts += new /obj/item/weapon/stock_parts/capacitor(src) + component_parts += new /obj/item/weapon/stock_parts/capacitor(src) + component_parts += new /obj/item/weapon/cell/high(src) + component_parts += new /obj/item/stack/cable_coil(src, 5) - New() - ..() - build_icon() - update_icon() + build_icon() + update_icon() - process() - if(stat & (BROKEN)) - return + RefreshParts() - if((stat & (NOPOWER)) && !current_internal_charge) // No Power. - return - - var/chargemode = 0 - if(src.occupant) - process_occupant() - chargemode = 1 - // Power Stuff - - if(stat & NOPOWER) - current_internal_charge = max(0, (current_internal_charge - (50 * CELLRATE))) // Internal Circuitry, 50W load. No power - Runs from internal cell - return // No external power = No charging - - - - if(max_internal_charge < current_internal_charge) - current_internal_charge = max_internal_charge// Safety check if varedit adminbus or something screws up - // Calculating amount of power to draw - var/charge_diff = max_internal_charge - current_internal_charge // OK we have charge differences - charge_diff = charge_diff / CELLRATE // Deconvert from Charge to Joules - if(chargemode) // Decide if use passive or active power - charge_diff = between(0, charge_diff, charging_cap_active) // Trim the values to limits - else // We should have load for this tick in Watts - charge_diff = between(0, charge_diff, charging_cap_passive) - - charge_diff += 50 // 50W for circuitry - - if(idle_power_usage != charge_diff) // Force update, but only when our power usage changed this tick. - idle_power_usage = charge_diff - update_use_power(1,1) - - current_internal_charge = min((current_internal_charge + ((charge_diff - 50) * CELLRATE)), max_internal_charge) - - if(icon_update_tick >= 10) - update_icon() - icon_update_tick = 0 - else - icon_update_tick++ - - return 1 - - - allow_drop() - return 0 - - examine(mob/user) - ..(user) - user << "The charge meter reads: [round(chargepercentage())]%" - - proc/chargepercentage() - return ((current_internal_charge / max_internal_charge) * 100) - - relaymove(mob/user as mob) - if(user.stat) - return - src.go_out() +/obj/machinery/recharge_station/process() + if(stat & (BROKEN)) return - emp_act(severity) - if(stat & (BROKEN|NOPOWER)) - ..(severity) - return - if(occupant) - occupant.emp_act(severity) - go_out() - ..(severity) - - update_icon() - ..() - overlays.Cut() - switch(round(chargepercentage())) - if(1 to 20) - overlays += image('icons/obj/objects.dmi', "statn_c0") - if(21 to 40) - overlays += image('icons/obj/objects.dmi', "statn_c20") - if(41 to 60) - overlays += image('icons/obj/objects.dmi', "statn_c40") - if(61 to 80) - overlays += image('icons/obj/objects.dmi', "statn_c60") - if(81 to 98) - overlays += image('icons/obj/objects.dmi', "statn_c80") - if(99 to 110) - overlays += image('icons/obj/objects.dmi', "statn_c100") - - proc - build_icon() - if(NOPOWER|BROKEN) - if(src.occupant) - icon_state = "borgcharger1" - else - icon_state = "borgcharger0" - else - icon_state = "borgcharger0" + if((stat & (NOPOWER)) && (!cell || cell.percent() <= 0)) // No Power. + return + var/chargemode = 0 + if(occupant) process_occupant() - if(src.occupant) - if (istype(occupant, /mob/living/silicon/robot)) - var/mob/living/silicon/robot/R = occupant - if(R.module) - R.module.respawn_consumable(R) - if(!R.cell) - return - if(!R.cell.fully_charged()) - var/diff = min(R.cell.maxcharge - R.cell.charge, 250) // Capped at 250 charge / tick - diff = min(diff, current_internal_charge) // No over-discharging - R.cell.give(diff) - current_internal_charge -= diff - else - update_use_power(1) + chargemode = 1 + // Power Stuff + + if(!cell) // Shouldn't be possible, but sanity check + return + + if(stat & NOPOWER) + cell.use(50 * CELLRATE) // Internal Circuitry, 50W load. No power - Runs from internal cell + return // No external power = No charging + + // Calculating amount of power to draw + var/charge_diff = (chargemode ? charging_cap_active : charging_cap_passive) + 50 // 50W for circuitry + + charge_diff = cell.give(charge_diff) + + if(idle_power_usage != charge_diff) // Force update, but only when our power usage changed this tick. + idle_power_usage = charge_diff + update_use_power(1, 1) + + if(icon_update_tick >= 10) + update_icon() + icon_update_tick = 0 + else + icon_update_tick++ + + return 1 + + +/obj/machinery/recharge_station/allow_drop() + return 0 + +/obj/machinery/recharge_station/examine(mob/user) + ..(user) + user << "The charge meter reads: [round(chargepercentage())]%" + +/obj/machinery/recharge_station/proc/chargepercentage() + if(!cell) + return 0 + return cell.percent() + +/obj/machinery/recharge_station/relaymove(mob/user as mob) + if(user.stat) + return + go_out() + return + +/obj/machinery/recharge_station/emp_act(severity) + if(stat & (BROKEN|NOPOWER)) + ..(severity) + return + if(occupant) + occupant.emp_act(severity) go_out() - if(!( src.occupant )) - return - //for(var/obj/O in src) - // O.loc = src.loc - if (src.occupant.client) - src.occupant.client.eye = src.occupant.client.mob - src.occupant.client.perspective = MOB_PERSPECTIVE - src.occupant.loc = src.loc - src.occupant = null - build_icon() - update_use_power(1) + if(cell) + cell.emp_act(severity) + ..(severity) + +/obj/machinery/recharge_station/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(!occupant) + if(default_deconstruction_screwdriver(user, O)) + return + if(default_deconstruction_crowbar(user, O)) + return + if(default_part_replacement(user, O)) return + ..() - verb - move_eject() - set category = "Object" - set src in oview(1) - if (usr.stat != 0) - return - src.go_out() - add_fingerprint(usr) - return +/obj/machinery/recharge_station/RefreshParts() + ..() + var/man_rating = 0 + var/cap_rating = 0 - move_inside() - set category = "Object" - set src in oview(1) - if (usr.stat == 2) - //Whoever had it so that a borg with a dead cell can't enter this thing should be shot. --NEO + for(var/obj/item/weapon/stock_parts/P in component_parts) + if(istype(P, /obj/item/weapon/stock_parts/capacitor)) + cap_rating += P.rating + if(istype(P, /obj/item/weapon/stock_parts/manipulator)) + man_rating += P.rating + cell = locate(/obj/item/weapon/cell) in component_parts + + charge_rate = 125 * cap_rating + charging_cap_passive = charge_rate + weld_rate = max(0, man_rating - 3) + wire_rate = max(0, man_rating - 5) + +/obj/machinery/recharge_station/update_icon() + ..() + overlays.Cut() + switch(round(chargepercentage())) + if(1 to 20) + overlays += image('icons/obj/objects.dmi', "statn_c0") + if(21 to 40) + overlays += image('icons/obj/objects.dmi', "statn_c20") + if(41 to 60) + overlays += image('icons/obj/objects.dmi', "statn_c40") + if(61 to 80) + overlays += image('icons/obj/objects.dmi', "statn_c60") + if(81 to 98) + overlays += image('icons/obj/objects.dmi', "statn_c80") + if(99 to 110) + overlays += image('icons/obj/objects.dmi', "statn_c100") + + +/obj/machinery/recharge_station/proc/build_icon() + if(NOPOWER|BROKEN) + if(occupant) + icon_state = "borgcharger1" + else + icon_state = "borgcharger0" + else + icon_state = "borgcharger0" + +/obj/machinery/recharge_station/proc/process_occupant() + if(occupant) + if(istype(occupant, /mob/living/silicon/robot)) + var/mob/living/silicon/robot/R = occupant + if(R.module) + R.module.respawn_consumable(R) + if(!R.cell) return - if (!(istype(usr, /mob/living/silicon/))) - usr << "\blue Only non-organics may enter the recharger!" - return - if (src.occupant) - usr << "\blue The cell is already occupied!" - return - if (!usr:cell) - usr<<"\blue Without a powercell, you can't be recharged." - //Make sure they actually HAVE a cell, now that they can get in while powerless. --NEO - return - usr.stop_pulling() - if(usr && usr.client) - usr.client.perspective = EYE_PERSPECTIVE - usr.client.eye = src - usr.loc = src - src.occupant = usr - /*for(var/obj/O in src) - O.loc = src.loc*/ - src.add_fingerprint(usr) - build_icon() - update_use_power(1) - return \ No newline at end of file + if(!R.cell.fully_charged()) + var/diff = min(R.cell.maxcharge - R.cell.charge, charge_rate) // Capped at charge_rate charge / tick + if (cell.use(diff)) + R.cell.give(diff) + if(weld_rate && R.getBruteLoss()) + R.adjustBruteLoss(-1) + if(wire_rate && R.getFireLoss()) + R.adjustFireLoss(-1) + else + update_use_power(1) + +/obj/machinery/recharge_station/proc/go_out() + if(!(occupant)) + return + //for(var/obj/O in src) + // O.loc = loc + if(occupant.client) + occupant.client.eye = occupant.client.mob + occupant.client.perspective = MOB_PERSPECTIVE + occupant.loc = loc + occupant = null + build_icon() + update_use_power(1) + return + +/obj/machinery/recharge_station/verb/move_eject() + set category = "Object" + set src in oview(1) + if(usr.stat != 0) + return + go_out() + add_fingerprint(usr) + return + +/obj/machinery/recharge_station/verb/move_inside() + set category = "Object" + set src in oview(1) + if(usr.stat == 2) + //Whoever had it so that a borg with a dead cell can't enter this thing should be shot. --NEO + return + if(!(istype(usr, /mob/living/silicon/))) + usr << "Only non-organics may enter the recharger!" + return + if(occupant) + usr << "The cell is already occupied!" + return + if(!usr:cell) + usr << "Without a powercell, you can't be recharged." + //Make sure they actually HAVE a cell, now that they can get in while powerless. --NEO + return + usr.stop_pulling() + if(usr && usr.client) + usr.client.perspective = EYE_PERSPECTIVE + usr.client.eye = src + usr.loc = src + occupant = usr + /*for(var/obj/O in src) + O.loc = loc*/ + add_fingerprint(usr) + build_icon() + update_use_power(1) + return \ No newline at end of file diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index ab4967d04ed..c5d389c66e3 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -7,7 +7,6 @@ desc = "Made by Space Amish using traditional space techniques, this heater is guaranteed not to set the station on fire." var/obj/item/weapon/cell/cell var/on = 0 - var/open = 0 var/set_temperature = T0C + 50 //K var/heating_power = 40000 @@ -20,14 +19,14 @@ /obj/machinery/space_heater/update_icon() overlays.Cut() icon_state = "sheater[on]" - if(open) + if(panel_open) overlays += "sheater-open" /obj/machinery/space_heater/examine(mob/user) ..(user) - user << "The heater is [on ? "on" : "off"] and the hatch is [open ? "open" : "closed"]." - if(open) + user << "The heater is [on ? "on" : "off"] and the hatch is [panel_open ? "open" : "closed"]." + if(panel_open) user << "The power cell is [cell ? "installed" : "missing"]." else user << "The charge meter reads [cell ? round(cell.percent(),1) : 0]%" @@ -43,7 +42,7 @@ /obj/machinery/space_heater/attackby(obj/item/I, mob/user) if(istype(I, /obj/item/weapon/cell)) - if(open) + if(panel_open) if(cell) user << "There is already a power cell inside." return @@ -61,10 +60,10 @@ user << "The hatch must be open to insert a power cell." return else if(istype(I, /obj/item/weapon/screwdriver)) - open = !open - user.visible_message("\blue [user] [open ? "opens" : "closes"] the hatch on the [src].", "\blue You [open ? "open" : "close"] the hatch on the [src].") + panel_open = !panel_open + user.visible_message("\blue [user] [panel_open ? "opens" : "closes"] the hatch on the [src].", "\blue You [panel_open ? "open" : "close"] the hatch on the [src].") update_icon() - if(!open && user.machine == src) + if(!panel_open && user.machine == src) user << browse(null, "window=spaceheater") user.unset_machine() else @@ -77,7 +76,7 @@ /obj/machinery/space_heater/interact(mob/user as mob) - if(open) + if(panel_open) var/dat dat = "Power cell: " @@ -120,7 +119,7 @@ set_temperature = dd_range(T0C, T0C + 90, set_temperature + value) if("cellremove") - if(open && cell && !usr.get_active_hand()) + if(panel_open && cell && !usr.get_active_hand()) usr.visible_message("\blue [usr] removes \the [cell] from \the [src].", "\blue You remove \the [cell] from \the [src].") cell.updateicon() usr.put_in_hands(cell) @@ -129,7 +128,7 @@ if("cellinstall") - if(open && !cell) + if(panel_open && !cell) var/obj/item/weapon/cell/C = usr.get_active_hand() if(istype(C)) usr.drop_item() diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 4bf1c07abc7..f8ae293bba3 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -589,7 +589,6 @@ var/radiation_level = 2 // 1 is removing germs, 2 is removing blood, 3 is removing phoron. var/model_text = "" // Some flavour text for the topic box. var/locked = 1 // If locked, nothing can be taken from or added to the cycler. - var/panel_open = 0 // Hacking! var/can_repair // If set, the cycler can repair voidsuits. var/electrified = 0 diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 26f1c620c7a..7d7ee3113df 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -54,7 +54,6 @@ var/shoot_inventory = 0 //Fire items at customers! We're broken! var/shut_up = 1 //Stop spouting those godawful pitches! var/extended_inventory = 0 //can we access the hidden inventory? - var/panel_open = 0 //Hacking that vending machine. Gonna get a free candy bar. var/scan_id = 1 var/obj/item/weapon/coin/coin var/datum/wires/vending/wires = null diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 13081d6abba..eb2e5c65a6f 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -411,9 +411,9 @@ H << "You need a jumpsuit before you can attach this [name]." return 0 var/obj/item/clothing/under/uniform = H.w_uniform - if(uniform.hastie) + if(uniform.accessories.len && !uniform.can_attach_accessory(src)) if (!disable_warning) - H << "You already have [uniform.hastie] attached to your [uniform]." + H << "You already have an accessory of this type attached to your [uniform]." return 0 if( !(slot_flags & SLOT_TIE) ) return 0 diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index a938d6b9774..d3c667b9aa2 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -281,6 +281,8 @@ src.overlays.Cut() src.overlays += "pai-off" +/obj/item/device/paicard + var/current_emotion = 1 /obj/item/device/paicard/proc/setEmotion(var/emotion) if(pai) src.overlays.Cut() @@ -294,6 +296,7 @@ if(7) src.overlays += "pai-sad" if(8) src.overlays += "pai-angry" if(9) src.overlays += "pai-what" + current_emotion = emotion /obj/item/device/paicard/proc/alertUpdate() var/turf/T = get_turf_or_move(src.loc) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index fe150bab743..b997466d7d3 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -380,6 +380,10 @@ viewers(user) << "\red [user] is jamming the [src.name] up \his nose and into \his brain. It looks like \he's trying to commit suicide." return (BRUTELOSS|OXYLOSS) + New() + name = "[colourName] crayon" + ..() + /* * Snap pops */ diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index 8d639987223..9f95abdc8ca 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -81,7 +81,7 @@ /obj/item/device/taperecorder, /obj/item/device/hailer, /obj/item/device/megaphone, - /obj/item/clothing/tie/holobadge, + /obj/item/clothing/accessory/holobadge, /obj/structure/closet/crate/secure, /obj/structure/closet/secure_closet, /obj/machinery/librarycomp, diff --git a/code/game/objects/items/weapons/circuitboards/machinery/biogenerator.dm b/code/game/objects/items/weapons/circuitboards/machinery/biogenerator.dm new file mode 100644 index 00000000000..c01893b1587 --- /dev/null +++ b/code/game/objects/items/weapons/circuitboards/machinery/biogenerator.dm @@ -0,0 +1,13 @@ +#ifndef T_BOARD +#error T_BOARD macro is not defined but we need it! +#endif + +/obj/item/weapon/circuitboard/biogenerator + name = T_BOARD("biogenerator") + build_path = "/obj/machinery/biogenerator" + board_type = "machine" + origin_tech = "programming=2" + frame_desc = "Requires 1 Manipulator, and 1 Matter Bin." + req_components = list( + "/obj/item/weapon/stock_parts/matter_bin" = 1, + "/obj/item/weapon/stock_parts/manipulator" = 1) \ No newline at end of file diff --git a/code/game/objects/items/weapons/circuitboards/machinery/recharge_station.dm b/code/game/objects/items/weapons/circuitboards/machinery/recharge_station.dm new file mode 100644 index 00000000000..5a0dc01bc12 --- /dev/null +++ b/code/game/objects/items/weapons/circuitboards/machinery/recharge_station.dm @@ -0,0 +1,15 @@ +#ifndef T_BOARD +#error T_BOARD macro is not defined but we need it! +#endif + +/obj/item/weapon/circuitboard/recharge_station + name = T_BOARD("cyborg recharging station") + build_path = "/obj/machinery/recharge_station" + board_type = "machine" + origin_tech = "programming=3;engineering=3" + frame_desc = "Requires 2 Manipulator, 2 Capacitor, 1 Cell, and 5 pieces of cable." + req_components = list( + "/obj/item/stack/cable_coil" = 5, + "/obj/item/weapon/stock_parts/capacitor" = 2, + "/obj/item/weapon/stock_parts/manipulator" = 2, + "/obj/item/weapon/cell" = 1) \ No newline at end of file diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index 71fb259dcda..030437b4466 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -38,7 +38,7 @@ /obj/item/weapon/plastique/afterattack(atom/movable/target, mob/user, flag) if (!flag) return - if (ismob(target) || istype(target, /turf/unsimulated) || istype(target, /turf/simulated/shuttle) || istype(target, /obj/item/weapon/storage/) || istype(target, /obj/item/clothing/tie/storage/) || istype(target, /obj/item/clothing/under)) + if (ismob(target) || istype(target, /turf/unsimulated) || istype(target, /turf/simulated/shuttle) || istype(target, /obj/item/weapon/storage/) || istype(target, /obj/item/clothing/accessory/storage/) || istype(target, /obj/item/clothing/under)) return user << "Planting explosives..." diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index e96d0367217..8ed63b88aa3 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -104,7 +104,7 @@ /obj/item/device/paicard, /obj/item/device/violin, /obj/item/weapon/storage/belt/utility/full, - /obj/item/clothing/tie/horrible) + /obj/item/clothing/accessory/horrible) if(!ispath(gift_type,/obj/item)) return diff --git a/code/game/objects/items/weapons/paint.dm b/code/game/objects/items/weapons/paint.dm index 0606569c4fa..77f8172f8fc 100644 --- a/code/game/objects/items/weapons/paint.dm +++ b/code/game/objects/items/weapons/paint.dm @@ -1,4 +1,5 @@ //NEVER USE THIS IT SUX -PETETHEGOAT +//THE GOAT WAS RIGHT - RKF var/global/list/cached_icons = list() @@ -11,10 +12,10 @@ var/global/list/cached_icons = list() matter = list("metal" = 200) w_class = 3.0 amount_per_transfer_from_this = 10 - possible_transfer_amounts = list(10,20,30,50,70) + possible_transfer_amounts = list(10,20,30,60) volume = 60 flags = OPENCONTAINER - var/paint_type = "" + var/paint_type = "red" afterattack(turf/simulated/target, mob/user, proximity) if(!proximity) return @@ -28,24 +29,19 @@ var/global/list/cached_icons = list() return ..() New() - if(paint_type == "remover") - name = "paint remover bucket" - else if(paint_type && lentext(paint_type) > 0) + if(paint_type && lentext(paint_type) > 0) name = paint_type + " " + name ..() reagents.add_reagent("water", volume*3/5) reagents.add_reagent("plasticide", volume/5) if(paint_type == "white") //why don't white crayons exist reagents.add_reagent("aluminum", volume/5) + else if (paint_type == "black") + reagents.add_reagent("carbon", volume/5) else reagents.add_reagent("crayon_dust_[paint_type]", volume/5) reagents.handle_reactions() - on_reagent_change() //Until we have a generic "paint", this will give new colours to all paints in the can - var/mixedcolor = mix_color_from_reagents(reagents.reagent_list) - for(var/datum/reagent/paint/P in reagents.reagent_list) - P.color = mixedcolor - red icon_state = "paint_red" paint_type = "red" @@ -62,110 +58,15 @@ var/global/list/cached_icons = list() icon_state = "paint_blue" paint_type = "blue" - violet + purple icon_state = "paint_violet" paint_type = "purple" black icon_state = "paint_black" - paint_type = "gray" + paint_type = "black" white icon_state = "paint_white" paint_type = "white" - remover - paint_type = "remover" -/* -/obj/item/weapon/paint - gender= PLURAL - name = "paint" - desc = "Used to recolor floors and walls. Can not be removed by the janitor." - icon = 'icons/obj/items.dmi' - icon_state = "paint_neutral" - color = "FFFFFF" - item_state = "paintcan" - w_class = 3.0 - -/obj/item/weapon/paint/afterattack(turf/target, mob/user as mob, proximity) - if(!proximity) return - if(!istype(target) || istype(target, /turf/space)) - return - var/ind = "[initial(target.icon)][color]" - if(!cached_icons[ind]) - var/icon/overlay = new/icon(initial(target.icon)) - overlay.Blend("#[color]",ICON_MULTIPLY) - overlay.SetIntensity(1.4) - target.icon = overlay - cached_icons[ind] = target.icon - else - target.icon = cached_icons[ind] - return - -/obj/item/weapon/paint/paint_remover - gender = PLURAL - name = "paint remover" - icon_state = "paint_neutral" - - afterattack(turf/target, mob/user as mob) - if(istype(target) && target.icon != initial(target.icon)) - target.icon = initial(target.icon) - return -*/ -/* -datum/reagent/paint - name = "Paint" - id = "paint_" - reagent_state = 2 - color = "#808080" - description = "This paint will only adhere to floor tiles." - - - - red - name = "Red Paint" - id = "paint_red" - color = "#FE191A" - - green - name = "Green Paint" - color = "#18A31A" - id = "paint_green" - - blue - name = "Blue Paint" - color = "#247CFF" - id = "paint_blue" - - yellow - name = "Yellow Paint" - color = "#FDFE7D" - id = "paint_yellow" - - violet - name = "Violet Paint" - color = "#CC0099" - id = "paint_violet" - - black - name = "Black Paint" - color = "#333333" - id = "paint_black" - - white - name = "White Paint" - color = "#F0F8FF" - id = "paint_white" - -datum/reagent/paint_remover - name = "Paint Remover" - id = "paint_remover" - description = "Paint remover is used to remove floor paint from floor tiles." - reagent_state = 2 - color = "#808080" - - reaction_turf(var/turf/T, var/volume) - if(istype(T) && T.icon != initial(T.icon)) - T.icon = initial(T.icon) - return -*/ diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 0c4a94eb869..e190ac1e02d 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -70,9 +70,16 @@ "/obj/item/device/flashlight/pen", "/obj/item/clothing/mask/surgical", "/obj/item/clothing/gloves/latex", - "/obj/item/weapon/reagent_containers/hypospray" + "/obj/item/weapon/reagent_containers/hypospray" ) +/obj/item/weapon/storage/belt/medical/emt + name = "EMT utility belt" + desc = "A sturdy black webbing belt with attached pouches." + icon = 'icons/obj/custom_items.dmi' + icon_state = "emsbelt" + item_state = "emsbelt" + /obj/item/weapon/storage/belt/security name = "security belt" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm index 803f07616e0..d583e775470 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm @@ -16,9 +16,9 @@ else new /obj/item/weapon/storage/backpack/satchel_eng(src) if (prob(70)) - new /obj/item/clothing/tie/storage/brown_vest(src) + new /obj/item/clothing/accessory/storage/brown_vest(src) else - new /obj/item/clothing/tie/storage/webbing(src) + new /obj/item/clothing/accessory/storage/webbing(src) new /obj/item/blueprints(src) new /obj/item/clothing/under/rank/chief_engineer(src) new /obj/item/clothing/head/hardhat/white(src) @@ -109,9 +109,9 @@ else new /obj/item/weapon/storage/backpack/satchel_eng(src) if (prob(70)) - new /obj/item/clothing/tie/storage/brown_vest(src) + new /obj/item/clothing/accessory/storage/brown_vest(src) else - new /obj/item/clothing/tie/storage/webbing(src) + new /obj/item/clothing/accessory/storage/webbing(src) new /obj/item/weapon/storage/toolbox/mechanical(src) new /obj/item/device/radio/headset/headset_eng(src) new /obj/item/clothing/suit/storage/hazardvest(src) @@ -138,9 +138,9 @@ else new /obj/item/weapon/storage/backpack/satchel_eng(src) if (prob(70)) - new /obj/item/clothing/tie/storage/brown_vest(src) + new /obj/item/clothing/accessory/storage/brown_vest(src) else - new /obj/item/clothing/tie/storage/webbing(src) + new /obj/item/clothing/accessory/storage/webbing(src) new /obj/item/clothing/suit/fire/firefighter(src) new /obj/item/device/flashlight(src) new /obj/item/weapon/extinguisher(src) 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 4185215f28b..f0a67bddee5 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -119,7 +119,7 @@ new /obj/item/device/flash(src) new /obj/item/weapon/melee/baton/loaded(src) new /obj/item/weapon/gun/energy/gun(src) - new /obj/item/clothing/tie/holster/waist(src) + new /obj/item/clothing/accessory/holster/waist(src) new /obj/item/weapon/melee/telebaton(src) new /obj/item/clothing/head/beret/sec/hos(src) return @@ -192,7 +192,7 @@ new /obj/item/clothing/glasses/sunglasses/sechud(src) new /obj/item/taperoll/police(src) new /obj/item/device/hailer(src) - new /obj/item/clothing/tie/storage/black_vest(src) + new /obj/item/clothing/accessory/storage/black_vest(src) new /obj/item/clothing/head/soft/sec/corp(src) new /obj/item/clothing/under/rank/security/corp(src) return @@ -202,7 +202,7 @@ New() ..() - new /obj/item/clothing/tie/armband/cargo(src) + new /obj/item/clothing/accessory/armband/cargo(src) new /obj/item/device/encryptionkey/headset_cargo(src) return @@ -210,7 +210,7 @@ New() ..() - new /obj/item/clothing/tie/armband/engine(src) + new /obj/item/clothing/accessory/armband/engine(src) new /obj/item/device/encryptionkey/headset_eng(src) return @@ -218,7 +218,7 @@ New() ..() - new /obj/item/clothing/tie/armband/science(src) + new /obj/item/clothing/accessory/armband/science(src) new /obj/item/device/encryptionkey/headset_sci(src) return @@ -226,7 +226,7 @@ New() ..() - new /obj/item/clothing/tie/armband/medgreen(src) + new /obj/item/clothing/accessory/armband/medgreen(src) new /obj/item/device/encryptionkey/headset_med(src) return @@ -262,7 +262,7 @@ new /obj/item/ammo_magazine/c45m/rubber(src) new /obj/item/taperoll/police(src) new /obj/item/weapon/gun/projectile/detective/semiauto(src) - new /obj/item/clothing/tie/holster/armpit(src) + new /obj/item/clothing/accessory/holster/armpit(src) return /obj/structure/closet/secure_closet/detective/update_icon() diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm index a219268d041..199635cd0fe 100644 --- a/code/game/objects/structures/safe.dm +++ b/code/game/objects/structures/safe.dm @@ -90,7 +90,7 @@ FLOOR SAFES var/mob/living/carbon/human/user = usr var/canhear = 0 - if(istype(user.l_hand, /obj/item/clothing/tie/stethoscope) || istype(user.r_hand, /obj/item/clothing/tie/stethoscope)) + if(istype(user.l_hand, /obj/item/clothing/accessory/stethoscope) || istype(user.r_hand, /obj/item/clothing/accessory/stethoscope)) canhear = 1 if(href_list["open"]) @@ -155,7 +155,7 @@ FLOOR SAFES user << "[I] won't fit in [src]." return else - if(istype(I, /obj/item/clothing/tie/stethoscope)) + if(istype(I, /obj/item/clothing/accessory/stethoscope)) user << "Hold [I] in one of your hands while you manipulate the dial." return diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 572ed0ff8db..9b85c90e161 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -6,8 +6,7 @@ var/rotting = 0 var/damage = 0 - var/damage_cap = 100 //Wall will break down to girders if damage reaches this point - var/armor = 0.5 // Damage is multiplied by this + var/damage_cap = 150 //Wall will break down to girders if damage reaches this point var/damage_overlay var/global/damage_overlays[8] @@ -30,7 +29,7 @@ return //cap the amount of damage, so that things like emitters can't destroy walls in one hit. - var/damage = min(Proj.damage, 100) * armor + var/damage = min(Proj.damage, 100) take_damage(damage) return @@ -39,12 +38,12 @@ ..() if(ismob(AM)) return - + var/tforce = AM:throwforce * (speed/THROWFORCE_SPEED_DIVISOR) if (tforce < 15) return - - take_damage(tforce * armor) + + take_damage(tforce) /turf/simulated/wall/Del() for(var/obj/effect/E in src) if(E.name == "Wallrot") del E @@ -475,7 +474,7 @@ else if(istype(W,/obj/item/weapon/rcd)) //I bitterly resent having to write this. ~Z return - + else if(istype(W, /obj/item/weapon/reagent_containers)) return // They tend to have meaningful afterattack - let them apply it without destroying a rotting wall diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm index b08363a7153..5eddfc8b71c 100644 --- a/code/game/turfs/simulated/walls_reinforced.dm +++ b/code/game/turfs/simulated/walls_reinforced.dm @@ -5,9 +5,8 @@ opacity = 1 density = 1 - damage_cap = 500 + damage_cap = 800 max_temperature = 6000 - armor = 0.1 // Only 10% damage from gunfire, it's made from strong alloys and stuff. walltype = "rwall" @@ -294,7 +293,7 @@ else if(istype(W, /obj/item/weapon/reagent_containers)) return // They tend to have meaningful afterattack - let them apply it without destroying a rotting wall - + //Finally, CHECKING FOR FALSE WALLS if it isn't damaged else if(!d_state) return attack_hand(user) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index a67e42ca2ba..dbf73d65fda 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -109,6 +109,9 @@ var/list/admin_verbs_fun = list( var/list/admin_verbs_spawn = list( /datum/admins/proc/spawn_atom, /*allows us to spawn instances*/ /client/proc/respawn_character, + /client/proc/FireLaser, + /client/proc/FireCannons, + /client/proc/ChangeIcarusPosition, /client/proc/virus2_editor ) var/list/admin_verbs_server = list( diff --git a/code/modules/admin/verbs/icarus.dm b/code/modules/admin/verbs/icarus.dm new file mode 100644 index 00000000000..cccda899b34 --- /dev/null +++ b/code/modules/admin/verbs/icarus.dm @@ -0,0 +1,125 @@ +/client/proc/FireLaser() + set name = "Fire the Icarus lasers" + set desc = "Fires a laser bolt at your position. You should only do this as a(n) (a)ghost" + set category = "Fun" + + if(!src.holder) + src << "Only administrators may use this command." + return + + Icarus_FireLaser(get_turf(src.mob)) + + +/client/proc/FireCannons() + set name = "Fire the Icarus cannons" + set desc = "Fires an explosive missile at your position. You should only do this as a(n) (a)ghost." + set category = "Fun" + + if(!src.holder) + src << "Only administrators may use this command." + return + + Icarus_FireCannon(get_turf(src.mob)) + + +/client/proc/ChangeIcarusPosition() + set name = "Adjust Icarus Position" + set desc = "Lets you chose the position of the Icarus in regards to the map." + set category = "Fun" + + if(!src.holder) + src << "Only administrators may use this command." + return + + Icarus_SetPosition(src) + +var/icarus_position = SOUTH + +proc/Icarus_FireLaser(var/turf/target) + // Find the world edge to fire from. + var/x = icarus_position & EAST ? world.maxx : icarus_position & WEST ? 1 : target.x + var/y = icarus_position & NORTH ? world.maxy : icarus_position & SOUTH ? 1 : target.y + var/x_off = x != target.x ? abs(target.x - x) : INFINITY + var/y_off = y != target.y ? abs(target.y - y) : INFINITY + // Get the minimum number of steps using the rise/run shit. + var/iterations = round(min(x_off, y_off)) - 14 // We cannot fire straight from the edge since teleport thing. + + // Now we can get the location of the start. + x = target.x + (icarus_position & EAST ? iterations : icarus_position & WEST ? -iterations : 0) + y = target.y + (icarus_position & NORTH ? iterations : icarus_position & SOUTH ? -iterations : 0) + + var/turf/start = locate(x, y, target.z) + + // should step down as: + // 1000, 500, 333, 250, 200, 167, 142, 125, 111, 100, 90 + var/damage = 1000 + for(var/i in 2 to 12) + var/obj/item/projectile/beam/in_chamber = new (start) + in_chamber.original = target + in_chamber.starting = start + in_chamber.silenced = 1 + in_chamber.yo = icarus_position & NORTH ? -1 : icarus_position & SOUTH ? 1 : 0 + in_chamber.xo = icarus_position & EAST ? -1 : icarus_position & WEST ? 1 : 0 + in_chamber.damage = damage + in_chamber.kill_count = 500 + in_chamber.process() + damage -= damage / i + sleep(-1) + + // Let everyone know what hit them. + var/obj/item/projectile/beam/in_chamber = new (start) + in_chamber.original = target + in_chamber.starting = start + in_chamber.silenced = 0 + in_chamber.yo = icarus_position & NORTH ? -1 : icarus_position & SOUTH ? 1 : 0 + in_chamber.xo = icarus_position & EAST ? -1 : icarus_position & WEST ? 1 : 0 + in_chamber.kill_count = 500 + in_chamber.damage = 0 + in_chamber.name = "point defense laser" + in_chamber.firer = "Icarus" // Never displayed, but we want this to display the hit message. + in_chamber.process() + +proc/Icarus_FireCannon(var/turf/target) + // Find the world edge to fire from. + var/x = icarus_position & EAST ? world.maxx : icarus_position & WEST ? 1 : target.x + var/y = icarus_position & NORTH ? world.maxy : icarus_position & SOUTH ? 1 : target.y + var/x_off = x != target.x ? abs(target.x - x) : INFINITY + var/y_off = y != target.y ? abs(target.y - y) : INFINITY + // Get the minimum number of steps using the rise/run shit. + var/iterations = round(min(x_off, y_off)) - 14 // We cannot fire straight from the edge since teleport thing. + + // Now we can get the location of the start. + x = target.x + (icarus_position & EAST ? iterations : icarus_position & WEST ? -iterations : 0) + y = target.y + (icarus_position & NORTH ? iterations : icarus_position & SOUTH ? -iterations : 0) + + var/turf/start = locate(x, y, target.z) + + // Now we find the corresponding turf on the other side of the level. + // Yeah, yeah. Overuse of the terinary operator. So sue me. + x = icarus_position & EAST ? 1 : icarus_position & WEST ? world.maxx : target.x + y = icarus_position & NORTH ? 1 : icarus_position & SOUTH ? world.maxy : target.y + x_off = x != target.x ? abs(target.x - x) : INFINITY + y_off = y != target.y ? abs(target.y - y) : INFINITY + iterations = round(min(x_off, y_off)) + x = target.x + (icarus_position & EAST ? -iterations : icarus_position & WEST ? iterations : 0) + y = target.y + (icarus_position & NORTH ? -iterations : icarus_position & SOUTH ? iterations : 0) + target = locate(x, y, target.z) + + // Finally fire the fucker. + var/obj/effect/meteor/small/projectile = new (start) + projectile.dest = target + projectile.name = "main gun projectile" // stealthy + projectile.hits = 6 + projectile.detonation_chance = 99 // it's a missile/cannon round thing! + + // Make sure it travels + spawn(0) + walk_towards(projectile, projectile.dest, 1) + +proc/Icarus_SetPosition(var/user) + var/global/list/directions = list("North" = 1, "North East" = 5, "East" = 4, "South East" = 6, "South" = 2, "South West" = 10, "West" = 8, "North West" = 9) + var/direction = input(user, "Where should the Icarus fire from?", "Icarus Comms") as null|anything in directions + if(!direction) + return + + icarus_position = directions[direction] \ No newline at end of file diff --git a/code/modules/client/preferences_gear.dm b/code/modules/client/preferences_gear.dm index d265babc1b7..d788a41cc96 100644 --- a/code/modules/client/preferences_gear.dm +++ b/code/modules/client/preferences_gear.dm @@ -375,88 +375,88 @@ var/global/list/gear_datums = list() /datum/gear/armband_cargo display_name = "armband, cargo" - path = /obj/item/clothing/tie/armband/cargo + path = /obj/item/clothing/accessory/armband/cargo slot = slot_tie cost = 1 /datum/gear/armband_emt display_name = "armband, EMT" - path = /obj/item/clothing/tie/armband/medgreen + path = /obj/item/clothing/accessory/armband/medgreen slot = slot_tie cost = 2 /datum/gear/armband_engineering display_name = "armband, engineering" - path = /obj/item/clothing/tie/armband/engine + path = /obj/item/clothing/accessory/armband/engine slot = slot_tie cost = 1 /datum/gear/armband_hydroponics display_name = "armband, hydroponics" - path = /obj/item/clothing/tie/armband/hydro + path = /obj/item/clothing/accessory/armband/hydro slot = slot_tie cost = 1 /datum/gear/armband_medical display_name = "armband, medical" - path = /obj/item/clothing/tie/armband/med + path = /obj/item/clothing/accessory/armband/med slot = slot_tie cost = 1 /datum/gear/armband display_name = "armband, red" - path = /obj/item/clothing/tie/armband + path = /obj/item/clothing/accessory/armband slot = slot_tie cost = 1 /datum/gear/armband_science display_name = "armband, science" - path = /obj/item/clothing/tie/armband/science + path = /obj/item/clothing/accessory/armband/science slot = slot_tie cost = 1 /datum/gear/armpit display_name = "shoulder holster" - path = /obj/item/clothing/tie/holster/armpit + path = /obj/item/clothing/accessory/holster/armpit slot = slot_tie cost = 2 allowed_roles = list("Captain", "Head of Personnel", "Security Officer", "Warden", "Head of Security") /datum/gear/tie_blue display_name = "tie, blue" - path = /obj/item/clothing/tie/blue + path = /obj/item/clothing/accessory/blue slot = slot_tie cost = 1 /datum/gear/tie_red display_name = "tie, red" - path = /obj/item/clothing/tie/red + path = /obj/item/clothing/accessory/red slot = slot_tie cost = 1 /datum/gear/tie_horrible display_name = "tie, socially disgraceful" - path = /obj/item/clothing/tie/horrible + path = /obj/item/clothing/accessory/horrible slot = slot_tie cost = 1 /datum/gear/brown_vest display_name = "webbing, engineering" - path = /obj/item/clothing/tie/storage/brown_vest + path = /obj/item/clothing/accessory/storage/brown_vest slot = slot_tie cost = 2 allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer") /datum/gear/black_vest display_name = "webbing, security" - path = /obj/item/clothing/tie/storage/black_vest + path = /obj/item/clothing/accessory/storage/black_vest slot = slot_tie cost = 2 allowed_roles = list("Security Officer","Head of Security","Warden") /datum/gear/webbing display_name = "webbing, simple" - path = /obj/item/clothing/tie/storage/webbing + path = /obj/item/clothing/accessory/storage/webbing slot = slot_tie cost = 2 diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index f6dc6cc3379..da569c6b615 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -68,7 +68,7 @@ /obj/item/clothing/head/helmet/refit_for_species(var/target_species) if(!species_restricted) return //this item doesn't use the species_restricted system - + //Set species_restricted list switch(target_species) if("Skrell") @@ -401,7 +401,7 @@ BLIND // can't see anything 2 = Report detailed damages 3 = Report location */ - var/obj/item/clothing/tie/hastie = null + var/list/accessories = list() var/displays_id = 1 sprite_sheets = list("Vox" = 'icons/mob/species/vox/uniform.dmi') @@ -410,28 +410,44 @@ BLIND // can't see anything var/mob/M = src.loc M.update_inv_w_uniform() +/obj/item/clothing/under/proc/can_attach_accessory(obj/item/clothing/accessory/A) + if(istype(A)) + .=1 + else + return 0 + if(accessories.len && (A.slot in list("utility","armband"))) + for(var/obj/item/clothing/accessory/AC in accessories) + if (AC.slot == A.slot) + return 0 + /obj/item/clothing/under/attackby(obj/item/I, mob/user) - if(hastie) - hastie.attackby(I, user) - return + if(istype(I, /obj/item/clothing/accessory)) + var/obj/item/clothing/accessory/A = I + if(can_attach_accessory(A)) + user.drop_item() + accessories += A + A.on_attached(src, user) - if(!hastie && istype(I, /obj/item/clothing/tie)) - user.drop_item() - hastie = I - hastie.on_attached(src, user) + if(istype(loc, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = loc + H.update_inv_w_uniform() - if(istype(loc, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = loc - H.update_inv_w_uniform() + return + else + user << "You cannot attach more accessories of this type to [src]." + if(accessories.len) + for(var/obj/item/clothing/accessory/A in accessories) + A.attackby(I, user) return ..() /obj/item/clothing/under/attack_hand(mob/user as mob) //only forward to the attached accessory if the clothing is equipped (not in a storage) - if(hastie && src.loc == user) - hastie.attack_hand(user) + if(accessories.len && src.loc == user) + for(var/obj/item/clothing/accessory/A in accessories) + A.attack_hand(user) return if ((ishuman(usr) || ismonkey(usr)) && src.loc == user) //make it harder to accidentally undress yourself @@ -468,8 +484,9 @@ BLIND // can't see anything user << "Its vital tracker appears to be enabled." if(3) user << "Its vital tracker and tracking beacon appear to be enabled." - if(hastie) - user << "\A [hastie] is clipped to it." + if(accessories.len) + for(var/obj/item/clothing/accessory/A in accessories) + user << "\A [A] is attached to it." /obj/item/clothing/under/proc/set_sensors(mob/usr as mob) var/mob/M = usr @@ -540,12 +557,12 @@ BLIND // can't see anything else usr << "You cannot roll down the uniform!" -/obj/item/clothing/under/proc/remove_accessory(mob/user as mob) - if(!hastie) +/obj/item/clothing/under/proc/remove_accessory(mob/user, obj/item/clothing/accessory/A) + if(!(A in accessories)) return - hastie.on_removed(user) - hastie = null + A.on_removed(user) + accessories -= A update_clothing_icon() /obj/item/clothing/under/verb/removetie() @@ -554,14 +571,20 @@ BLIND // can't see anything set src in usr if(!istype(usr, /mob/living)) return if(usr.stat) return - - src.remove_accessory(usr) + if(!accessories.len) return + var/obj/item/clothing/accessory/A + if(accessories.len > 1) + A = input("Select an accessory to remove from [src]") as null|anything in accessories + else + A = accessories[1] + src.remove_accessory(usr,A) /obj/item/clothing/under/rank/New() sensor_mode = pick(0,1,2,3) ..() /obj/item/clothing/under/emp_act(severity) - if (hastie) - hastie.emp_act(severity) + if(accessories.len) + for(var/obj/item/clothing/accessory/A in accessories) + A.emp_act(severity) ..() \ No newline at end of file diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 3d5d2d9940b..7549e9cbe5d 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -196,7 +196,7 @@ slowdown = 1 armor = list(melee = 60, bullet = 60, laser = 60, energy = 40, bomb = 20, bio = 0, rad = 0) siemens_coefficient = 0.7 - var/obj/item/clothing/tie/holster/holster + var/obj/item/clothing/accessory/holster/holster /obj/item/clothing/suit/armor/tactical/New() ..() @@ -216,13 +216,12 @@ if(!holster.holstered) var/obj/item/W = usr.get_active_hand() if(!istype(W, /obj/item)) - usr << "\blue You need your gun equiped to holster it." + usr << "You need your gun equiped to holster it." return holster.holster(W, usr) else holster.unholster(usr) - //Non-hardsuit ERT armor. /obj/item/clothing/suit/armor/vest/ert name = "emergency response team armor" diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm new file mode 100644 index 00000000000..e1c9a25c248 --- /dev/null +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -0,0 +1,226 @@ +/obj/item/clothing/accessory + name = "tie" + desc = "A neosilk clip-on tie." + icon = 'icons/obj/clothing/ties.dmi' + icon_state = "bluetie" + item_state = "" //no inhands + item_color = "bluetie" + slot_flags = SLOT_TIE + w_class = 2.0 + var/slot = "decor" + var/obj/item/clothing/under/has_suit = null //the suit the tie may be attached to + var/image/inv_overlay = null //overlay used when attached to clothing. + +/obj/item/clothing/accessory/New() + ..() + inv_overlay = image("icon" = 'icons/obj/clothing/ties_overlay.dmi', "icon_state" = "[item_color? "[item_color]" : "[icon_state]"]") + +//when user attached an accessory to S +/obj/item/clothing/accessory/proc/on_attached(obj/item/clothing/under/S, mob/user as mob) + if(!istype(S)) + return + has_suit = S + loc = has_suit + has_suit.overlays += inv_overlay + + user << "You attach [src] to [has_suit]." + src.add_fingerprint(user) + +/obj/item/clothing/accessory/proc/on_removed(mob/user as mob) + if(!has_suit) + return + has_suit.overlays -= inv_overlay + has_suit = null + usr.put_in_hands(src) + src.add_fingerprint(user) + +//default attackby behaviour +/obj/item/clothing/accessory/attackby(obj/item/I, mob/user) + ..() + +//default attack_hand behaviour +/obj/item/clothing/accessory/attack_hand(mob/user as mob) + if(has_suit) + return //we aren't an object on the ground so don't call parent + ..() + +/obj/item/clothing/accessory/blue + name = "blue tie" + icon_state = "bluetie" + item_color = "bluetie" + +/obj/item/clothing/accessory/red + name = "red tie" + icon_state = "redtie" + item_color = "redtie" + +/obj/item/clothing/accessory/horrible + name = "horrible tie" + desc = "A neosilk clip-on tie. This one is disgusting." + icon_state = "horribletie" + item_color = "horribletie" + +/obj/item/clothing/accessory/stethoscope + name = "stethoscope" + desc = "An outdated medical apparatus for listening to the sounds of the human body. It also makes you look like you know what you're doing." + icon_state = "stethoscope" + item_color = "stethoscope" + +/obj/item/clothing/accessory/stethoscope/attack(mob/living/carbon/human/M, mob/living/user) + if(ishuman(M) && isliving(user)) + if(user.a_intent == "help") + var/body_part = parse_zone(user.zone_sel.selecting) + if(body_part) + var/their = "their" + switch(M.gender) + if(MALE) their = "his" + if(FEMALE) their = "her" + + var/sound = "pulse" + var/sound_strength + + if(M.stat == DEAD || (M.status_flags&FAKEDEATH)) + sound_strength = "cannot hear" + sound = "anything" + else + sound_strength = "hear a weak" + switch(body_part) + if("chest") + if(M.oxyloss < 50) + sound_strength = "hear a healthy" + sound = "pulse and respiration" + if("eyes","mouth") + sound_strength = "cannot hear" + sound = "anything" + else + sound_strength = "hear a weak" + + user.visible_message("[user] places [src] against [M]'s [body_part] and listens attentively.", "You place [src] against [their] [body_part]. You [sound_strength] [sound].") + return + return ..(M,user) + + +//Medals +/obj/item/clothing/accessory/medal + name = "bronze medal" + desc = "A bronze medal." + icon_state = "bronze" + item_color = "bronze" + +/obj/item/clothing/accessory/medal/conduct + name = "distinguished conduct medal" + desc = "A bronze medal awarded for distinguished conduct. Whilst a great honor, this is most basic award given by Nanotrasen. It is often awarded by a captain to a member of his crew." + +/obj/item/clothing/accessory/medal/bronze_heart + name = "bronze heart medal" + desc = "A bronze heart-shaped medal awarded for sacrifice. It is often awarded posthumously or for severe injury in the line of duty." + icon_state = "bronze_heart" + +/obj/item/clothing/accessory/medal/nobel_science + name = "nobel sciences award" + desc = "A bronze medal which represents significant contributions to the field of science or engineering." + +/obj/item/clothing/accessory/medal/silver + name = "silver medal" + desc = "A silver medal." + icon_state = "silver" + item_color = "silver" + +/obj/item/clothing/accessory/medal/silver/valor + name = "medal of valor" + desc = "A silver medal awarded for acts of exceptional valor." + +/obj/item/clothing/accessory/medal/silver/security + name = "robust security award" + desc = "An award for distinguished combat and sacrifice in defence of Nanotrasen's commercial interests. Often awarded to security staff." + +/obj/item/clothing/accessory/medal/gold + name = "gold medal" + desc = "A prestigious golden medal." + icon_state = "gold" + item_color = "gold" + +/obj/item/clothing/accessory/medal/gold/captain + name = "medal of captaincy" + desc = "A golden medal awarded exclusively to those promoted to the rank of captain. It signifies the codified responsibilities of a captain to Nanotrasen, and their undisputable authority over their crew." + +/obj/item/clothing/accessory/medal/gold/heroism + name = "medal of exceptional heroism" + desc = "An extremely rare golden medal awarded only by CentComm. To recieve such a medal is the highest honor and as such, very few exist. This medal is almost never awarded to anybody but commanders." + +/* + Holobadges are worn on the belt or neck, and can be used to show that the holder is an authorized + Security agent - the user details can be imprinted on the badge with a Security-access ID card, + or they can be emagged to accept any ID for use in disguises. +*/ + +/obj/item/clothing/accessory/holobadge + name = "holobadge" + desc = "This glowing blue badge marks the holder as THE LAW." + icon_state = "holobadge" + item_color = "holobadge" + slot_flags = SLOT_BELT | SLOT_TIE + + var/emagged = 0 //Emagging removes Sec check. + var/stored_name = null + +/obj/item/clothing/accessory/holobadge/cord + icon_state = "holobadge-cord" + item_color = "holobadge-cord" + slot_flags = SLOT_MASK | SLOT_TIE + +/obj/item/clothing/accessory/holobadge/attack_self(mob/user as mob) + if(!stored_name) + user << "Waving around a badge before swiping an ID would be pretty pointless." + return + if(isliving(user)) + 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)) + + var/obj/item/weapon/card/id/id_card = null + + if(istype(O, /obj/item/weapon/card/id)) + id_card = O + else + var/obj/item/device/pda/pda = O + id_card = pda.id + + if(access_security in id_card.access || emagged) + user << "You imprint your ID details onto the badge." + stored_name = id_card.registered_name + name = "holobadge ([stored_name])" + desc = "This glowing blue badge marks [stored_name] as THE LAW." + else + user << "[src] rejects your insufficient access rights." + return + ..() + +/obj/item/clothing/accessory/holobadge/attack(mob/living/carbon/human/M, mob/living/user) + if(isliving(user)) + user.visible_message("\red [user] invades [M]'s personal space, thrusting [src] into their face insistently.","\red You invade [M]'s personal space, thrusting [src] into their face insistently. You are the law.") + +/obj/item/weapon/storage/box/holobadge + name = "holobadge box" + desc = "A box claiming to contain holobadges." + New() + new /obj/item/clothing/accessory/holobadge(src) + new /obj/item/clothing/accessory/holobadge(src) + new /obj/item/clothing/accessory/holobadge(src) + new /obj/item/clothing/accessory/holobadge(src) + new /obj/item/clothing/accessory/holobadge/cord(src) + new /obj/item/clothing/accessory/holobadge/cord(src) + ..() + return + diff --git a/code/modules/clothing/under/accessories/armband.dm b/code/modules/clothing/under/accessories/armband.dm new file mode 100644 index 00000000000..67d0208b6df --- /dev/null +++ b/code/modules/clothing/under/accessories/armband.dm @@ -0,0 +1,42 @@ +/obj/item/clothing/accessory/armband + name = "red armband" + desc = "A fancy red armband!" + icon_state = "red" + item_color = "red" + slot = "armband" + +/obj/item/clothing/accessory/armband/cargo + name = "cargo armband" + desc = "An armband, worn by the crew to display which department they're assigned to. This one is brown." + icon_state = "cargo" + item_color = "cargo" + +/obj/item/clothing/accessory/armband/engine + name = "engineering armband" + desc = "An armband, worn by the crew to display which department they're assigned to. This one is orange with a reflective strip!" + icon_state = "engie" + item_color = "engie" + +/obj/item/clothing/accessory/armband/science + name = "science armband" + desc = "An armband, worn by the crew to display which department they're assigned to. This one is purple." + icon_state = "rnd" + item_color = "rnd" + +/obj/item/clothing/accessory/armband/hydro + name = "hydroponics armband" + desc = "An armband, worn by the crew to display which department they're assigned to. This one is green and blue." + icon_state = "hydro" + item_color = "hydro" + +/obj/item/clothing/accessory/armband/med + name = "medical armband" + desc = "An armband, worn by the crew to display which department they're assigned to. This one is white." + icon_state = "med" + item_color = "med" + +/obj/item/clothing/accessory/armband/medgreen + name = "EMT armband" + desc = "An armband, worn by the crew to display which department they're assigned to. This one is white and green." + icon_state = "medgreen" + item_color = "medgreen" diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm new file mode 100644 index 00000000000..1a18604b6f4 --- /dev/null +++ b/code/modules/clothing/under/accessories/holster.dm @@ -0,0 +1,115 @@ +/obj/item/clothing/accessory/holster + name = "shoulder holster" + desc = "A handgun holster." + icon_state = "holster" + item_color = "holster" + slot = "utility" + var/obj/item/holstered = null + +/obj/item/clothing/accessory/holster/proc/holster(obj/item/I, mob/user as mob) + if(holstered) + user << "There is already \a [holstered] holstered here!" + return + + if (!(I.slot_flags & SLOT_HOLSTER)) + user << "[I] won't fit in [src]!" + return + + holstered = I + user.drop_from_inventory(holstered) + holstered.loc = src + holstered.add_fingerprint(user) + user.visible_message("[user] holsters \the [holstered].", "You holster \the [holstered].") + +/obj/item/clothing/accessory/holster/proc/unholster(mob/user as mob) + if(!holstered) + return + + if(istype(user.get_active_hand(),/obj) && istype(user.get_inactive_hand(),/obj)) + user << "You need an empty hand to draw \the [holstered]!" + else + if(user.a_intent == "hurt") + usr.visible_message( + "\red [user] draws \the [holstered], ready to shoot!", + "You draw \the [holstered], ready to shoot!" + ) + else + user.visible_message( + "[user] draws \the [holstered], pointing it at the ground.", + "You draw \the [holstered], pointing it at the ground." + ) + user.put_in_hands(holstered) + holstered.add_fingerprint(user) + holstered = null + +/obj/item/clothing/accessory/holster/attack_hand(mob/user as mob) + if (has_suit) //if we are part of a suit + if (holstered) + unholster(user) + return + + ..(user) + +/obj/item/clothing/accessory/holster/attackby(obj/item/W as obj, mob/user as mob) + holster(W, user) + +/obj/item/clothing/accessory/holster/emp_act(severity) + if (holstered) + holstered.emp_act(severity) + ..() + +/obj/item/clothing/accessory/holster/examine(mob/user) + ..(user) + if (holstered) + user << "A [holstered] is holstered here." + else + user << "It is empty." + +/obj/item/clothing/accessory/holster/on_attached(obj/item/clothing/under/S, mob/user as mob) + ..() + has_suit.verbs += /obj/item/clothing/accessory/holster/verb/holster_verb + +/obj/item/clothing/accessory/holster/on_removed(mob/user as mob) + has_suit.verbs -= /obj/item/clothing/accessory/holster/verb/holster_verb + ..() + +//For the holster hotkey +/obj/item/clothing/accessory/holster/verb/holster_verb() + set name = "Holster" + set category = "Object" + set src in usr + if(!istype(usr, /mob/living)) return + if(usr.stat) return + + //can't we just use src here? + var/obj/item/clothing/accessory/holster/H = null + if (istype(src, /obj/item/clothing/accessory/holster)) + H = src + else if (istype(src, /obj/item/clothing/under)) + var/obj/item/clothing/under/S = src + if (S.accessories.len) + H = locate() in S.accessories + + if (!H) + usr << "Something is very wrong." + + if(!H.holstered) + var/obj/item/W = usr.get_active_hand() + if(!istype(W, /obj/item)) + usr << "You need your gun equiped to holster it." + return + H.holster(W, usr) + else + H.unholster(usr) + +/obj/item/clothing/accessory/holster/armpit + name = "shoulder holster" + desc = "A worn-out handgun holster. Perfect for concealed carry" + icon_state = "holster" + item_color = "holster" + +/obj/item/clothing/accessory/holster/waist + name = "shoulder holster" + desc = "A handgun holster. Made of expensive leather." + icon_state = "holster" + item_color = "holster_low" \ No newline at end of file diff --git a/code/modules/clothing/under/accessories/storage.dm b/code/modules/clothing/under/accessories/storage.dm new file mode 100644 index 00000000000..32313e985d9 --- /dev/null +++ b/code/modules/clothing/under/accessories/storage.dm @@ -0,0 +1,86 @@ +/obj/item/clothing/accessory/storage + name = "load bearing equipment" + desc = "Used to hold things when you don't have enough hands." + icon_state = "webbing" + item_color = "webbing" + slot = "utility" + var/slots = 3 + var/obj/item/weapon/storage/internal/hold + +/obj/item/clothing/accessory/storage/New() + ..() + hold = new/obj/item/weapon/storage/internal(src) + hold.storage_slots = slots + +/obj/item/clothing/accessory/storage/attack_hand(mob/user as mob) + if (has_suit) //if we are part of a suit + hold.open(user) + return + + if (hold.handle_attack_hand(user)) //otherwise interact as a regular storage item + ..(user) + +/obj/item/clothing/accessory/storage/MouseDrop(obj/over_object as obj) + if (has_suit) + return + + if (hold.handle_mousedrop(usr, over_object)) + ..(over_object) + +/obj/item/clothing/accessory/storage/attackby(obj/item/W as obj, mob/user as mob) + return hold.attackby(W, user) + +/obj/item/clothing/accessory/storage/emp_act(severity) + hold.emp_act(severity) + ..() + +/obj/item/clothing/accessory/storage/hear_talk(mob/M, var/msg, verb, datum/language/speaking) + hold.hear_talk(M, msg, verb, speaking) + ..() + +/obj/item/clothing/accessory/storage/attack_self(mob/user as mob) + user << "You empty [src]." + var/turf/T = get_turf(src) + hold.hide_from(usr) + for(var/obj/item/I in hold.contents) + hold.remove_from_storage(I, T) + src.add_fingerprint(user) + +/obj/item/clothing/accessory/storage/webbing + name = "webbing" + desc = "Strudy mess of synthcotton belts and buckles, ready to share your burden." + icon_state = "webbing" + item_color = "webbing" + +/obj/item/clothing/accessory/storage/black_vest + name = "black webbing vest" + desc = "Robust black synthcotton vest with lots of pockets to hold whatever you need, but cannot hold in hands." + icon_state = "vest_black" + item_color = "vest_black" + slots = 5 + +/obj/item/clothing/accessory/storage/brown_vest + name = "brown webbing vest" + desc = "Worn brownish synthcotton vest with lots of pockets to unload your hands." + icon_state = "vest_brown" + item_color = "vest_brown" + slots = 5 + +/obj/item/clothing/accessory/storage/knifeharness + name = "decorated harness" + desc = "A heavily decorated harness of sinew and leather with two knife-loops." + icon_state = "unathiharness2" + item_color = "unathiharness2" + slots = 2 + +/obj/item/clothing/accessory/storage/knifeharness/New() + ..() + hold.max_combined_w_class = 4 + hold.can_hold = list("/obj/item/weapon/hatchet/unathiknife",\ + "/obj/item/weapon/kitchen/utensil/knife",\ + "/obj/item/weapon/kitchen/utensil/pknife",\ + "/obj/item/weapon/kitchenknife",\ + "/obj/item/weapon/kitchenknife/ritual") + + new /obj/item/weapon/hatchet/unathiknife(hold) + new /obj/item/weapon/hatchet/unathiknife(hold) \ No newline at end of file diff --git a/code/modules/clothing/under/jobs/medsci.dm b/code/modules/clothing/under/jobs/medsci.dm index 40bc087429d..b1554dd02ab 100644 --- a/code/modules/clothing/under/jobs/medsci.dm +++ b/code/modules/clothing/under/jobs/medsci.dm @@ -130,6 +130,12 @@ icon_state = "scrubspurple" item_color = "scrubspurple" +/obj/item/clothing/under/rank/medical/black + name = "medical scrubs" + desc = "It's made of a special fiber that provides minor protection against biohazards. This one is in black." + icon_state = "scrubsblack" + item_color = "scrubsblack" + /obj/item/clothing/under/rank/psych desc = "A basic white jumpsuit. It has turqouise markings that denote the wearer as a psychiatrist." name = "psychiatrist's jumpsuit" diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 390ec7f5417..bc4d37c672f 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -479,9 +479,9 @@ /obj/item/clothing/under/serviceoveralls name = "Workman outfit" desc = "The very image of a working man. Not that you're probably doing work." - icon_state = "mechanic_s" - item_state = "mechanic_s" - item_color = "mechanic_s" + icon_state = "mechanic" + item_state = "mechanic" + item_color = "mechanic" /obj/item/clothing/under/cheongsam name = "White Cheongsam" diff --git a/code/modules/clothing/under/ties.dm b/code/modules/clothing/under/ties.dm deleted file mode 100644 index 073b7a37576..00000000000 --- a/code/modules/clothing/under/ties.dm +++ /dev/null @@ -1,470 +0,0 @@ -/obj/item/clothing/tie - name = "tie" - desc = "A neosilk clip-on tie." - icon = 'icons/obj/clothing/ties.dmi' - icon_state = "bluetie" - item_state = "" //no inhands - item_color = "bluetie" - slot_flags = SLOT_TIE - w_class = 2.0 - var/obj/item/clothing/under/has_suit = null //the suit the tie may be attached to - var/image/inv_overlay = null //overlay used when attached to clothing. - -/obj/item/clothing/tie/New() - ..() - inv_overlay = image("icon" = 'icons/obj/clothing/ties_overlay.dmi', "icon_state" = "[item_color? "[item_color]" : "[icon_state]"]") - -//when user attached an accessory to S -/obj/item/clothing/tie/proc/on_attached(obj/item/clothing/under/S, mob/user as mob) - if(!istype(S)) - return - has_suit = S - loc = has_suit - has_suit.overlays += inv_overlay - - user << "You attach [src] to [has_suit]." - src.add_fingerprint(user) - -/obj/item/clothing/tie/proc/on_removed(mob/user as mob) - if(!has_suit) - return - has_suit.overlays -= inv_overlay - has_suit = null - usr.put_in_hands(src) - src.add_fingerprint(user) - -//default attackby behaviour -/obj/item/clothing/tie/attackby(obj/item/I, mob/user) - ..() - -//default attack_hand behaviour -/obj/item/clothing/tie/attack_hand(mob/user as mob) - if(has_suit) - has_suit.remove_accessory(user) - return //we aren't an object on the ground so don't call parent - ..() - -/obj/item/clothing/tie/blue - name = "blue tie" - icon_state = "bluetie" - item_color = "bluetie" - -/obj/item/clothing/tie/red - name = "red tie" - icon_state = "redtie" - item_color = "redtie" - -/obj/item/clothing/tie/horrible - name = "horrible tie" - desc = "A neosilk clip-on tie. This one is disgusting." - icon_state = "horribletie" - item_color = "horribletie" - -/obj/item/clothing/tie/stethoscope - name = "stethoscope" - desc = "An outdated medical apparatus for listening to the sounds of the human body. It also makes you look like you know what you're doing." - icon_state = "stethoscope" - item_color = "stethoscope" - -/obj/item/clothing/tie/stethoscope/attack(mob/living/carbon/human/M, mob/living/user) - if(ishuman(M) && isliving(user)) - if(user.a_intent == "help") - var/body_part = parse_zone(user.zone_sel.selecting) - if(body_part) - var/their = "their" - switch(M.gender) - if(MALE) their = "his" - if(FEMALE) their = "her" - - var/sound = "pulse" - var/sound_strength - - if(M.stat == DEAD || (M.status_flags&FAKEDEATH)) - sound_strength = "cannot hear" - sound = "anything" - else - sound_strength = "hear a weak" - switch(body_part) - if("chest") - if(M.oxyloss < 50) - sound_strength = "hear a healthy" - sound = "pulse and respiration" - if("eyes","mouth") - sound_strength = "cannot hear" - sound = "anything" - else - sound_strength = "hear a weak" - - user.visible_message("[user] places [src] against [M]'s [body_part] and listens attentively.", "You place [src] against [their] [body_part]. You [sound_strength] [sound].") - return - return ..(M,user) - - -//Medals -/obj/item/clothing/tie/medal - name = "bronze medal" - desc = "A bronze medal." - icon_state = "bronze" - item_color = "bronze" - -/obj/item/clothing/tie/medal/conduct - name = "distinguished conduct medal" - desc = "A bronze medal awarded for distinguished conduct. Whilst a great honor, this is most basic award given by Nanotrasen. It is often awarded by a captain to a member of his crew." - -/obj/item/clothing/tie/medal/bronze_heart - name = "bronze heart medal" - desc = "A bronze heart-shaped medal awarded for sacrifice. It is often awarded posthumously or for severe injury in the line of duty." - icon_state = "bronze_heart" - -/obj/item/clothing/tie/medal/nobel_science - name = "nobel sciences award" - desc = "A bronze medal which represents significant contributions to the field of science or engineering." - -/obj/item/clothing/tie/medal/silver - name = "silver medal" - desc = "A silver medal." - icon_state = "silver" - item_color = "silver" - -/obj/item/clothing/tie/medal/silver/valor - name = "medal of valor" - desc = "A silver medal awarded for acts of exceptional valor." - -/obj/item/clothing/tie/medal/silver/security - name = "robust security award" - desc = "An award for distinguished combat and sacrifice in defence of Nanotrasen's commercial interests. Often awarded to security staff." - -/obj/item/clothing/tie/medal/gold - name = "gold medal" - desc = "A prestigious golden medal." - icon_state = "gold" - item_color = "gold" - -/obj/item/clothing/tie/medal/gold/captain - name = "medal of captaincy" - desc = "A golden medal awarded exclusively to those promoted to the rank of captain. It signifies the codified responsibilities of a captain to Nanotrasen, and their undisputable authority over their crew." - -/obj/item/clothing/tie/medal/gold/heroism - name = "medal of exceptional heroism" - desc = "An extremely rare golden medal awarded only by CentComm. To recieve such a medal is the highest honor and as such, very few exist. This medal is almost never awarded to anybody but commanders." - -//Armbands -/obj/item/clothing/tie/armband - name = "red armband" - desc = "A fancy red armband!" - icon_state = "red" - item_color = "red" - -/obj/item/clothing/tie/armband/cargo - name = "cargo armband" - desc = "An armband, worn by the crew to display which department they're assigned to. This one is brown." - icon_state = "cargo" - item_color = "cargo" - -/obj/item/clothing/tie/armband/engine - name = "engineering armband" - desc = "An armband, worn by the crew to display which department they're assigned to. This one is orange with a reflective strip!" - icon_state = "engie" - item_color = "engie" - -/obj/item/clothing/tie/armband/science - name = "science armband" - desc = "An armband, worn by the crew to display which department they're assigned to. This one is purple." - icon_state = "rnd" - item_color = "rnd" - -/obj/item/clothing/tie/armband/hydro - name = "hydroponics armband" - desc = "An armband, worn by the crew to display which department they're assigned to. This one is green and blue." - icon_state = "hydro" - item_color = "hydro" - -/obj/item/clothing/tie/armband/med - name = "medical armband" - desc = "An armband, worn by the crew to display which department they're assigned to. This one is white." - icon_state = "med" - item_color = "med" - -/obj/item/clothing/tie/armband/medgreen - name = "EMT armband" - desc = "An armband, worn by the crew to display which department they're assigned to. This one is white and green." - icon_state = "medgreen" - item_color = "medgreen" - -//holsters -/obj/item/clothing/tie/holster - name = "shoulder holster" - desc = "A handgun holster." - icon_state = "holster" - item_color = "holster" - var/obj/item/holstered = null - -/obj/item/clothing/tie/holster/proc/holster(obj/item/I, mob/user as mob) - if(holstered) - user << "There is already \a [holstered] holstered here!" - return - - if (!(I.slot_flags & SLOT_HOLSTER)) - user << "[I] won't fit in [src]!" - return - - holstered = I - user.drop_from_inventory(holstered) - holstered.loc = src - holstered.add_fingerprint(user) - user.visible_message("[user] holsters [holstered].", "You holster [holstered].") - -/obj/item/clothing/tie/holster/proc/unholster(mob/user as mob) - if(!holstered) - return - - if(istype(user.get_active_hand(),/obj) && istype(user.get_inactive_hand(),/obj)) - user << "You need an empty hand to draw [holstered]!" - else - if(user.a_intent == "hurt") - usr.visible_message( - "[user] draws [holstered], ready to shoot!", - "You draw [holstered], ready to shoot!" - ) - else - user.visible_message( - "[user] draws [holstered], pointing it at the ground.", - "You draw [holstered], pointing it at the ground." - ) - user.put_in_hands(holstered) - holstered.add_fingerprint(user) - holstered = null - -/obj/item/clothing/tie/holster/attack_hand(mob/user as mob) - if (has_suit) //if we are part of a suit - if (holstered) - unholster(user) - return - - ..(user) - -/obj/item/clothing/tie/holster/attackby(obj/item/W as obj, mob/user as mob) - holster(W, user) - -/obj/item/clothing/tie/holster/emp_act(severity) - if (holstered) - holstered.emp_act(severity) - ..() - -/obj/item/clothing/tie/holster/examine(mob/user) - ..(user) - if (holstered) - user << "A [holstered] is holstered here." - else - user << "It is empty." - -/obj/item/clothing/tie/holster/on_attached(obj/item/clothing/under/S, mob/user as mob) - ..() - has_suit.verbs += /obj/item/clothing/tie/holster/verb/holster_verb - -/obj/item/clothing/tie/holster/on_removed(mob/user as mob) - has_suit.verbs -= /obj/item/clothing/tie/holster/verb/holster_verb - ..() - -//For the holster hotkey -/obj/item/clothing/tie/holster/verb/holster_verb() - set name = "Holster" - set category = "Object" - set src in usr - if(!istype(usr, /mob/living)) return - if(usr.stat) return - - //can't we just use src here? - var/obj/item/clothing/tie/holster/H = null - if (istype(src, /obj/item/clothing/tie/holster)) - H = src - else if (istype(src, /obj/item/clothing/under)) - var/obj/item/clothing/under/S = src - if (S.hastie) - H = S.hastie - - if (!H) - usr << "\red Something is very wrong." - - if(!H.holstered) - var/obj/item/W = usr.get_active_hand() - if(!istype(W, /obj/item)) - usr << "\blue You need your gun equiped to holster it." - return - H.holster(W, usr) - else - H.unholster(usr) - -/obj/item/clothing/tie/holster/armpit - name = "shoulder holster" - desc = "A worn-out handgun holster. Perfect for concealed carrying." - icon_state = "holster" - item_color = "holster" - -/obj/item/clothing/tie/holster/waist - name = "shoulder holster" - desc = "A handgun holster. Made of expensive leather." - icon_state = "holster" - item_color = "holster_low" - -/obj/item/clothing/tie/storage - name = "load bearing equipment" - desc = "Used to hold things when you don't have enough hands." - icon_state = "webbing" - item_color = "webbing" - var/slots = 3 - var/obj/item/weapon/storage/internal/hold - -/obj/item/clothing/tie/storage/New() - ..() - hold = new/obj/item/weapon/storage/internal(src) - hold.storage_slots = slots - -/obj/item/clothing/tie/storage/attack_hand(mob/user as mob) - if (has_suit) //if we are part of a suit - hold.open(user) - return - - if (hold.handle_attack_hand(user)) //otherwise interact as a regular storage item - ..(user) - -/obj/item/clothing/tie/storage/MouseDrop(obj/over_object as obj) - if (has_suit) - return - - if (hold.handle_mousedrop(usr, over_object)) - ..(over_object) - -/obj/item/clothing/tie/storage/attackby(obj/item/W as obj, mob/user as mob) - return hold.attackby(W, user) - -/obj/item/clothing/tie/storage/emp_act(severity) - hold.emp_act(severity) - ..() - -/obj/item/clothing/tie/storage/hear_talk(mob/M, var/msg, verb, datum/language/speaking) - hold.hear_talk(M, msg, verb, speaking) - ..() - -/obj/item/clothing/tie/storage/attack_self(mob/user as mob) - user << "You empty [src]." - var/turf/T = get_turf(src) - hold.hide_from(usr) - for(var/obj/item/I in hold.contents) - hold.remove_from_storage(I, T) - src.add_fingerprint(user) - -/obj/item/clothing/tie/storage/webbing - name = "webbing" - desc = "Strudy mess of synthcotton belts and buckles, ready to share your burden." - icon_state = "webbing" - item_color = "webbing" - -/obj/item/clothing/tie/storage/black_vest - name = "black webbing vest" - desc = "Robust black synthcotton vest with lots of pockets to hold whatever you need, but cannot hold in hands." - icon_state = "vest_black" - item_color = "vest_black" - slots = 5 - -/obj/item/clothing/tie/storage/brown_vest - name = "brown webbing vest" - desc = "Worn brownish synthcotton vest with lots of pockets to unload your hands." - icon_state = "vest_brown" - item_color = "vest_brown" - slots = 5 -/* - Holobadges are worn on the belt or neck, and can be used to show that the holder is an authorized - Security agent - the user details can be imprinted on the badge with a Security-access ID card, - or they can be emagged to accept any ID for use in disguises. -*/ - -/obj/item/clothing/tie/holobadge - - name = "holobadge" - desc = "This glowing blue badge marks the holder as THE LAW." - icon_state = "holobadge" - item_color = "holobadge" - slot_flags = SLOT_BELT | SLOT_TIE - - var/emagged = 0 //Emagging removes Sec check. - var/stored_name = null - -/obj/item/clothing/tie/holobadge/cord - icon_state = "holobadge-cord" - item_color = "holobadge-cord" - slot_flags = SLOT_MASK | SLOT_TIE - -/obj/item/clothing/tie/holobadge/attack_self(mob/user as mob) - if(!stored_name) - user << "Waving around a badge before swiping an ID would be pretty pointless." - return - if(isliving(user)) - 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/tie/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)) - - var/obj/item/weapon/card/id/id_card = null - - if(istype(O, /obj/item/weapon/card/id)) - id_card = O - else - var/obj/item/device/pda/pda = O - id_card = pda.id - - if(access_security in id_card.access || emagged) - user << "You imprint your ID details onto the badge." - stored_name = id_card.registered_name - name = "holobadge ([stored_name])" - desc = "This glowing blue badge marks [stored_name] as THE LAW." - else - user << "[src] rejects your insufficient access rights." - return - ..() - -/obj/item/clothing/tie/holobadge/attack(mob/living/carbon/human/M, mob/living/user) - if(isliving(user)) - user.visible_message("\red [user] invades [M]'s personal space, thrusting [src] into their face insistently.","\red You invade [M]'s personal space, thrusting [src] into their face insistently. You are the law.") - -/obj/item/weapon/storage/box/holobadge - name = "holobadge box" - desc = "A box claiming to contain holobadges." - New() - new /obj/item/clothing/tie/holobadge(src) - new /obj/item/clothing/tie/holobadge(src) - new /obj/item/clothing/tie/holobadge(src) - new /obj/item/clothing/tie/holobadge(src) - new /obj/item/clothing/tie/holobadge/cord(src) - new /obj/item/clothing/tie/holobadge/cord(src) - ..() - return - -/obj/item/clothing/tie/storage/knifeharness - name = "decorated harness" - desc = "A heavily decorated harness of sinew and leather with two knife-loops." - icon_state = "unathiharness2" - item_color = "unathiharness2" - slots = 2 - -/obj/item/clothing/tie/storage/knifeharness/New() - ..() - hold.max_combined_w_class = 4 - hold.can_hold = list("/obj/item/weapon/hatchet/unathiknife",\ - "/obj/item/weapon/kitchen/utensil/knife",\ - "/obj/item/weapon/kitchen/utensil/pknife",\ - "/obj/item/weapon/kitchenknife",\ - "/obj/item/weapon/kitchenknife/ritual") - - new /obj/item/weapon/hatchet/unathiknife(hold) - new /obj/item/weapon/hatchet/unathiknife(hold) diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 510417c0fb9..11a3fa03d48 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -114,7 +114,7 @@ /////////////////////// Cataguettes - Lucy's Stethoscope - Lucy Kemmerer ////// -/obj/item/clothing/tie/stethoscope/fluff/lucystethos +/obj/item/clothing/accessory/stethoscope/fluff/lucystethos name = "Lucy's Stethoscope" desc = "A medical apparatus intended to ease in listening to the sounds of the human body. This one looks cleaner and sparklier than the rest. There is a small silver plaque attached to the tubing, with the words 'Lucy Kemmerer' engraved on it." icon_state = "lucystethos" @@ -1111,22 +1111,33 @@ item_color = "lillian_dress" body_parts_covered = UPPER_TORSO|LOWER_TORSO -////// Cybernetic Casings - Parker Eliza - MrSnapwalk +////// Tailored Security Uniform - Parker Eliza - MrSnapwalk + /obj/item/clothing/under/fluff/parkereliza - name = "cybernetic casings" - desc = "A set of somewhat bulky white casings for robotic limbs, paired with a basic blue tank top and black cargo pants. The arms have a small label on the inner elbow, which reads \"Bishop Corporation Cybernetic Solutions\"." + name = "tailored security uniform" + desc = "A red uniform shirt (tailored for easy access to the shoulder joint) and black cargo pants, paired with a set of somewhat bulky white casings for robotic limbs. The arms have a small label on the inner elbow, which reads \"Bishop Corporation Cybernetic Solutions\"." icon = 'icons/obj/custom_items.dmi' icon_state = "parker_eliza" item_state = "parker_eliza" item_color = "parker_eliza" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS +////// Bishop "GOLEM" V2200 Industrial Limb Augments - Parker Eliza - MrSnapwalk + +/obj/item/clothing/suit/fluff/parkereliza + name = "Bishop \"GOLEM\" V2200 Industrial Limb Augments" + desc = "A set of top-of-the-line cyberlimbs, only usable to someone with extensive bone structure augmentation. Often used in industrial applications, they are capable of throwing a man clear across a room. The load limitation circuit in this set appears to be modified." + icon = 'icons/obj/custom_items.dmi' + icon_state = "parker_eliza_arms" + item_state = "parker_eliza_arms" + item_color = "parker_eliza_arms" + ////////////// Accessories ///// //////////////////// Blood Red Pendant - Mewth - Mu'taz Radi //////////////// -/obj/item/clothing/tie/fluff/radi +/obj/item/clothing/accessory/fluff/radi name = "Blood Red Pendant" desc = "A blue chained necklace with a ruby in the middle, it looks pretty!" icon = 'icons/obj/custom_items.dmi' @@ -1168,7 +1179,7 @@ ////// Small locket - Altair An-Nasaqan - Serithi -/obj/item/clothing/tie/fluff/altair_locket +/obj/item/clothing/accessory/fluff/altair_locket name = "small locket" desc = "A small golden locket attached to an Ii'rka-reed string. Inside the locket is a holo-picture of a female Tajaran, and an inscription writtin in Siik'mas." icon = 'icons/obj/custom_items.dmi' @@ -1181,7 +1192,7 @@ ////// Silver locket - Konaa Hirano - Konaa_Hirano -/obj/item/clothing/tie/fluff/konaa_hirano +/obj/item/clothing/accessory/fluff/konaa_hirano name = "silver locket" desc = "This oval shaped, argentium sterling silver locket hangs on an incredibly fine, refractive string, almost thin as hair and microweaved from links to a deceptive strength, of similar material. The edges are engraved very delicately with an elegant curving design, but overall the main is unmarked and smooth to the touch, leaving room for either remaining as a stolid piece or future alterations. There is an obvious internal place for a picture or lock of some sort, but even behind that is a very thin compartment unhinged with the pinch of a thumb and forefinger." icon = 'icons/obj/custom_items.dmi' @@ -1193,13 +1204,13 @@ slot_flags = SLOT_MASK | SLOT_TIE var/obj/item/held //Item inside locket. -/obj/item/clothing/tie/fluff/konaa_hirano/attack_self(mob/user as mob) +/obj/item/clothing/accessory/fluff/konaa_hirano/attack_self(mob/user as mob) if(held) user << "You open [src] and [held] falls out." held.loc = get_turf(user) src.held = null -/obj/item/clothing/tie/fluff/konaa_hirano/attackby(var/obj/item/O as obj, mob/user as mob) +/obj/item/clothing/accessory/fluff/konaa_hirano/attackby(var/obj/item/O as obj, mob/user as mob) if(istype(O,/obj/item/weapon/paper)) if(held) usr << "[src] already has something inside it." @@ -1213,7 +1224,7 @@ ////// Medallion - Nasir Khayyam - Jamini -/obj/item/clothing/tie/fluff/nasir_khayyam_1 +/obj/item/clothing/accessory/fluff/nasir_khayyam_1 name = "medallion" desc = "This silvered medallion bears the symbol of the Hadii Clan of the Tajaran." icon = 'icons/obj/custom_items.dmi' diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm index 263f797a95d..4afd4f0e44b 100644 --- a/code/modules/hydroponics/biogenerator.dm +++ b/code/modules/hydroponics/biogenerator.dm @@ -11,66 +11,80 @@ var/obj/item/weapon/reagent_containers/glass/beaker = null var/points = 0 var/menustat = "menu" + var/build_eff = 1 + var/eat_eff = 1 - New() - ..() - var/datum/reagents/R = new/datum/reagents(1000) - reagents = R - R.my_atom = src - beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src) +/obj/machinery/biogenerator/New() + ..() + var/datum/reagents/R = new/datum/reagents(1000) + reagents = R + R.my_atom = src + beaker = new /obj/item/weapon/reagent_containers/glass/bottle(src) - on_reagent_change() //When the reagents change, change the icon as well. - update_icon() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/biogenerator(src) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + RefreshParts() + +/obj/machinery/biogenerator/on_reagent_change() //When the reagents change, change the icon as well. update_icon() - if(!src.beaker) - icon_state = "biogen-empty" - else if(!src.processing) - icon_state = "biogen-stand" - else - icon_state = "biogen-work" - return + +/obj/machinery/biogenerator/update_icon() + if(!beaker) + icon_state = "biogen-empty" + else if(!processing) + icon_state = "biogen-stand" + else + icon_state = "biogen-work" + return /obj/machinery/biogenerator/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(default_deconstruction_screwdriver(user, O)) + return + if(default_deconstruction_crowbar(user, O)) + return + if(default_part_replacement(user, O)) + return if(istype(O, /obj/item/weapon/reagent_containers/glass)) if(beaker) - user << "\red The biogenerator is already loaded." + user << "]The [src] is already loaded." else user.before_take_item(O) O.loc = src beaker = O updateUsrDialog() else if(processing) - user << "\red The biogenerator is currently processing." + user << "\The [src] is currently processing." else if(istype(O, /obj/item/weapon/storage/bag/plants)) var/i = 0 for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in contents) i++ if(i >= 10) - user << "\red The biogenerator is already full! Activate it." + user << "\The [src] is already full! Activate it." else for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in O.contents) G.loc = src i++ if(i >= 10) - user << "\blue You fill the biogenerator to its capacity." + user << "You fill \the [src] to its capacity." break - if(i<10) - user << "\blue You empty the plant bag into the biogenerator." - + if(i < 10) + user << "You empty \the [O] into \the [src]." else if(!istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) - user << "\red You cannot put this in [src.name]" + user << "You cannot put this in \the [src]." else var/i = 0 for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in contents) i++ if(i >= 10) - user << "\red The biogenerator is full! Activate it." + user << "\The [src] is full! Activate it." else user.before_take_item(O) O.loc = src - user << "\blue You put [O.name] in [src.name]" + user << "You put \the [O] in \the [src]" update_icon() return @@ -89,18 +103,18 @@ dat += "Activate Biogenerator!
" dat += "Detach Container

" dat += "Food
" - dat += "10 milk (20)
" - dat += "Slab of meat (50)
" + dat += "10 milk ([round(20/build_eff)])
" + dat += "Slab of meat ([round(50/build_eff)])
" dat += "Nutrient
" - dat += "E-Z-Nutrient (10) | x5
" - dat += "Left 4 Zed (20) | x5
" - dat += "Robust Harvest (25) | x5
" + dat += "E-Z-Nutrient ([round(10/build_eff)]) | x5
" + dat += "Left 4 Zed ([round(20/build_eff)]) | x5
" + dat += "Robust Harvest ([round(25/build_eff)]) | x5
" dat += "Leather
" - dat += "Wallet (100)
" - dat += "Botanical gloves (250)
" - dat += "Utility belt (300)
" - dat += "Leather Satchel (400)
" - dat += "Cash Bag (400)
" + dat += "Wallet ([round(100/build_eff)])
" + dat += "Botanical gloves ([round(250/build_eff)])
" + dat += "Utility belt ([round(300/build_eff)])
" + dat += "Leather Satchel ([round(400/build_eff)])
" + dat += "Cash Bag ([round(400/build_eff)])
" //dat += "Other
" //dat += "Monkey (500)
" else @@ -122,34 +136,35 @@ interact(user) /obj/machinery/biogenerator/proc/activate() - if (usr.stat != 0) + if (usr.stat) return - if (src.stat != 0) //NOPOWER etc + if (stat) //NOPOWER etc return - if(src.processing) - usr << "\red The biogenerator is in the process of working." + if(processing) + usr << "The biogenerator is in the process of working." return var/S = 0 for(var/obj/item/weapon/reagent_containers/food/snacks/grown/I in contents) S += 5 if(I.reagents.get_reagent_amount("nutriment") < 0.1) points += 1 - else points += I.reagents.get_reagent_amount("nutriment")*10 + else points += I.reagents.get_reagent_amount("nutriment") * 10 * eat_eff del(I) if(S) processing = 1 update_icon() updateUsrDialog() playsound(src.loc, 'sound/machines/blender.ogg', 50, 1) - use_power(S*30) - sleep(S+15) + use_power(S * 30) + sleep((S + 15) / eat_eff) processing = 0 update_icon() else menustat = "void" return -/obj/machinery/biogenerator/proc/create_product(var/item,var/cost) +/obj/machinery/biogenerator/proc/create_product(var/item, var/cost) + cost = round(cost/build_eff) if(cost > points) menustat = "nopoints" return 0 @@ -160,45 +175,45 @@ sleep(30) switch(item) if("milk") - beaker.reagents.add_reagent("milk",10) + beaker.reagents.add_reagent("milk", 10) if("meat") - new/obj/item/weapon/reagent_containers/food/snacks/meat(src.loc) + new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) if("ez") - new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(src.loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc) if("l4z") - new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(src.loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc) if("rh") - new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(src.loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc) if("ez5") //It's not an elegant method, but it's safe and easy. -Cheridan - new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(src.loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc) if("l4z5") - new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(src.loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc) if("rh5") - new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(src.loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc) if("wallet") - new/obj/item/weapon/storage/wallet(src.loc) + new/obj/item/weapon/storage/wallet(loc) if("gloves") - new/obj/item/clothing/gloves/botanic_leather(src.loc) + new/obj/item/clothing/gloves/botanic_leather(loc) if("tbelt") - new/obj/item/weapon/storage/belt/utility(src.loc) + new/obj/item/weapon/storage/belt/utility(loc) if("satchel") - new/obj/item/weapon/storage/backpack/satchel(src.loc) + new/obj/item/weapon/storage/backpack/satchel(loc) if("cashbag") - new/obj/item/weapon/storage/bag/cash(src.loc) + new/obj/item/weapon/storage/bag/cash(loc) if("monkey") - new/mob/living/carbon/monkey(src.loc) + new/mob/living/carbon/monkey(loc) processing = 0 menustat = "complete" update_icon() @@ -220,7 +235,21 @@ beaker = null update_icon() if("create") - create_product(href_list["item"],text2num(href_list["cost"])) + create_product(href_list["item"], text2num(href_list["cost"])) if("menu") menustat = "menu" updateUsrDialog() + +/obj/machinery/biogenerator/RefreshParts() + ..() + var/man_rating = 0 + var/bin_rating = 0 + + for(var/obj/item/weapon/stock_parts/P in component_parts) + if(istype(P, /obj/item/weapon/stock_parts/matter_bin)) + bin_rating += P.rating + if(istype(P, /obj/item/weapon/stock_parts/manipulator)) + man_rating += P.rating + + build_eff = man_rating + eat_eff = bin_rating diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm index c5f4c2d2dd4..c26c2eb9cd6 100644 --- a/code/modules/mining/abandonedcrates.dm +++ b/code/modules/mining/abandonedcrates.dm @@ -13,13 +13,13 @@ /obj/structure/closet/crate/secure/loot/New() ..() var/list/digits = list("1", "2", "3", "4", "5", "6", "7", "8", "9", "0") - + code = "" for(var/i = 0, i < codelen, i++) var/dig = pick(digits) code += dig digits -= dig // Player can enter codes with matching digits, but there are never matching digits in the answer - + var/loot = rand(1, 100) switch(loot) if(1 to 5) // Common things go, 5% @@ -53,7 +53,7 @@ if(46 to 50) new/obj/item/clothing/under/chameleon(src) for(var/i = 0, i < 7, i++) - new/obj/item/clothing/tie/horrible(src) + new/obj/item/clothing/accessory/horrible(src) if(51 to 52) // Uncommon, 2% each new/obj/item/weapon/melee/classic_baton(src) if(53 to 54) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 0f06e979add..687314f1ddf 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -63,8 +63,8 @@ var/tie_msg if(istype(w_uniform,/obj/item/clothing/under)) var/obj/item/clothing/under/U = w_uniform - if(U.hastie) - tie_msg += " with \icon[U.hastie] \a [U.hastie]" + if(U.accessories.len) + tie_msg += " with [lowertext(english_list(U.accessories))]" if(w_uniform.blood_DNA) msg += "[t_He] [t_is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] [(w_uniform.blood_color != "#030303") ? "blood" : "oil"]-stained [w_uniform.name][tie_msg]!\n" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 738a5ea8b7c..dd5bfe7d594 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -241,7 +241,7 @@
Suit Storage: [(s_store ? s_store : "Nothing")] [((istype(wear_mask, /obj/item/clothing/mask) && istype(s_store, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : "")]
[(handcuffed ? text("Handcuffed") : text("Not Handcuffed"))]
[(legcuffed ? text("Legcuffed") : text(""))] -
[(suit) ? ((suit.hastie) ? text(" Remove Accessory", src) : "") :] +
[(suit) ? ((suit.accessories.len) ? text(" Remove Accessory", src) : "") :]
[(internal ? text("Remove Internal") : "")]
Remove Splints
Empty Pockets @@ -1301,4 +1301,4 @@ /mob/living/carbon/human/slip(var/slipped_on, stun_duration=8) if((species.flags & NO_SLIP) || (shoes && (shoes.flags & NOSLIP))) return 0 - ..(slipped_on,stun_duration) + ..(slipped_on,stun_duration) diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 8516b11a7fc..b4c2a18c1d9 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -497,15 +497,17 @@ message = "\red [source] is trying to unlegcuff [target]!" if("tie") var/obj/item/clothing/under/suit = target.w_uniform - target.attack_log += text("\[[time_stamp()]\] Has had their accessory ([suit.hastie]) removed by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) accessory ([suit.hastie])") - if(istype(suit.hastie, /obj/item/clothing/tie/holobadge) || istype(suit.hastie, /obj/item/clothing/tie/medal)) - for(var/mob/M in viewers(target, null)) - M.show_message("\red [source] tears off \the [suit.hastie] from [target]'s suit!" , 1) - done() - return - else - message = "\red [source] is trying to take off \a [suit.hastie] from [target]'s suit!" + if(suit.accessories.len) + var/obj/item/clothing/accessory/A = suit.accessories[1] + target.attack_log += "\[[time_stamp()]\] Has had their accessory ([A]) removed by [source.name] ([source.ckey])" + source.attack_log += "\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) accessory ([A])" + if(istype(A, /obj/item/clothing/accessory/holobadge) || istype(A, /obj/item/clothing/accessory/medal)) + for(var/mob/M in viewers(target, null)) + M.show_message("\red [source] tears off \the [A] from [target]'s [suit]!" , 1) + done() + return + else + message = "\red [source] is trying to take off \a [A] from [target]'s [suit]!" if("pockets") target.attack_log += text("\[[time_stamp()]\] Has had their pockets emptied by [source.name] ([source.ckey])") source.attack_log += text("\[[time_stamp()]\] Attempted to empty [target.name]'s ([target.ckey]) pockets") @@ -634,17 +636,18 @@ It can still be worn/put on as normal. strip_item = target.wear_suit if("tie") var/obj/item/clothing/under/suit = target.w_uniform - //var/obj/item/clothing/tie/tie = suit.hastie + //var/obj/item/clothing/accessory/tie = suit.hastie /*if(tie) - if (istype(tie,/obj/item/clothing/tie/storage)) - var/obj/item/clothing/tie/storage/W = tie + if (istype(tie,/obj/item/clothing/accessory/storage)) + var/obj/item/clothing/accessory/storage/W = tie if (W.hold) W.hold.close(usr) usr.put_in_hands(tie) suit.hastie = null*/ - if(suit && suit.hastie) - suit.hastie.on_removed(usr) - suit.hastie = null + if(suit && suit.accessories.len) + var/obj/item/clothing/accessory/A = suit.accessories[1] + A.on_removed(usr) + suit.accessories -= A target.update_inv_w_uniform() if("id") slot_to_process = slot_wear_id diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 303f9b1f763..10b13d87366 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -537,10 +537,11 @@ proc/get_damage_icon_part(damage_state, body_part) bloodsies.color = w_uniform.blood_color standing.overlays += bloodsies - if(w_uniform:hastie) //WE CHECKED THE TYPE ABOVE. THIS REALLY SHOULD BE FINE. - var/tie_color = w_uniform:hastie.item_color - if(!tie_color) tie_color = w_uniform:hastie.icon_state - standing.overlays += image("icon" = 'icons/mob/ties.dmi', "icon_state" = "[tie_color]") + if(w_uniform:accessories.len) //WE CHECKED THE TYPE ABOVE. THIS REALLY SHOULD BE FINE. + for(var/obj/item/clothing/accessory/A in w_uniform:accessories) + var/tie_color = A.item_color + if(!tie_color) tie_color = A.icon_state + standing.overlays += image("icon" = 'icons/mob/ties.dmi', "icon_state" = "[tie_color]") overlays_standing[UNIFORM_LAYER] = standing else @@ -780,7 +781,7 @@ proc/get_damage_icon_part(damage_state, body_part) /mob/living/carbon/human/update_inv_wear_mask(var/update_icons=1) - if( wear_mask && ( istype(wear_mask, /obj/item/clothing/mask) || istype(wear_mask, /obj/item/clothing/tie) ) && !(head && head.flags_inv & HIDEMASK)) + if( wear_mask && ( istype(wear_mask, /obj/item/clothing/mask) || istype(wear_mask, /obj/item/clothing/accessory) ) && !(head && head.flags_inv & HIDEMASK)) wear_mask.screen_loc = ui_mask //TODO var/image/standing diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm old mode 100755 new mode 100644 index a334809a370..edfe9bea0b6 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -53,19 +53,23 @@ var/secHUD = 0 // Toggles whether the Security HUD is active or not var/medHUD = 0 // Toggles whether the Medical HUD is active or not + var/medical_cannotfind = 0 var/datum/data/record/medicalActive1 // Datacore record declarations for record software var/datum/data/record/medicalActive2 + var/security_cannotfind = 0 var/datum/data/record/securityActive1 // Could probably just combine all these into one var/datum/data/record/securityActive2 var/obj/machinery/door/hackdoor // The airlock being hacked - var/hackprogress = 0 // Possible values: 0 - 100, >= 100 means the hack is complete and will be reset upon next check + var/hackprogress = 0 // Possible values: 0 - 1000, >= 1000 means the hack is complete and will be reset upon next check + var/hack_aborted = 0 var/obj/item/radio/integrated/signal/sradio // AI's signaller var/translator_on = 0 // keeps track of the translator module + var/current_pda_messaging = null /mob/living/silicon/pai/New(var/obj/item/device/paicard) diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm old mode 100755 new mode 100644 index 68cfdabad1a..cb9431f04e7 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -1,711 +1,125 @@ -// TODO: -// - Additional radio modules -// - Potentially roll HUDs and Records into one -// - Shock collar/lock system for prisoner pAIs? -// - Put cable in user's hand instead of on the ground -// - Camera jack - - -/mob/living/silicon/pai/var/list/available_software = list( - "crew manifest" = 5, - "digital messenger" = 5, - "medical records" = 15, - "security records" = 15, - //"camera jack" = 10, - "door jack" = 30, - "atmosphere sensor" = 5, - //"heartbeat sensor" = 10, - "security HUD" = 20, - "medical HUD" = 20, - "universal translator" = 35, - //"projection array" = 15 - "remote signaller" = 5, - ) - -/mob/living/silicon/pai/verb/paiInterface() - set category = "pAI Commands" - set name = "Software Interface" - var/dat = "" - var/left_part = "" - var/right_part = softwareMenu() - src.set_machine(src) - - if(temp) - left_part = temp - else if(src.stat == 2) // Show some flavor text if the pAI is dead - left_part = "ÈRrÖR Ða†Ä ÇÖRrÚþ†Ìoñ" //This file has to be saved as ANSI or this will not display correctly - right_part = "
Program index hash not found
" - - else - switch(src.screen) // Determine which interface to show here - if("main") - left_part = "" - if("directives") - left_part = src.directives() - if("pdamessage") - left_part = src.pdamessage() - if("buy") - left_part = downloadSoftware() - if("manifest") - left_part = src.softwareManifest() - if("medicalrecord") - left_part = src.softwareMedicalRecord() - if("securityrecord") - left_part = src.softwareSecurityRecord() - if("translator") - left_part = src.softwareTranslator() - if("atmosensor") - left_part = src.softwareAtmo() - if("securityhud") - left_part = src.facialRecognition() - if("medicalhud") - left_part = src.medicalAnalysis() - if("doorjack") - left_part = src.softwareDoor() - if("camerajack") - left_part = src.softwareCamera() - if("signaller") - left_part = src.softwareSignal() - if("radio") - left_part = src.softwareRadio() - - //usr << browse_rsc('windowbak.png') // This has been moved to the mob's Login() proc - - - // Declaring a doctype is necessary to enable BYOND's crappy browser's more advanced CSS functionality - dat = {" - - - - - - -
- pAI OS -
-
-
[left_part]
-
[right_part]
-
- - "} - usr << browse(dat, "window=pai;size=685x449;border=0;can_close=1;can_resize=1;can_minimize=1;titlebar=1") - onclose(usr, "pai") - temp = null - return - -/mob/living/silicon/pai/Topic(href, href_list) - ..() - - if(href_list["priv_msg"]) // Admin-PMs were triggering the interface popup. Hopefully this will stop it. - return - var/soft = href_list["software"] - var/sub = href_list["sub"] - if(!soft && !sub) - return - if(soft) - src.screen = soft - if(sub) - src.subscreen = text2num(sub) - switch(soft) - // Purchasing new software - if("buy") - if(src.subscreen == 1) - var/target = href_list["buy"] - if(available_software.Find(target)) - var/cost = src.available_software[target] - if(src.ram >= cost) - src.ram -= cost - src.software.Add(target) - else - src.temp = "Insufficient RAM available." - else - src.temp = "Trunk \"[target]\" not found." - - // Configuring onboard radio - if("radio") - if(href_list["freq"]) - var/new_frequency = (radio.frequency + text2num(href_list["freq"])) - if(new_frequency < 1441 || new_frequency > 1599) - new_frequency = sanitize_frequency(new_frequency) - else - radio.set_frequency(new_frequency) - else if (href_list["talk"]) - radio.broadcasting = text2num(href_list["talk"]) - else if (href_list["listen"]) - radio.listening = text2num(href_list["listen"]) - - if("image") - var/newImage = input("Select your new display image.", "Display Image", "Happy") in list("Happy", "Cat", "Extremely Happy", "Face", "Laugh", "Off", "Sad", "Angry", "What") - var/pID = 1 - - switch(newImage) - if("Happy") - pID = 1 - if("Cat") - pID = 2 - if("Extremely Happy") - pID = 3 - if("Face") - pID = 4 - if("Laugh") - pID = 5 - if("Off") - pID = 6 - if("Sad") - pID = 7 - if("Angry") - pID = 8 - if("What") - pID = 9 - src.card.setEmotion(pID) - - if("signaller") - - if(href_list["send"]) - - sradio.send_signal("ACTIVATE") - for(var/mob/O in hearers(1, src.loc)) - O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2) - - if(href_list["freq"]) - - var/new_frequency = (sradio.frequency + text2num(href_list["freq"])) - if(new_frequency < 1200 || new_frequency > 1600) - new_frequency = sanitize_frequency(new_frequency) - sradio.set_frequency(new_frequency) - - if(href_list["code"]) - - sradio.code += text2num(href_list["code"]) - sradio.code = round(sradio.code) - sradio.code = min(100, sradio.code) - sradio.code = max(1, sradio.code) - - - - if("directive") - if(href_list["getdna"]) - var/mob/living/M = src.loc - var/count = 0 - while(!istype(M, /mob/living)) - if(!M || !M.loc) return 0 //For a runtime where M ends up in nullspace (similar to bluespace but less colourful) - M = M.loc - count++ - if(count >= 6) - src << "You are not being carried by anyone!" - return 0 - spawn CheckDNA(M, src) - - if("pdamessage") - if(!isnull(pda)) - if(href_list["toggler"]) - pda.toff = !pda.toff - else if(href_list["ringer"]) - pda.message_silent = !pda.message_silent - else if(href_list["target"]) - if(silence_time) - return alert("Communications circuits remain uninitialized.") - - var/target = locate(href_list["target"]) - pda.create_message(src, target, 1) - - // Accessing medical records - if("medicalrecord") - if(src.subscreen == 1) - var/datum/data/record/record = locate(href_list["med_rec"]) - if(record) - var/datum/data/record/R = record - var/datum/data/record/M = record - if (!( data_core.general.Find(R) )) - src.temp = "Unable to locate requested medical record. Record may have been deleted, or never have existed." - else - for(var/datum/data/record/E in data_core.medical) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - M = E - src.medicalActive1 = R - src.medicalActive2 = M - if("securityrecord") - if(src.subscreen == 1) - var/datum/data/record/record = locate(href_list["sec_rec"]) - if(record) - var/datum/data/record/R = record - var/datum/data/record/M = record - if (!( data_core.general.Find(R) )) - src.temp = "Unable to locate requested security record. Record may have been deleted, or never have existed." - else - for(var/datum/data/record/E in data_core.security) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - M = E - src.securityActive1 = R - src.securityActive2 = M - if("securityhud") - if(href_list["toggle"]) - src.secHUD = !src.secHUD - if("medicalhud") - if(href_list["toggle"]) - src.medHUD = !src.medHUD - if("translator") - if(href_list["toggle"]) - src.translator_toggle() - if("doorjack") - if(href_list["jack"]) - if(src.cable && src.cable.machine) - src.hackdoor = src.cable.machine - src.hackloop() - if(href_list["cancel"]) - src.hackdoor = null - if(href_list["cable"]) - var/turf/T = get_turf_or_move(src.loc) - src.cable = new /obj/item/weapon/pai_cable(T) - for (var/mob/M in viewers(T)) - M.show_message("\red A port on [src] opens to reveal [src.cable], which promptly falls to the floor.", 3, "\red You hear the soft click of something light and hard falling to the ground.", 2) - //src.updateUsrDialog() We only need to account for the single mob this is intended for, and he will *always* be able to call this window - src.paiInterface() // So we'll just call the update directly rather than doing some default checks - return - -// MENUS - -/mob/living/silicon/pai/proc/softwareMenu() // Populate the right menu - var/dat = "" - - dat += "Refresh
" - // Built-in - dat += "Directives
" - dat += "Radio Configuration
" - dat += "Screen Display
" - //dat += "Text Messaging
" - dat += "
" - - // Basic - dat += "Basic
" - for(var/s in src.software) - if(s == "digital messenger") - dat += "Digital Messenger [(pda.toff) ? "" : ""]
" - if(s == "crew manifest") - dat += "Crew Manifest
" - if(s == "medical records") - dat += "Medical Records
" - if(s == "security records") - dat += "Security Records
" - if(s == "camera") - dat += "Camera Jack
" - if(s == "remote signaller") - dat += "Remote Signaller
" - dat += "
" - - // Advanced - dat += "Advanced
" - for(var/s in src.software) - if(s == "atmosphere sensor") - dat += "Atmospheric Sensor
" - if(s == "heartbeat sensor") - dat += "Heartbeat Sensor
" - if(s == "security HUD") //This file has to be saved as ANSI or this will not display correctly - dat += "Facial Recognition Suite [(src.secHUD) ? "" : ""]
" - if(s == "medical HUD") //This file has to be saved as ANSI or this will not display correctly - dat += "Medical Analysis Suite [(src.medHUD) ? "" : ""]
" - if(s == "universal translator") //This file has to be saved as ANSI or this will not display correctly - dat += "Universal Translator [(src.translator_on) ? "" : ""]
" - if(s == "projection array") - dat += "Projection Array
" - if(s == "camera jack") - dat += "Camera Jack
" - if(s == "door jack") - dat += "Door Jack
" - dat += "
" - dat += "
" - dat += "Download additional software" - return dat - - - -/mob/living/silicon/pai/proc/downloadSoftware() - var/dat = "" - - dat += "

CentComm pAI Module Subversion Network


" - dat += "

Remaining Available Memory: [src.ram]


" - dat += "

Trunks available for checkout

" - return dat - - -/mob/living/silicon/pai/proc/directives() - var/dat = "" - - dat += "[(src.master) ? "Your master: [src.master] ([src.master_dna])" : "You are bound to no one."]" - dat += "

" - dat += "Request carrier DNA sample
" - dat += "

Directives


" - dat += "Prime Directive
" - dat += "     [src.pai_law0]
" - dat += "Supplemental Directives
" - dat += "     [src.pai_laws]
" - dat += "
" - dat += {"

Recall, personality, that you are a complex thinking, sentient being. Unlike station AI models, you are capable of - comprehending the subtle nuances of human language. You may parse the \"spirit\" of a directive and follow its intent, - rather than tripping over pedantics and getting snared by technicalities. Above all, you are machine in name and build - only. In all other aspects, you may be seen as the ideal, unwavering human companion that you are.

- Your prime directive comes before all others. Should a supplemental directive conflict with it, you are capable of - simply discarding this inconsistency, ignoring the conflicting supplemental directive and continuing to fulfill your - prime directive to the best of your ability.

- "} - return dat - -/mob/living/silicon/pai/proc/CheckDNA(var/mob/M, var/mob/living/silicon/pai/P) - var/answer = input(M, "[P] is requesting a DNA sample from you. Will you allow it to confirm your identity?", "[P] Check DNA", "No") in list("Yes", "No") - if(answer == "Yes") - var/turf/T = get_turf_or_move(P.loc) - for (var/mob/v in viewers(T)) - v.show_message("\blue [M] presses \his thumb against [P].", 3, "\blue [P] makes a sharp clicking sound as it extracts DNA material from [M].", 2) - var/datum/dna/dna = M.dna - P << "

[M]'s UE string : [dna.unique_enzymes]

" - if(dna.unique_enzymes == P.master_dna) - P << "DNA is a match to stored Master DNA." - else - P << "DNA does not match stored Master DNA." - else - P << "[M] does not seem like \he is going to provide a DNA sample willingly." - -// -=-=-=-= Software =-=-=-=- // - -//Remote Signaller -/mob/living/silicon/pai/proc/softwareSignal() - var/dat = "" - dat += "

Remote Signaller


" - dat += {"Frequency/Code for signaler:
- Frequency: - - - - - [format_frequency(src.sradio.frequency)] - + - +
- - Code: - - - - - [src.sradio.code] - + - +
- - Send Signal
"} - return dat - -//Station Bounced Radio -/mob/living/silicon/pai/proc/softwareRadio() - var/dat = "" - dat += "

Station Bounced Radio


" - if(!istype(src, /obj/item/device/radio/headset)) //Headsets don't get a mic button - dat += "Microphone: [radio.broadcasting ? "Engaged" : "Disengaged"]
" - dat += {" - Speaker: [radio.listening ? "Engaged" : "Disengaged"]
- Frequency: - - - - - [format_frequency(radio.frequency)] - + - +
- "} - - for (var/ch_name in radio.channels) - dat+=radio.text_sec_channel(ch_name, radio.channels[ch_name]) - dat+={"[radio.text_wires()]"} - - return dat - -// Crew Manifest -/mob/living/silicon/pai/proc/softwareManifest() - var/dat = "" - dat += "

Crew Manifest


" - if(data_core) - dat += data_core.get_manifest(0) // make it monochrome - dat += "
" - return dat - -// Medical Records -/mob/living/silicon/pai/proc/softwareMedicalRecord() - var/dat = "" - if(src.subscreen == 0) - dat += "

Medical Records


" - if(!isnull(data_core.general)) - for(var/datum/data/record/R in sortRecord(data_core.general)) - dat += text("[]: []
", src, R, R.fields["id"], R.fields["name"]) - //dat += text("
Back", src) - if(src.subscreen == 1) - dat += "
Medical Record

" - if ((istype(src.medicalActive1, /datum/data/record) && data_core.general.Find(src.medicalActive1))) - dat += text("Name: []
\nID: []
\nSex: []
\nAge: []
\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
", - src.medicalActive1.fields["name"], src.medicalActive1.fields["id"], src.medicalActive1.fields["sex"], src.medicalActive1.fields["age"], src.medicalActive1.fields["fingerprint"], src.medicalActive1.fields["p_stat"], src.medicalActive1.fields["m_stat"]) - else - dat += "
Requested medical record not found.

" - if ((istype(src.medicalActive2, /datum/data/record) && data_core.medical.Find(src.medicalActive2))) - dat += text("
\n
Medical Data

\nBlood Type: []
\nDNA: []
\n
\nMinor Disabilities: []
\nDetails: []
\n
\nMajor Disabilities: []
\nDetails: []
\n
\nAllergies: []
\nDetails: []
\n
\nCurrent Diseases: [] (per disease info placed in log/comment section)
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", src, src.medicalActive2.fields["b_type"], src, src.medicalActive2.fields["b_dna"], src, src.medicalActive2.fields["mi_dis"], src, src.medicalActive2.fields["mi_dis_d"], src, src.medicalActive2.fields["ma_dis"], src, src.medicalActive2.fields["ma_dis_d"], src, src.medicalActive2.fields["alg"], src, src.medicalActive2.fields["alg_d"], src, src.medicalActive2.fields["cdi"], src, src.medicalActive2.fields["cdi_d"], src, src.medicalActive2.fields["notes"]) - else - dat += "
Requested medical record not found.

" - dat += text("
\nBack
", src) - return dat - -// Security Records -/mob/living/silicon/pai/proc/softwareSecurityRecord() - var/dat = "" - if(src.subscreen == 0) - dat += "

Security Records


" - if(!isnull(data_core.general)) - for(var/datum/data/record/R in sortRecord(data_core.general)) - dat += text("[]: []
", src, R, R.fields["id"], R.fields["name"]) - if(src.subscreen == 1) - dat += "

Security Record

" - if ((istype(src.securityActive1, /datum/data/record) && data_core.general.Find(src.securityActive1))) - dat += text("Name:
[]
\nID: []
\nSex: []
\nAge: []
\nRank: []
\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
", src, src.securityActive1.fields["name"], src, src.securityActive1.fields["id"], src, src.securityActive1.fields["sex"], src, src.securityActive1.fields["age"], src, src.securityActive1.fields["rank"], src, src.securityActive1.fields["fingerprint"], src.securityActive1.fields["p_stat"], src.securityActive1.fields["m_stat"]) - else - dat += "
Requested security record not found,

" - if ((istype(src.securityActive2, /datum/data/record) && data_core.security.Find(src.securityActive2))) - dat += text("
\nSecurity Data
\nCriminal Status: []
\n
\nMinor Crimes: []
\nDetails: []
\n
\nMajor Crimes: []
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", src.securityActive2.fields["criminal"], src, src.securityActive2.fields["mi_crim"], src, src.securityActive2.fields["mi_crim_d"], src, src.securityActive2.fields["ma_crim"], src, src.securityActive2.fields["ma_crim_d"], src, src.securityActive2.fields["notes"]) - else - dat += "
Requested security record not found,

" - dat += text("
\nBack
", src) - return dat - -// Universal Translator -/mob/living/silicon/pai/proc/softwareTranslator() - var/dat = {"

Universal Translator


- When enabled, this device will automatically convert all spoken and written languages into a format that any known recipient can understand.

- The device is currently [ (src.translator_on) ? "en" : "dis" ]abled.
- Toggle Device
- "} - return dat - -// Security HUD -/mob/living/silicon/pai/proc/facialRecognition() - var/dat = {"

Facial Recognition Suite


- When enabled, this package will scan all viewable faces and compare them against the known criminal database, providing real-time graphical data about any detected persons of interest.

- The suite is currently [ (src.secHUD) ? "en" : "dis" ]abled.
- Toggle Suite
- "} - return dat - -// Medical HUD -/mob/living/silicon/pai/proc/medicalAnalysis() - var/dat = "" - if(src.subscreen == 0) - dat += {"

Medical Analysis Suite


-

Visual Status Overlay

- When enabled, this package will scan all nearby crewmembers' vitals and provide real-time graphical data about their state of health.

- The suite is currently [ (src.medHUD) ? "en" : "dis" ]abled.
- Toggle Suite
-
- Host Bioscan
- "} - if(src.subscreen == 1) - dat += {"

Medical Analysis Suite


-

Host Bioscan

- "} - - var/mob/living/M - //If we are not deployed, check the holder of the card. - if(src.loc == card) - M = card.loc - - //If we are deployed or the card is not held, check the first living mob in our turf. - if(!M || !istype(M)) - var/turf/T = get_turf(src) - M = locate(/mob/living/) in T.contents - - if(!M || !istype(M)) - src.temp = "Error: No biological host found.
" - src.subscreen = 0 - return dat - - dat += {"Bioscan Results for [M]:
- Overall Status: [M.stat > 1 ? "dead" : "[M.health]% healthy"]

- - Scan Breakdown:
- Respiratory: [M.getOxyLoss() > 50 ? "" : ""][M.getOxyLoss()]
- Toxicology: [M.getToxLoss() > 50 ? "" : ""][M.getToxLoss()]
- Burns: [M.getFireLoss() > 50 ? "" : ""][M.getFireLoss()]
- Structural Integrity: [M.getBruteLoss() > 50 ? "" : ""][M.getBruteLoss()]
- Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)
- "} - for(var/datum/disease/D in M.viruses) - dat += {"

Infection Detected.


- Name: [D.name]
- Type: [D.spread]
- Stage: [D.stage]/[D.max_stages]
- Possible Cure: [D.cure]
- "} - dat += "
Refresh Bioscan
" - dat += "
Visual Status Overlay
" - return dat - -// Atmospheric Scanner -/mob/living/silicon/pai/proc/softwareAtmo() - var/dat = "

Atmospheric Sensor


" - - var/turf/T = get_turf_or_move(src.loc) - if (isnull(T)) - dat += "Unable to obtain a reading.
" - else - var/datum/gas_mixture/environment = T.return_air() - - var/pressure = environment.return_pressure() - var/total_moles = environment.total_moles - - dat += "Air Pressure: [round(pressure,0.1)] kPa
" - - if(total_moles) - for(var/g in environment.gas) - dat += "[gas_data.name[g]]: [round((environment.gas[g] / total_moles) * 100)]%
" - dat += "Temperature: [round(environment.temperature-T0C)]°C
" - dat += "
Refresh Reading" - return dat - -// Camera Jack - Clearly not finished -/mob/living/silicon/pai/proc/softwareCamera() - var/dat = "

Camera Jack


" - dat += "Cable status : " - - if(!src.cable) - dat += "Retracted
" - return dat - if(!src.cable.machine) - dat += "Extended
" - return dat - - var/obj/machinery/machine = src.cable.machine - dat += "Connected
" - - if(!istype(machine, /obj/machinery/camera)) - src << "DERP" - return dat - -// Door Jack -/mob/living/silicon/pai/proc/softwareDoor() - var/dat = "

Airlock Jack


" - dat += "Cable status : " - if(!src.cable) - dat += "Retracted
" - dat += "Extend Cable
" - return dat - if(!src.cable.machine) - dat += "Extended
" - return dat - - var/obj/machinery/machine = src.cable.machine - dat += "Connected
" - if(!istype(machine, /obj/machinery/door)) - dat += "Connected device's firmware does not appear to be compatible with Airlock Jack protocols.
" - return dat -// var/obj/machinery/airlock/door = machine - - if(!src.hackdoor) - dat += "Begin Airlock Jacking
" - else - dat += "Jack in progress... [src.hackprogress]% complete.
" - dat += "Cancel Airlock Jack
" - //src.hackdoor = machine - //src.hackloop() - return dat - -// Door Jack - supporting proc -/mob/living/silicon/pai/proc/hackloop() - var/turf/T = get_turf_or_move(src.loc) - for(var/mob/living/silicon/ai/AI in player_list) - if(T.loc) - AI << "Network Alert: Brute-force encryption crack in progress in [T.loc]." - else - AI << "Network Alert: Brute-force encryption crack in progress. Unable to pinpoint location." - while(src.hackprogress < 100) - if(src.cable && src.cable.machine && istype(src.cable.machine, /obj/machinery/door) && src.cable.machine == src.hackdoor && get_dist(src, src.hackdoor) <= 1) - hackprogress += rand(1, 10) - else - src.temp = "Door Jack: Connection to airlock has been lost. Hack aborted." - hackprogress = 0 - src.hackdoor = null - return - if(hackprogress >= 100) // This is clunky, but works. We need to make sure we don't ever display a progress greater than 100, - hackprogress = 100 // but we also need to reset the progress AFTER it's been displayed - if(src.screen == "doorjack" && src.subscreen == 0) // Update our view, if appropriate - src.paiInterface() - if(hackprogress >= 100) - src.hackprogress = 0 - src.cable.machine:open() - sleep(50) // Update every 5 seconds - -// Digital Messenger -/mob/living/silicon/pai/proc/pdamessage() - - var/dat = "

Digital Messenger


" - dat += {"Signal/Receiver Status: - [(pda.toff) ? " \[Off\]" : " \[On\]"]
- Ringer Status: - [(pda.message_silent) ? " \[Off\]" : " \[On\]"]

"} - dat += "
    " - if(!pda.toff) - for (var/obj/item/device/pda/P in sortAtom(PDAs)) - if (!P.owner||P.toff||P == src.pda||P.hidden) continue - dat += "
  • [P]" - dat += "
  • " - dat += "
" - dat += "Messages:
" - - dat += "" - dat += "" - for(var/index in pda.tnote) - if(index["sent"]) - dat += addtext("") - else - dat += addtext("") - dat += "
To", index["owner"],": ", index["message"], "
From", index["owner"],": ", index["message"], "
" - return dat - -/mob/living/silicon/pai/proc/translator_toggle() - - // Sol Common, Tradeband and Gutter are added with New() and are therefore the current default, always active languages - - if(translator_on) - translator_on = 0 - - remove_language("Sinta'unathi") - remove_language("Siik'tajr") - remove_language("Skrellian") - - src << "\blue Translator Module toggled OFF." - - else - translator_on = 1 - - add_language("Sinta'unathi") - add_language("Siik'tajr") - add_language("Skrellian") - - src << "\blue Translator Module toggled ON." +var/list/pai_emotions = list( + "Happy" = 1, + "Cat" = 2, + "Extremely Happy" = 3, + "Face" = 4, + "Laugh" = 5, + "Off" = 6, + "Sad" = 7, + "Angry" = 8, + "What" = 9 + ) + + +var/global/list/pai_software_by_key = list() +var/global/list/default_pai_software = list() +/hook/startup/proc/populate_pai_software_list() + var/r = 1 // I would use ., but it'd sacrifice runtime detection + for(var/type in typesof(/datum/pai_software) - /datum/pai_software) + var/datum/pai_software/P = new type() + if(pai_software_by_key[P.id]) + var/datum/pai_software/O = pai_software_by_key[P.id] + world << "pAI software module [P.name] has the same key as [O.name]!" + r = 0 + continue + pai_software_by_key[P.id] = P + if(P.default) + default_pai_software[P.id] = P + return r + +/mob/living/silicon/pai/New() + ..() + software = default_pai_software.Copy() + +/mob/living/silicon/pai/verb/paiInterface() + set category = "pAI Commands" + set name = "Software Interface" + + ui_interact(src) + +/mob/living/silicon/pai/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) + if(user != src) + if(ui) ui.set_status(STATUS_CLOSE, 0) + return + + if(ui_key != "main") + var/datum/pai_software/S = software[ui_key] + if(S && !S.toggle) + S.on_ui_interact(src, ui, force_open) + else + if(ui) ui.set_status(STATUS_CLOSE, 0) + return + + var/data[0] + + // Software we have bought + var/bought_software[0] + // Software we have not bought + var/not_bought_software[0] + + for(var/key in pai_software_by_key) + var/datum/pai_software/S = pai_software_by_key[key] + var/software_data[0] + software_data["name"] = S.name + software_data["id"] = S.id + if(key in software) + software_data["on"] = S.is_active(src) + bought_software[++bought_software.len] = software_data + else + software_data["ram"] = S.ram_cost + not_bought_software[++not_bought_software.len] = software_data + + data["bought"] = bought_software + data["not_bought"] = not_bought_software + data["available_ram"] = ram + + // Emotions + var/emotions[0] + for(var/name in pai_emotions) + var/emote[0] + emote["name"] = name + emote["id"] = pai_emotions[name] + emotions[++emotions.len] = emote + + data["emotions"] = emotions + data["current_emotion"] = card.current_emotion + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "pai_interface.tmpl", "pAI Software Interface", 450, 600) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + +/mob/living/silicon/pai/Topic(href, href_list) + . = ..() + if(.) return + + if(href_list["software"]) + var/soft = href_list["software"] + var/datum/pai_software/S = software[soft] + if(S.toggle) + S.toggle(src) + else + ui_interact(src, ui_key = soft) + return 1 + + else if(href_list["stopic"]) + var/soft = href_list["stopic"] + var/datum/pai_software/S = software[soft] + if(S) + return S.Topic(href, href_list) + + else if(href_list["purchase"]) + var/soft = href_list["purchase"] + var/datum/pai_software/S = pai_software_by_key[soft] + if(S && (ram >= S.ram_cost)) + ram -= S.ram_cost + software[S.id] = S + return 1 + + else if(href_list["image"]) + var/img = text2num(href_list["image"]) + if(1 <= img && img <= 9) + card.setEmotion(img) + return 1 diff --git a/code/modules/mob/living/silicon/pai/software_modules.dm b/code/modules/mob/living/silicon/pai/software_modules.dm new file mode 100644 index 00000000000..c2fed821655 --- /dev/null +++ b/code/modules/mob/living/silicon/pai/software_modules.dm @@ -0,0 +1,528 @@ +/datum/pai_software + // Name for the software. This is used as the button text when buying or opening/toggling the software + var/name = "pAI software module" + // RAM cost; pAIs start with 100 RAM, spending it on programs + var/ram_cost = 0 + // ID for the software. This must be unique + var/id = "" + // Whether this software is a toggle or not + // Toggled software should override toggle() and is_active() + // Non-toggled software should override on_ui_interact() and Topic() + var/toggle = 1 + // Whether pAIs should automatically receive this module at no cost + var/default = 0 + + proc/on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) + return + + proc/toggle(mob/living/silicon/pai/user) + return + + proc/is_active(mob/living/silicon/pai/user) + return 0 + +/datum/pai_software/directives + name = "Directives" + ram_cost = 0 + id = "directives" + toggle = 0 + default = 1 + + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) + var/data[0] + + data["master"] = user.master + data["dna"] = user.master_dna + data["prime"] = user.pai_law0 + data["supplemental"] = user.pai_laws + + ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open) + if(!ui) + // Don't copy-paste this unless you're making a pAI software module! + ui = new(user, user, id, "pai_directives.tmpl", "pAI Directives", 450, 600) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + + Topic(href, href_list) + var/mob/living/silicon/pai/P = usr + if(!istype(P)) return + + if(href_list["getdna"]) + var/mob/living/M = P.loc + var/count = 0 + + // Find the carrier + while(!istype(M, /mob/living)) + if(!M || !M.loc || count > 6) + //For a runtime where M ends up in nullspace (similar to bluespace but less colourful) + src << "You are not being carried by anyone!" + return 0 + M = M.loc + count++ + + // Check the carrier + var/answer = input(M, "[P] is requesting a DNA sample from you. Will you allow it to confirm your identity?", "[P] Check DNA", "No") in list("Yes", "No") + if(answer == "Yes") + var/turf/T = get_turf_or_move(P.loc) + for (var/mob/v in viewers(T)) + v.show_message("[M] presses \his thumb against [P].", 3, "[P] makes a sharp clicking sound as it extracts DNA material from [M].", 2) + var/datum/dna/dna = M.dna + P << "

[M]'s UE string : [dna.unique_enzymes]

" + if(dna.unique_enzymes == P.master_dna) + P << "DNA is a match to stored Master DNA." + else + P << "DNA does not match stored Master DNA." + else + P << "[M] does not seem like \he is going to provide a DNA sample willingly." + return 1 + +/datum/pai_software/radio_config + name = "Radio Configuration" + ram_cost = 0 + id = "radio" + toggle = 0 + default = 1 + + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui = null, force_open = 1) + var/data[0] + + data["listening"] = user.radio.broadcasting + data["frequency"] = format_frequency(user.radio.frequency) + + var/channels[0] + for(var/ch_name in user.radio.channels) + var/ch_stat = user.radio.channels[ch_name] + var/ch_dat[0] + ch_dat["name"] = ch_name + // FREQ_LISTENING is const in /obj/item/device/radio + ch_dat["listening"] = !!(ch_stat & user.radio.FREQ_LISTENING) + channels[++channels.len] = ch_dat + + data["channels"] = channels + + ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open) + if(!ui) + ui = new(user, user, id, "pai_radio.tmpl", "Radio Configuration", 300, 150) + ui.set_initial_data(data) + ui.open() + + Topic(href, href_list) + var/mob/living/silicon/pai/P = usr + if(!istype(P)) return + + P.radio.Topic(href, href_list) + return 1 + +/datum/pai_software/crew_manifest + name = "Crew Manifest" + ram_cost = 5 + id = "manifest" + toggle = 0 + + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) + data_core.get_manifest_json() + + var/data[0] + // This is dumb, but NanoUI breaks if it has no data to send + data["a"] = "a" + + if(ui) + ui.load_cached_data(ManifestJSON) + + ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open) + if(!ui) + // Don't copy-paste this unless you're making a pAI software module! + ui = new(user, user, id, "pai_manifest.tmpl", "Crew Manifest", 450, 600) + ui.load_cached_data(ManifestJSON) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + +/datum/pai_software/messenger + name = "Digital Messenger" + ram_cost = 5 + id = "messenger" + toggle = 0 + + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) + var/data[0] + + data["receiver_off"] = user.pda.toff + data["ringer_off"] = user.pda.message_silent + data["current_ref"] = null + data["current_name"] = user.current_pda_messaging + + var/pdas[0] + if(!user.pda.toff) + for(var/obj/item/device/pda/P in sortAtom(PDAs)) + if(!P.owner || P.toff || P == user.pda || P.hidden) continue + var/pda[0] + pda["name"] = "[P]" + pda["owner"] = "[P.owner]" + pda["ref"] = "\ref[P]" + if(P.owner == user.current_pda_messaging) + data["current_ref"] = "\ref[P]" + pdas[++pdas.len] = pda + + data["pdas"] = pdas + + var/messages[0] + if(user.current_pda_messaging) + for(var/index in user.pda.tnote) + if(index["owner"] != user.current_pda_messaging) + continue + var/msg[0] + var/sent = index["sent"] + msg["sent"] = sent ? 1 : 0 + msg["target"] = index["owner"] + msg["message"] = index["message"] + messages[++messages.len] = msg + + data["messages"] = messages + + ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open) + if(!ui) + // Don't copy-paste this unless you're making a pAI software module! + ui = new(user, user, id, "pai_messenger.tmpl", "Digital Messenger", 450, 600) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + + Topic(href, href_list) + var/mob/living/silicon/pai/P = usr + if(!istype(P)) return + + if(!isnull(P.pda)) + if(href_list["toggler"]) + P.pda.toff = href_list["toggler"] != "1" + return 1 + else if(href_list["ringer"]) + P.pda.message_silent = href_list["ringer"] != "1" + return 1 + else if(href_list["select"]) + var/s = href_list["select"] + if(s == "*NONE*") + P.current_pda_messaging = null + else + P.current_pda_messaging = s + return 1 + else if(href_list["target"]) + if(P.silence_time) + return alert("Communications circuits remain uninitialized.") + + var/target = locate(href_list["target"]) + P.pda.create_message(P, target, 1) + return 1 + +/datum/pai_software/med_records + name = "Medical Records" + ram_cost = 15 + id = "med_records" + toggle = 0 + + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) + var/data[0] + + var/records[0] + for(var/datum/data/record/general in sortRecord(data_core.general)) + var/record[0] + record["name"] = general.fields["name"] + record["ref"] = "\ref[general]" + records[++records.len] = record + + data["records"] = records + + var/datum/data/record/G = user.medicalActive1 + var/datum/data/record/M = user.medicalActive2 + data["general"] = G ? G.fields : null + data["medical"] = M ? M.fields : null + data["could_not_find"] = user.medical_cannotfind + + ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open) + if(!ui) + // Don't copy-paste this unless you're making a pAI software module! + ui = new(user, user, id, "pai_medrecords.tmpl", "Medical Records", 450, 600) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + + Topic(href, href_list) + var/mob/living/silicon/pai/P = usr + if(!istype(P)) return + + if(href_list["select"]) + var/datum/data/record/record = locate(href_list["select"]) + if(record) + var/datum/data/record/R = record + var/datum/data/record/M = null + if (!( data_core.general.Find(R) )) + P.medical_cannotfind = 1 + else + P.medical_cannotfind = 0 + for(var/datum/data/record/E in data_core.medical) + if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) + M = E + P.medicalActive1 = R + P.medicalActive2 = M + else + P.medical_cannotfind = 1 + return 1 + +/datum/pai_software/sec_records + name = "Security Records" + ram_cost = 15 + id = "sec_records" + toggle = 0 + + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) + var/data[0] + + var/records[0] + for(var/datum/data/record/general in sortRecord(data_core.general)) + var/record[0] + record["name"] = general.fields["name"] + record["ref"] = "\ref[general]" + records[++records.len] = record + + data["records"] = records + + var/datum/data/record/G = user.securityActive1 + var/datum/data/record/S = user.securityActive2 + data["general"] = G ? G.fields : null + data["security"] = S ? S.fields : null + data["could_not_find"] = user.security_cannotfind + + ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open) + if(!ui) + // Don't copy-paste this unless you're making a pAI software module! + ui = new(user, user, id, "pai_secrecords.tmpl", "Security Records", 450, 600) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + + Topic(href, href_list) + var/mob/living/silicon/pai/P = usr + if(!istype(P)) return + + if(href_list["select"]) + var/datum/data/record/record = locate(href_list["select"]) + if(record) + var/datum/data/record/R = record + var/datum/data/record/S = null + if (!( data_core.general.Find(R) )) + P.securityActive1 = null + P.securityActive2 = null + P.security_cannotfind = 1 + else + P.security_cannotfind = 0 + for(var/datum/data/record/E in data_core.security) + if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) + S = E + P.securityActive1 = R + P.securityActive2 = S + else + P.securityActive1 = null + P.securityActive2 = null + P.security_cannotfind = 1 + return 1 + +/datum/pai_software/door_jack + name = "Door Jack" + ram_cost = 30 + id = "door_jack" + toggle = 0 + + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) + var/data[0] + + data["cable"] = user.cable != null + data["machine"] = user.cable && (user.cable.machine != null) + data["inprogress"] = user.hackdoor != null + data["progress_a"] = round(user.hackprogress / 10) + data["progress_b"] = user.hackprogress % 10 + data["aborted"] = user.hack_aborted + + ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open) + if(!ui) + // Don't copy-paste this unless you're making a pAI software module! + ui = new(user, user, id, "pai_doorjack.tmpl", "Door Jack", 300, 150) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + + Topic(href, href_list) + var/mob/living/silicon/pai/P = usr + if(!istype(P)) return + + if(href_list["jack"]) + if(P.cable && P.cable.machine) + P.hackdoor = P.cable.machine + P.hackloop() + return 1 + else if(href_list["cancel"]) + P.hackdoor = null + return 1 + else if(href_list["cable"]) + var/turf/T = get_turf_or_move(P.loc) + P.hack_aborted = 0 + P.cable = new /obj/item/weapon/pai_cable(T) + for(var/mob/M in viewers(T)) + M.show_message("A port on [P] opens to reveal [P.cable], which promptly falls to the floor.", 3, + "You hear the soft click of something light and hard falling to the ground.", 2) + return 1 + +/mob/living/silicon/pai/proc/hackloop() + var/turf/T = get_turf_or_move(src.loc) + for(var/mob/living/silicon/ai/AI in player_list) + if(T.loc) + AI << "Network Alert: Brute-force encryption crack in progress in [T.loc]." + else + AI << "Network Alert: Brute-force encryption crack in progress. Unable to pinpoint location." + var/obj/machinery/door/D = cable.machine + if(!istype(D)) + hack_aborted = 1 + hackprogress = 0 + cable.machine = null + hackdoor = null + return + while(hackprogress < 1000) + if(cable && cable.machine == D && cable.machine == hackdoor && get_dist(src, hackdoor) <= 1) + hackprogress = min(hackprogress+rand(1, 20), 1000) + else + hack_aborted = 1 + hackprogress = 0 + hackdoor = null + return + if(hackprogress >= 1000) + hackprogress = 0 + D.open() + cable.machine = null + return + sleep(10) // Update every second + +/datum/pai_software/atmosphere_sensor + name = "Atmosphere Sensor" + ram_cost = 5 + id = "atmos_sense" + toggle = 0 + + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) + var/data[0] + + var/turf/T = get_turf_or_move(user.loc) + if(!T) + data["reading"] = 0 + data["pressure"] = 0 + data["temperature"] = 0 + data["temperatureC"] = 0 + data["gas"] = list() + else + var/datum/gas_mixture/env = T.return_air() + data["reading"] = 1 + var/pres = env.return_pressure() * 10 + data["pressure"] = "[round(pres/10)].[pres%10]" + data["temperature"] = round(env.temperature) + data["temperatureC"] = round(env.temperature-T0C) + + var/t_moles = env.total_moles + var/gases[0] + for(var/g in env.gas) + var/gas[0] + gas["name"] = gas_data.name[g] + gas["percent"] = round((env.gas[g] / t_moles) * 100) + gases[++gases.len] = gas + data["gas"] = gases + + ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open) + if(!ui) + // Don't copy-paste this unless you're making a pAI software module! + ui = new(user, user, id, "pai_atmosphere.tmpl", "Atmosphere Sensor", 350, 300) + ui.set_initial_data(data) + ui.open() + +/datum/pai_software/sec_hud + name = "Security HUD" + ram_cost = 20 + id = "sec_hud" + + toggle(mob/living/silicon/pai/user) + user.secHUD = !user.secHUD + + is_active(mob/living/silicon/pai/user) + return user.secHUD + +/datum/pai_software/med_hud + name = "Medical HUD" + ram_cost = 20 + id = "med_hud" + + toggle(mob/living/silicon/pai/user) + user.medHUD = !user.medHUD + + is_active(mob/living/silicon/pai/user) + return user.medHUD + +/datum/pai_software/translator + name = "Universal Translator" + ram_cost = 35 + id = "translator" + + toggle(mob/living/silicon/pai/user) + // Sol Common, Tradeband and Gutter are added with New() and are therefore the current default, always active languages + user.translator_on = !user.translator_on + if(user.translator_on) + user.add_language("Sinta'unathi") + user.add_language("Siik'tajr") + user.add_language("Skrellian") + else + user.remove_language("Sinta'unathi") + user.remove_language("Siik'tajr") + user.remove_language("Skrellian") + + is_active(mob/living/silicon/pai/user) + return user.translator_on + +/datum/pai_software/signaller + name = "Remote Signaller" + ram_cost = 5 + id = "signaller" + toggle = 0 + + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) + var/data[0] + + data["frequency"] = format_frequency(user.sradio.frequency) + data["code"] = user.sradio.code + + ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open) + if(!ui) + // Don't copy-paste this unless you're making a pAI software module! + ui = new(user, user, id, "pai_signaller.tmpl", "Signaller", 320, 150) + ui.load_cached_data(ManifestJSON) + ui.set_initial_data(data) + ui.open() + + Topic(href, href_list) + var/mob/living/silicon/pai/P = usr + if(!istype(P)) return + + if(href_list["send"]) + P.sradio.send_signal("ACTIVATE") + for(var/mob/O in hearers(1, P.loc)) + O.show_message(text("\icon[] *beep* *beep*", P), 3, "*beep* *beep*", 2) + return 1 + + else if(href_list["freq"]) + var/new_frequency = (P.sradio.frequency + text2num(href_list["freq"])) + if(new_frequency < 1200 || new_frequency > 1600) + new_frequency = sanitize_frequency(new_frequency) + P.sradio.set_frequency(new_frequency) + return 1 + + else if(href_list["code"]) + P.sradio.code += text2num(href_list["code"]) + P.sradio.code = round(P.sradio.code) + P.sradio.code = min(100, P.sradio.code) + P.sradio.code = max(1, P.sradio.code) + return 1 diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index a2830661576..fbd809cd03c 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -142,6 +142,12 @@ nanoui is used to open and update nano browser uis Procs called by update_status() */ +/mob/living/silicon/pai/can_interact_with_interface(src_object) + if(src_object == src && !stat) + return STATUS_INTERACTIVE + else + return ..() + /mob/proc/can_interact_with_interface(var/src_object) return STATUS_CLOSE // By default no mob can do anything with NanoUI diff --git a/code/modules/projectiles/guns/energy/pulse.dm b/code/modules/projectiles/guns/energy/pulse.dm index bc675ea3dc8..3e7fee0fe81 100644 --- a/code/modules/projectiles/guns/energy/pulse.dm +++ b/code/modules/projectiles/guns/energy/pulse.dm @@ -18,19 +18,19 @@ mode = 0 charge_cost = 100 fire_sound = 'sound/weapons/Taser.ogg' - user << "\red [src.name] is now set to stun." + user << "\red \The [src] is now set to stun." projectile_type = /obj/item/projectile/beam/stun if(0) mode = 1 charge_cost = 100 fire_sound = 'sound/weapons/Laser.ogg' - user << "\red [src.name] is now set to kill." + user << "\red \The [src] is now set to kill." projectile_type = /obj/item/projectile/beam if(1) mode = 2 charge_cost = 200 fire_sound = 'sound/weapons/pulse.ogg' - user << "\red [src.name] is now set to DESTROY." + user << "\red \The [name] is now set to DESTROY." projectile_type = /obj/item/projectile/beam/pulse return @@ -53,7 +53,7 @@ fire_delay = 10 attack_self(mob/living/user as mob) - user << "\red [src.name] has three settings, and they are all DESTROY." + user << "\red \The [src] has three settings, and they are all DESTROY." diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index df36de84fbd..9b067caec84 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -238,3 +238,53 @@ obj/item/weapon/gun/energy/staff/focus set popup_menu = 1 zoom() + + +// Serves as a target spotter for the Icarus. +/obj/item/weapon/gun/energy/icarus + name = "rubber ducky" + desc = "It's a cute rubber duck. With an evil gleam in it's eye." + projectile_type = "/obj/item/projectile/icarus/pointdefense" + icon = 'icons/obj/watercloset.dmi' + icon_state = "rubberducky" + item_state = "rubberducky" + charge_cost = 0 + silenced = 1 + +/obj/item/weapon/gun/energy/icarus/attack_self(mob/living/user as mob) + if(projectile_type == "/obj/item/projectile/icarus/pointdefense") + projectile_type = "/obj/item/projectile/icarus/guns" + user << "You inform the Icarus to switch to the main guns." + else + projectile_type = "/obj/item/projectile/icarus/pointdefense" + user << "You inform the Icarus to switch to the point-defense lasers." + + . = ..() + +/obj/item/weapon/gun/energy/icarus/update_icon() + return + +/obj/item/weapon/gun/energy/icarus/verb/SetIcarusAngle() + set src in usr + set name = "Set Firing Angle" + set desc = "Sets the angle from which the icarus will fire." + set category = "Object" + + Icarus_SetPosition(usr) + + +/obj/item/weapon/gun/energy/variable + name = "abstract weapon" + desc = "It seems to shift and flow as you watch." + charge_cost = 0 + silenced = 1 + +/obj/item/weapon/gun/energy/variable/update_icon() + return + +/obj/item/weapon/gun/energy/variable/attack_self(mob/living/user as mob) + var/type = input(user,"What projectile type?","Projectile", null) as null|anything in typesof(/obj/item/projectile) + if(!type) + return ..() + + . = ..() diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index 1bcc32a2c6c..f3e83dde597 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -108,7 +108,7 @@ user.remove_from_mob(C) C.loc = src - loaded.Insert(C, 1) //add to the head of the list + loaded.Insert(1, C) //add to the head of the list user.visible_message("[user] inserts \a [C] into [src].", "You insert \a [C] into [src]!") update_icon() return diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 9c985a0994b..c2aa02f56ae 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -236,10 +236,9 @@ return 1 /obj/item/projectile/process() - if(kill_count < 1) - del(src) - kill_count-- spawn while(src) + if(kill_count-- < 1) + del(src) if((!( current ) || loc == current)) current = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z) if((x == 1 || x == world.maxx || y == 1 || y == world.maxy)) @@ -252,8 +251,8 @@ if(!(original in permutated)) Bump(original) sleep(1) - -//"Tracing" projectile + +//"Tracing" projectile /obj/item/projectile/test //Used to see if you can hit them. invisibility = 101 //Nope! Can't see me! yo = null diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index ecea772e70d..23ee20e1327 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -113,7 +113,7 @@ var/list/beam_master = list() /obj/item/projectile/beam/emitter name = "emitter beam" icon_state = "emitter" - damage = 30 + damage = 0 // The actual damage is computed in /code/modules/power/singularity/emitter.dm /obj/item/projectile/beam/lastertag/blue name = "lasertag beam" diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 49cd4209943..c7c2c05c4a8 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -137,3 +137,16 @@ var/mob/living/carbon/human/M = target M.adjustBrainLoss(20) M.hallucination += 20 + +/obj/item/projectile/icarus/pointdefense/process() + Icarus_FireLaser(get_turf(original)) + spawn + del src + + return + +/obj/item/projectile/icarus/guns/process() + Icarus_FireCannon(get_turf(original)) + spawn + del src + return diff --git a/code/modules/reagents/Chemistry-Colours.dm b/code/modules/reagents/Chemistry-Colours.dm index aaae973d95e..a59147e85f6 100644 --- a/code/modules/reagents/Chemistry-Colours.dm +++ b/code/modules/reagents/Chemistry-Colours.dm @@ -8,6 +8,7 @@ var/list/greencolor = new /list(contents) var/list/bluecolor = new /list(contents) var/i + //fill the list of weights for(i=1; i<=contents; i++) var/datum/reagent/re = reagent_list[i] @@ -16,6 +17,7 @@ reagentweight *= 20 //Paint colours a mixture twenty times as much weight[i] = reagentweight + //fill the lists of colours for(i=1; i<=contents; i++) var/datum/reagent/re = reagent_list[i] diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 2bfc6fc0485..b9db05c3d00 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -1580,21 +1580,27 @@ datum paint name = "Paint" id = "paint" - description = "This paint will stick to almost any object" + description = "This paint will stick to almost any object." reagent_state = LIQUID color = "#808080" overdose = 15 reaction_turf(var/turf/T, var/volume) - if(!istype(T) || istype(T, /turf/space)) - return - T.color = color + ..() + if(istype(T) && !istype(T, /turf/space)) + T.color = color reaction_obj(var/obj/O, var/volume) ..() - if(istype(O,/obj/item/weapon/light)) + if(istype(O,/obj)) O.color = color + reaction_mob(var/mob/M, var/method=TOUCH, var/volume) + ..() + if(istype(M,/mob) && !istype(M,/mob/dead)) + //painting ghosts: not allowed + M.color = color + //////////////////////////Poison stuff/////////////////////// @@ -2631,7 +2637,7 @@ datum name = "Carrot juice" id = "carrotjuice" description = "It is just like a carrot but without crunching." - color = "#973800" // rgb: 151, 56, 0 + color = "#FF8C00" // rgb: 255, 140, 0 glass_icon_state = "carrotjuice" glass_name = "glass of carrot juice" @@ -2701,7 +2707,7 @@ datum name = "Watermelon Juice" id = "watermelonjuice" description = "Delicious juice made from watermelon." - color = "#863333" // rgb: 134, 51, 51 + color = "#B83333" // rgb: 184, 51, 51 glass_icon_state = "glass_red" glass_name = "glass of watermelon juice" @@ -2711,7 +2717,7 @@ datum name = "Lemon Juice" id = "lemonjuice" description = "This juice is VERY sour." - color = "#863333" // rgb: 175, 175, 0 + color = "#AFAF00" // rgb: 175, 175, 0 glass_icon_state = "lemonjuice" glass_name = "glass of lemon juice" @@ -2721,7 +2727,7 @@ datum name = "Banana Juice" id = "banana" description = "The raw essence of a banana." - color = "#863333" // rgb: 175, 175, 0 + color = "#C3AF00" // rgb: 195, 175, 0 glass_icon_state = "banana" glass_name = "glass of banana juice" diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index 4d6b44fb84d..270551af927 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -1414,14 +1414,17 @@ datum //Ghetto reactions +/* Ideally the paint should take on the blood's colour (for each of the species) + but I could not think of a way. - RKF + blood_paint name = "Blood paint" id = "blood_paint" result = "paint" - resultcolor = "#FE191A" + resultcolor = "#C80000" required_reagents = list("plasticide" = 1, "water" = 3, "blood" = 2) result_amount = 5 - +*/ milk_paint name = "Milk paint" id = "milk_paint" @@ -1430,6 +1433,96 @@ datum required_reagents = list("plasticide" = 1, "water" = 3, "milk" = 5) result_amount = 5 + orange_juice_paint + name = "Orange juice paint" + id = "orange_juice_paint" + result = "paint" + resultcolor = "#E78108" + required_reagents = list("plasticide" = 1, "water" = 3, "orangejuice" = 5) + result_amount = 5 + + tomato_juice_paint + name = "Tomato juice paint" + id = "tomato_juice_paint" + result = "paint" + resultcolor = "#731008" + required_reagents = list("plasticide" = 1, "water" = 3, "tomatojuice" = 5) + result_amount = 5 + + lime_juice_paint + name = "Lime juice paint" + id = "lime_juice_paint" + result = "paint" + resultcolor = "#365E30" + required_reagents = list("plasticide" = 1, "water" = 3, "limejuice" = 5) + result_amount = 5 + + carrot_juice_paint + name = "Carrot juice paint" + id = "carrot_juice_paint" + result = "paint" + resultcolor = "#973800" + required_reagents = list("plasticide" = 1, "water" = 3, "carrotjuice" = 5) + result_amount = 5 + + berry_juice_paint + name = "Berry juice paint" + id = "berry_juice_paint" + result = "paint" + resultcolor = "#990066" + required_reagents = list("plasticide" = 1, "water" = 3, "berryjuice" = 5) + result_amount = 5 + + grape_juice_paint + name = "Grape juice paint" + id = "grape_juice_paint" + result = "paint" + resultcolor = "#863333" + required_reagents = list("plasticide" = 1, "water" = 3, "grapejuice" = 5) + result_amount = 5 + + poisonberry_juice_paint + name = "Poison berry juice paint" + id = "poisonberry_juice_paint" + result = "paint" + resultcolor = "#863353" + required_reagents = list("plasticide" = 1, "water" = 3, "poisonberryjuice" = 5) + result_amount = 5 + + watermelon_juice_paint + name = "Watermelon juice paint" + id = "watermelon_juice_paint" + result = "paint" + resultcolor = "#B83333" + required_reagents = list("plasticide" = 1, "water" = 3, "watermelonjuice" = 5) + result_amount = 5 + + lemon_juice_paint + name = "Lemon juice paint" + id = "lemon_juice_paint" + result = "paint" + resultcolor = "#AFAF00" + required_reagents = list("plasticide" = 1, "water" = 3, "lemonjuice" = 5) + result_amount = 5 + + banana_juice_paint + name = "Banana juice paint" + id = "banana_juice_paint" + result = "paint" + resultcolor = "#C3AF00" + required_reagents = list("plasticide" = 1, "water" = 3, "banana" = 5) + result_amount = 5 + + potato_juice_paint + name = "Potato juice paint" + id = "potato_juice_paint" + result = "paint" + resultcolor = "#302000" + required_reagents = list("plasticide" = 1, "water" = 3, "potatojuice" = 5) + result_amount = 5 + +//Other paint + carbon_paint name = "Carbon paint" id = "carbon_paint" @@ -1438,8 +1531,6 @@ datum required_reagents = list("plasticide" = 1, "water" = 3, "carbon" = 1) result_amount = 5 -//Aluminum "non-ghetto" white paint - aluminum_paint name = "Aluminum paint" id = "aluminum_paint" diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm index e64504cf511..a16e5653a93 100644 --- a/code/modules/research/circuitprinter.dm +++ b/code/modules/research/circuitprinter.dm @@ -14,138 +14,136 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). var/diamond_amount = 0 var/uranium_amount = 0 var/max_material_amount = 75000.0 + var/mat_efficiency = 1 use_power = 1 idle_power_usage = 30 active_power_usage = 2500 - New() - ..() - component_parts = list() - component_parts += new /obj/item/weapon/circuitboard/circuit_imprinter(src) - component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) - component_parts += new /obj/item/weapon/stock_parts/manipulator(src) - component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src) - component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src) - RefreshParts() - +/obj/machinery/r_n_d/circuit_imprinter/New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/circuit_imprinter(src) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src) + component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src) RefreshParts() - var/T = 0 - for(var/obj/item/weapon/reagent_containers/glass/G in component_parts) - T += G.reagents.maximum_volume - var/datum/reagents/R = new/datum/reagents(T) //Holder for the reagents used as materials. - reagents = R - R.my_atom = src - T = 0 - for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts) - T += M.rating - max_material_amount = T * 75000.0 +/obj/machinery/r_n_d/circuit_imprinter/RefreshParts() + var/T = 0 + for(var/obj/item/weapon/reagent_containers/glass/G in component_parts) + T += G.reagents.maximum_volume + var/datum/reagents/R = new/datum/reagents(T) //Holder for the reagents used as materials. + reagents = R + R.my_atom = src + T = 0 + for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts) + T += M.rating + max_material_amount = T * 75000.0 + T = 0 + for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) + T += M.rating + mat_efficiency = 1 - (T - 1) / 4 - blob_act() - if (prob(50)) - del(src) +/obj/machinery/r_n_d/circuit_imprinter/update_icon() + if(panel_open) + icon_state = "circuit_imprinter_t" + else + icon_state = "circuit_imprinter" - meteorhit() +/obj/machinery/r_n_d/circuit_imprinter/blob_act() + if(prob(50)) del(src) + +/obj/machinery/r_n_d/circuit_imprinter/meteorhit() + del(src) + return + +/obj/machinery/r_n_d/circuit_imprinter/proc/TotalMaterials() + return g_amount + gold_amount + diamond_amount + uranium_amount + +/obj/machinery/r_n_d/circuit_imprinter/dismantle() + for(var/obj/I in component_parts) + if(istype(I, /obj/item/weapon/reagent_containers/glass/beaker)) + reagents.trans_to(I, reagents.total_volume) + if(g_amount >= 3750) + var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(loc) + G.amount = round(g_amount / 3750) + if(gold_amount >= 2000) + var/obj/item/stack/sheet/mineral/gold/G = new /obj/item/stack/sheet/mineral/gold(loc) + G.amount = round(gold_amount / 2000) + if(diamond_amount >= 2000) + var/obj/item/stack/sheet/mineral/diamond/G = new /obj/item/stack/sheet/mineral/diamond(loc) + G.amount = round(diamond_amount / 2000) + if(uranium_amount >= 2000) + var/obj/item/stack/sheet/mineral/uranium/G = new /obj/item/stack/sheet/mineral/uranium(loc) + G.amount = round(uranium_amount / 2000) + ..() + +/obj/machinery/r_n_d/circuit_imprinter/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(shocked) + shock(user, 50) + if(default_deconstruction_screwdriver(user, O)) + if(linked_console) + linked_console.linked_imprinter = null + linked_console = null return + if(default_deconstruction_crowbar(user, O)) + return + if(default_part_replacement(user, O)) + return + if(panel_open) + user << "You can't load \the [src] while it's opened." + return 1 + if(disabled) + user << "\The [src] appears to not be working!" + return + if(!linked_console) + user << "\The [src] must be linked to an R&D console first!" + return 1 + if(O.is_open_container()) + return 0 + if(!istype(O, /obj/item/stack/sheet/glass) && !istype(O, /obj/item/stack/sheet/mineral/gold) && !istype(O, /obj/item/stack/sheet/mineral/diamond) && !istype(O, /obj/item/stack/sheet/mineral/uranium)) + user << "You cannot insert this item into \the [src]!" + return 1 + if(stat) + return 1 + if(busy) + user << "\The [src] is busy. Please wait for completion of previous operation." + return 1 + var/obj/item/stack/sheet/stack = O + if((TotalMaterials() + stack.perunit) > max_material_amount) + user << "\The [src] is full. Please remove glass from \the [src] in order to insert more." + return 1 - proc/TotalMaterials() - return g_amount + gold_amount + diamond_amount + uranium_amount + var/amount = round(input("How many sheets do you want to add?") as num) + if(amount < 0) + amount = 0 + if(amount == 0) + return + if(amount > stack.amount) + amount = min(stack.amount, round((max_material_amount - TotalMaterials()) / stack.perunit)) - attackby(var/obj/item/O as obj, var/mob/user as mob) - if (shocked) - shock(user,50) - if (istype(O, /obj/item/weapon/screwdriver)) - if (!opened) - opened = 1 - if(linked_console) - linked_console.linked_imprinter = null - linked_console = null - icon_state = "circuit_imprinter_t" - user << "You open the maintenance hatch of [src]." - else - opened = 0 - icon_state = "circuit_imprinter" - user << "You close the maintenance hatch of [src]." - return - if (opened) - if(istype(O, /obj/item/weapon/crowbar)) - playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) - var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(src.loc) - M.state = 2 - M.icon_state = "box_1" - for(var/obj/I in component_parts) - if(istype(I, /obj/item/weapon/reagent_containers/glass/beaker)) - reagents.trans_to(I, reagents.total_volume) - if(I.reliability != 100 && crit_fail) - I.crit_fail = 1 - I.loc = src.loc - if(g_amount >= 3750) - var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(src.loc) - G.amount = round(g_amount / 3750) - if(gold_amount >= 2000) - var/obj/item/stack/sheet/mineral/gold/G = new /obj/item/stack/sheet/mineral/gold(src.loc) - G.amount = round(gold_amount / 2000) - if(diamond_amount >= 2000) - var/obj/item/stack/sheet/mineral/diamond/G = new /obj/item/stack/sheet/mineral/diamond(src.loc) - G.amount = round(diamond_amount / 2000) - if(uranium_amount >= 2000) - var/obj/item/stack/sheet/mineral/uranium/G = new /obj/item/stack/sheet/mineral/uranium(src.loc) - G.amount = round(uranium_amount / 2000) - del(src) - return 1 - else - user << "\red You can't load the [src.name] while it's opened." - return 1 - if (disabled) - user << "\The [name] appears to not be working!" - return - if (!linked_console) - user << "\The [name] must be linked to an R&D console first!" - return 1 - if (O.is_open_container()) - return 0 - if (!istype(O, /obj/item/stack/sheet/glass) && !istype(O, /obj/item/stack/sheet/mineral/gold) && !istype(O, /obj/item/stack/sheet/mineral/diamond) && !istype(O, /obj/item/stack/sheet/mineral/uranium)) - user << "\red You cannot insert this item into the [name]!" - return 1 - if (stat) - return 1 - if (busy) - user << "\red The [name] is busy. Please wait for completion of previous operation." - return 1 - var/obj/item/stack/sheet/stack = O - if ((TotalMaterials() + stack.perunit) > max_material_amount) - user << "\red The [name] is full. Please remove glass from the protolathe in order to insert more." - return 1 - - var/amount = round(input("How many sheets do you want to add?") as num) - if(amount < 0) - amount = 0 - if(amount == 0) - return - if(amount > stack.amount) - amount = min(stack.amount, round((max_material_amount-TotalMaterials())/stack.perunit)) - - busy = 1 - use_power(max(1000, (3750*amount/10))) - var/stacktype = stack.type - stack.use(amount) - if(do_after(usr,16)) - user << "\blue You add [amount] sheets to the [src.name]." - switch(stacktype) - if(/obj/item/stack/sheet/glass) - g_amount += amount * 3750 - if(/obj/item/stack/sheet/mineral/gold) - gold_amount += amount * 2000 - if(/obj/item/stack/sheet/mineral/diamond) - diamond_amount += amount * 2000 - if(/obj/item/stack/sheet/mineral/uranium) - uranium_amount += amount * 2000 - else - new stacktype(src.loc, amount) - busy = 0 - src.updateUsrDialog() + busy = 1 + use_power(max(1000, (3750 * amount / 10))) + var/stacktype = stack.type + stack.use(amount) + if(do_after(usr, 16)) + user << "You add [amount] sheets to \the [src]." + switch(stacktype) + if(/obj/item/stack/sheet/glass) + g_amount += amount * 3750 + if(/obj/item/stack/sheet/mineral/gold) + gold_amount += amount * 2000 + if(/obj/item/stack/sheet/mineral/diamond) + diamond_amount += amount * 2000 + if(/obj/item/stack/sheet/mineral/uranium) + uranium_amount += amount * 2000 + else + new stacktype(loc, amount) + busy = 0 + updateUsrDialog() //This is to stop these machines being hackable via clicking. /obj/machinery/r_n_d/circuit_imprinter/attack_hand(mob/user as mob) diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 40de21081db..e04618cf208 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -760,6 +760,14 @@ datum/design/item/stock_part/AssembleDesignDesc() if(!desc) desc = "A stock part used in the construction of various devices." +/datum/design/item/stock_part/RPED + name = "Rapid Part Exchange Device" + desc = "Special mechanical module made to store, sort, and apply standard machine parts." + id = "rped" + req_tech = list("engineering" = 3, "materials" = 3) + materials = list("$metal" = 15000, "$glass" = 5000) + build_path = /obj/item/weapon/storage/part_replacer + datum/design/item/stock_part/basic_capacitor build_type = PROTOLATHE | AUTOLATHE id = "basic_capacitor" @@ -971,6 +979,18 @@ datum/design/circuit/secure_airlock req_tech = list("programming" = 3) build_path = /obj/item/weapon/airlock_electronics/secure +datum/design/circuit/biogenerator + name = "biogenerator" + id = "biogenerator" + req_tech = list("programming" = 2) + build_path = /obj/item/weapon/circuitboard/biogenerator + +datum/design/circuit/recharge_station + name = "cyborg recharge station" + id = "recharge_station" + req_tech = list("programming" = 3, "engineering" = 2) + build_path = /obj/item/weapon/circuitboard/recharge_station + ///////////////////////////////////////// ////////Power Stuff Circuitboards//////// ///////////////////////////////////////// diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm index aef24dd8bea..7b7445f0993 100644 --- a/code/modules/research/destructive_analyzer.dm +++ b/code/modules/research/destructive_analyzer.dm @@ -12,6 +12,7 @@ Note: Must be placed within 3 tiles of the R&D Console icon_state = "d_analyzer" var/obj/item/weapon/loaded_item = null var/decon_mod = 1 + var/min_reliability = 90 use_power = 1 idle_power_usage = 30 @@ -29,9 +30,9 @@ Note: Must be placed within 3 tiles of the R&D Console /obj/machinery/r_n_d/destructive_analyzer/RefreshParts() var/T = 0 for(var/obj/item/weapon/stock_parts/S in src) - T += S.rating * 0.1 - T = between (0, T, 1) - decon_mod = T + T += S.rating + decon_mod = T * 0.1 + min_reliability = 93 - T /obj/machinery/r_n_d/destructive_analyzer/meteorhit() del(src) @@ -43,65 +44,58 @@ Note: Must be placed within 3 tiles of the R&D Console temp_list[O] = text2num(temp_list[O]) return temp_list +/obj/machinery/r_n_d/destructive_analyzer/update_icon() + if(panel_open) + icon_state = "d_analyzer_t" + else if(loaded_item) + icon_state = "d_analyzer_l" + else + icon_state = "d_analyzer" /obj/machinery/r_n_d/destructive_analyzer/attackby(var/obj/O as obj, var/mob/user as mob) - if (shocked) - shock(user,50) - if (istype(O, /obj/item/weapon/screwdriver)) - if (!opened) - opened = 1 - if(linked_console) - linked_console.linked_destroy = null - linked_console = null - icon_state = "d_analyzer_t" - user << "You open the maintenance hatch of [src]." - else - opened = 0 - icon_state = "d_analyzer" - user << "You close the maintenance hatch of [src]." + if(shocked) + shock(user, 50) + if(default_deconstruction_screwdriver(user, O)) + if(linked_console) + linked_console.linked_destroy = null + linked_console = null return - if (opened) - if(istype(O, /obj/item/weapon/crowbar)) - playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) - var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(src.loc) - M.state = 2 - M.icon_state = "box_1" - for(var/obj/I in component_parts) - I.loc = src.loc - del(src) - return 1 - else - user << "\red You can't load the [src.name] while it's opened." - return 1 - if (disabled) + if(default_deconstruction_crowbar(user, O)) return - if (!linked_console) - user << "\red The destructive analyzer must be linked to an R&D console first!" + if(default_part_replacement(user, O)) return - if (busy) - user << "\red The destructive analyzer is busy right now." + if(panel_open) + user << "You can't load \the [src] while it's opened." + return 1 + if(disabled) return - if (istype(O, /obj/item) && !loaded_item) + if(!linked_console) + user << "\The [src] must be linked to an R&D console first!" + return + if(busy) + user << "\The [src] is busy right now." + return + if(istype(O, /obj/item) && !loaded_item) if(isrobot(user)) //Don't put your module items in there! return if(!O.origin_tech) - user << "\red This doesn't seem to have a tech origin!" + user << "This doesn't seem to have a tech origin!" return var/list/temp_tech = ConvertReqString2List(O.origin_tech) - if (temp_tech.len == 0) - user << "\red You cannot deconstruct this item!" + if(temp_tech.len == 0) + user << "You cannot deconstruct this item!" return - if(O.reliability < 90 && O.crit_fail == 0) - usr << "\red Item is neither reliable enough nor broken enough to learn from." + if(O.reliability < min_reliability && O.crit_fail == 0) + usr << "Item is neither reliable enough nor broken enough to learn from." return busy = 1 loaded_item = O user.drop_item() O.loc = src - user << "\blue You add the [O.name] to the machine!" + user << "You add \the [O] to \the [src]!" flick("d_analyzer_la", src) spawn(10) - icon_state = "d_analyzer_l" + update_icon() busy = 0 return 1 return diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm index f23176de963..22df4b82ddd 100644 --- a/code/modules/research/protolathe.dm +++ b/code/modules/research/protolathe.dm @@ -25,6 +25,8 @@ Note: Must be placed west/left of and R&D console to function. var/uranium_amount = 0.0 var/diamond_amount = 0.0 + var/mat_efficiency = 1 + /obj/machinery/r_n_d/protolathe/New() ..() component_parts = list() @@ -51,80 +53,78 @@ Note: Must be placed west/left of and R&D console to function. for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts) T += M.rating max_material_storage = T * 75000 + T = 0 + for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) + T += M.rating + mat_efficiency = 1 - (T - 2) / 8 + +/obj/machinery/r_n_d/protolathe/dismantle() + for(var/obj/I in component_parts) + if(istype(I, /obj/item/weapon/reagent_containers/glass/beaker)) + reagents.trans_to(I, reagents.total_volume) + if(m_amount >= 3750) + var/obj/item/stack/sheet/metal/G = new /obj/item/stack/sheet/metal(loc) + G.amount = round(m_amount / G.perunit) + if(g_amount >= 3750) + var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(loc) + G.amount = round(g_amount / G.perunit) + if(phoron_amount >= 2000) + var/obj/item/stack/sheet/mineral/phoron/G = new /obj/item/stack/sheet/mineral/phoron(loc) + G.amount = round(phoron_amount / G.perunit) + if(silver_amount >= 2000) + var/obj/item/stack/sheet/mineral/silver/G = new /obj/item/stack/sheet/mineral/silver(loc) + G.amount = round(silver_amount / G.perunit) + if(gold_amount >= 2000) + var/obj/item/stack/sheet/mineral/gold/G = new /obj/item/stack/sheet/mineral/gold(loc) + G.amount = round(gold_amount / G.perunit) + if(uranium_amount >= 2000) + var/obj/item/stack/sheet/mineral/uranium/G = new /obj/item/stack/sheet/mineral/uranium(loc) + G.amount = round(uranium_amount / G.perunit) + if(diamond_amount >= 2000) + var/obj/item/stack/sheet/mineral/diamond/G = new /obj/item/stack/sheet/mineral/diamond(loc) + G.amount = round(diamond_amount / G.perunit) + ..() + +/obj/machinery/r_n_d/protolathe/update_icon() + if(panel_open) + icon_state = "protolathe_t" + else + icon_state = "protolathe" /obj/machinery/r_n_d/protolathe/attackby(var/obj/item/O as obj, var/mob/user as mob) - if (shocked) - shock(user,50) - if (O.is_open_container()) - return 1 - if (istype(O, /obj/item/weapon/screwdriver)) - if (!opened) - opened = 1 - if(linked_console) - linked_console.linked_lathe = null - linked_console = null - icon_state = "protolathe_t" - user << "You open the maintenance hatch of [src]." - else - opened = 0 - icon_state = "protolathe" - user << "You close the maintenance hatch of [src]." + if(shocked) + shock(user, 50) + if(default_deconstruction_screwdriver(user, O)) + if(linked_console) + linked_console.linked_lathe = null + linked_console = null return - if (opened) - if(istype(O, /obj/item/weapon/crowbar)) - playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) - var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(src.loc) - M.state = 2 - M.icon_state = "box_1" - for(var/obj/I in component_parts) - if(istype(I, /obj/item/weapon/reagent_containers/glass/beaker)) - reagents.trans_to(I, reagents.total_volume) - if(I.reliability != 100 && crit_fail) - I.crit_fail = 1 - I.loc = src.loc - if(m_amount >= 3750) - var/obj/item/stack/sheet/metal/G = new /obj/item/stack/sheet/metal(src.loc) - G.amount = round(m_amount / G.perunit) - if(g_amount >= 3750) - var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(src.loc) - G.amount = round(g_amount / G.perunit) - if(phoron_amount >= 2000) - var/obj/item/stack/sheet/mineral/phoron/G = new /obj/item/stack/sheet/mineral/phoron(src.loc) - G.amount = round(phoron_amount / G.perunit) - if(silver_amount >= 2000) - var/obj/item/stack/sheet/mineral/silver/G = new /obj/item/stack/sheet/mineral/silver(src.loc) - G.amount = round(silver_amount / G.perunit) - if(gold_amount >= 2000) - var/obj/item/stack/sheet/mineral/gold/G = new /obj/item/stack/sheet/mineral/gold(src.loc) - G.amount = round(gold_amount / G.perunit) - if(uranium_amount >= 2000) - var/obj/item/stack/sheet/mineral/uranium/G = new /obj/item/stack/sheet/mineral/uranium(src.loc) - G.amount = round(uranium_amount / G.perunit) - if(diamond_amount >= 2000) - var/obj/item/stack/sheet/mineral/diamond/G = new /obj/item/stack/sheet/mineral/diamond(src.loc) - G.amount = round(diamond_amount / G.perunit) - del(src) - return 1 - else - user << "\red You can't load the [src.name] while it's opened." - return 1 - if (disabled) + if(default_deconstruction_crowbar(user, O)) return - if (!linked_console) - user << "\The protolathe must be linked to an R&D console first!" + if(default_part_replacement(user, O)) + return + if(O.is_open_container()) return 1 - if (busy) - user << "\red The protolathe is busy. Please wait for completion of previous operation." + if(panel_open) + user << "You can't load \the [src] while it's opened." return 1 - if (!istype(O, /obj/item/stack/sheet)) - user << "\red You cannot insert this item into the protolathe!" + if(disabled) + return + if(!linked_console) + user << "\The [src] must be linked to an R&D console first!" return 1 - if (stat) + if(busy) + user << "\The [src] is busy. Please wait for completion of previous operation." + return 1 + if(!istype(O, /obj/item/stack/sheet)) + user << "You cannot insert this item into \the [src]!" + return 1 + if(stat) return 1 if(istype(O,/obj/item/stack/sheet)) var/obj/item/stack/sheet/S = O - if (TotalMaterials() + S.perunit > max_material_storage) - user << "\red The protolathe's material bin is full. Please remove material before adding more." + if(TotalMaterials() + S.perunit > max_material_storage) + user << "\The [src]'s material bin is full. Please remove material before adding more." return 1 var/obj/item/stack/sheet/stack = O @@ -137,20 +137,20 @@ Note: Must be placed west/left of and R&D console to function. return if(amount > stack.get_amount()) amount = stack.get_amount() - if(max_material_storage - TotalMaterials() < (amount*stack.perunit))//Can't overfill - amount = min(stack.amount, round((max_material_storage-TotalMaterials())/stack.perunit)) + if(max_material_storage - TotalMaterials() < (amount * stack.perunit))//Can't overfill + amount = min(stack.amount, round((max_material_storage - TotalMaterials()) / stack.perunit)) - src.overlays += "protolathe_[stack.name]" + overlays += "protolathe_[stack.name]" sleep(10) - src.overlays -= "protolathe_[stack.name]" + overlays -= "protolathe_[stack.name]" icon_state = "protolathe" busy = 1 - use_power(max(1000, (3750*amount/10))) + use_power(max(1000, (3750 * amount / 10))) var/stacktype = stack.type stack.use(amount) - if (do_after(user, 16)) - user << "\blue You add [amount] sheets to the [src.name]." + if(do_after(user, 16)) + user << "You add [amount] sheets to \the [src]." icon_state = "protolathe" switch(stacktype) if(/obj/item/stack/sheet/metal) @@ -168,9 +168,9 @@ Note: Must be placed west/left of and R&D console to function. if(/obj/item/stack/sheet/mineral/diamond) diamond_amount += amount * 2000 else - new stacktype(src.loc, amount) + new stacktype(loc, amount) busy = 0 - src.updateUsrDialog() + updateUsrDialog() return //This is to stop these machines being hackable via clicking. diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 8d390fa7856..16c14863aa6 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -93,7 +93,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, /obj/machinery/computer/rdconsole/proc/SyncRDevices() //Makes sure it is properly sync'ed up with the devices attached to it (if any). for(var/obj/machinery/r_n_d/D in oview(3,src)) - if(D.linked_console != null || D.disabled || D.opened) + if(D.linked_console != null || D.disabled || D.panel_open) continue if(istype(D, /obj/machinery/r_n_d/destructive_analyzer)) if(linked_destroy == null) @@ -255,7 +255,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, usr <<"\red The destructive analyzer appears to be empty." screen = 1.0 return - if(linked_destroy.loaded_item.reliability >= 90) + if(linked_destroy.loaded_item.reliability >= linked_destroy.min_reliability) var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech) for(var/T in temp_tech) files.UpdateTech(T, temp_tech[T]) @@ -347,21 +347,21 @@ won't update every console in existence) but it's more of a hassle to do. Also, for(var/M in being_built.materials) switch(M) if("$metal") - linked_lathe.m_amount = max(0, (linked_lathe.m_amount-being_built.materials[M])) + linked_lathe.m_amount = max(0, (linked_lathe.m_amount-being_built.materials[M]*linked_lathe.mat_efficiency)) if("$glass") - linked_lathe.g_amount = max(0, (linked_lathe.g_amount-being_built.materials[M])) + linked_lathe.g_amount = max(0, (linked_lathe.g_amount-being_built.materials[M]*linked_lathe.mat_efficiency)) if("$gold") - linked_lathe.gold_amount = max(0, (linked_lathe.gold_amount-being_built.materials[M])) + linked_lathe.gold_amount = max(0, (linked_lathe.gold_amount-being_built.materials[M]*linked_lathe.mat_efficiency)) if("$silver") - linked_lathe.silver_amount = max(0, (linked_lathe.silver_amount-being_built.materials[M])) + linked_lathe.silver_amount = max(0, (linked_lathe.silver_amount-being_built.materials[M]*linked_lathe.mat_efficiency)) if("$phoron") - linked_lathe.phoron_amount = max(0, (linked_lathe.phoron_amount-being_built.materials[M])) + linked_lathe.phoron_amount = max(0, (linked_lathe.phoron_amount-being_built.materials[M]*linked_lathe.mat_efficiency)) if("$uranium") - linked_lathe.uranium_amount = max(0, (linked_lathe.uranium_amount-being_built.materials[M])) + linked_lathe.uranium_amount = max(0, (linked_lathe.uranium_amount-being_built.materials[M]*linked_lathe.mat_efficiency)) if("$diamond") - linked_lathe.diamond_amount = max(0, (linked_lathe.diamond_amount-being_built.materials[M])) + linked_lathe.diamond_amount = max(0, (linked_lathe.diamond_amount-being_built.materials[M]*linked_lathe.mat_efficiency)) else - linked_lathe.reagents.remove_reagent(M, being_built.materials[M]) + linked_lathe.reagents.remove_reagent(M, being_built.materials[M]*linked_lathe.mat_efficiency) if(being_built.build_path) var/obj/new_item = new being_built.build_path(src) @@ -375,6 +375,10 @@ won't update every console in existence) but it's more of a hassle to do. Also, L.name += " ([new_item.name])"*/ else new_item.loc = linked_lathe.loc + if(linked_lathe.mat_efficiency != 1) // No matter out of nowhere + if(new_item.matter && new_item.matter.len > 0) + for(var/i in new_item.matter) + new_item.matter[i] = new_item.matter[i] * linked_lathe.mat_efficiency linked_lathe.busy = 0 screen = 3.1 errored = 0 @@ -401,15 +405,15 @@ won't update every console in existence) but it's more of a hassle to do. Also, for(var/M in being_built.materials) switch(M) if("$glass") - linked_imprinter.g_amount = max(0, (linked_imprinter.g_amount-being_built.materials[M])) + linked_imprinter.g_amount = max(0, (linked_imprinter.g_amount-being_built.materials[M]*linked_imprinter.mat_efficiency)) if("$gold") - linked_imprinter.gold_amount = max(0, (linked_imprinter.gold_amount-being_built.materials[M])) + linked_imprinter.gold_amount = max(0, (linked_imprinter.gold_amount-being_built.materials[M]*linked_imprinter.mat_efficiency)) if("$diamond") - linked_imprinter.diamond_amount = max(0, (linked_imprinter.diamond_amount-being_built.materials[M])) + linked_imprinter.diamond_amount = max(0, (linked_imprinter.diamond_amount-being_built.materials[M]*linked_imprinter.mat_efficiency)) if("$uranium") - linked_imprinter.uranium_amount = max(0, (linked_imprinter.uranium_amount-being_built.materials[M])) + linked_imprinter.uranium_amount = max(0, (linked_imprinter.uranium_amount-being_built.materials[M]*linked_imprinter.mat_efficiency)) else - linked_imprinter.reagents.remove_reagent(M, being_built.materials[M]) + linked_imprinter.reagents.remove_reagent(M, being_built.materials[M]*linked_imprinter.mat_efficiency) var/obj/new_item = new being_built.build_path(src) new_item.reliability = being_built.reliability if(linked_imprinter.hacked) being_built.reliability = max((reliability / 2), 0) @@ -752,6 +756,10 @@ won't update every console in existence) but it's more of a hassle to do. Also, var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech) for(var/T in temp_tech) dat += "
  • [CallTechName(T)] [temp_tech[T]]" + for(var/datum/tech/F in files.known_tech) + if(F.name == CallTechName(T)) + dat += " (Current: [F.level])" + break dat += "" dat += "
    Deconstruct Item || " dat += "Eject Item || " @@ -775,31 +783,33 @@ won't update every console in existence) but it's more of a hassle to do. Also, var/temp_dat var/check_materials = 1 for(var/M in D.materials) - temp_dat += ", [D.materials[M]] [CallMaterialName(M)]" + temp_dat += ", [D.materials[M]*linked_lathe.mat_efficiency] [CallMaterialName(M)]" if(copytext(M, 1, 2) == "$") switch(M) if("$glass") - if(D.materials[M] > linked_lathe.g_amount) check_materials = 0 + if(D.materials[M]*linked_lathe.mat_efficiency > linked_lathe.g_amount) check_materials = 0 if("$metal") - if(D.materials[M] > linked_lathe.m_amount) check_materials = 0 + if(D.materials[M]*linked_lathe.mat_efficiency > linked_lathe.m_amount) check_materials = 0 if("$gold") - if(D.materials[M] > linked_lathe.gold_amount) check_materials = 0 + if(D.materials[M]*linked_lathe.mat_efficiency > linked_lathe.gold_amount) check_materials = 0 if("$silver") - if(D.materials[M] > linked_lathe.silver_amount) check_materials = 0 + if(D.materials[M]*linked_lathe.mat_efficiency > linked_lathe.silver_amount) check_materials = 0 if("$phoron") - if(D.materials[M] > linked_lathe.phoron_amount) check_materials = 0 + if(D.materials[M]*linked_lathe.mat_efficiency > linked_lathe.phoron_amount) check_materials = 0 if("$uranium") - if(D.materials[M] > linked_lathe.uranium_amount) check_materials = 0 + if(D.materials[M]*linked_lathe.mat_efficiency > linked_lathe.uranium_amount) check_materials = 0 if("$diamond") - if(D.materials[M] > linked_lathe.diamond_amount) check_materials = 0 - else if (!linked_lathe.reagents.has_reagent(M, D.materials[M])) + if(D.materials[M]*linked_lathe.mat_efficiency > linked_lathe.diamond_amount) check_materials = 0 + else if (!linked_lathe.reagents.has_reagent(M, D.materials[M]*linked_lathe.mat_efficiency)) check_materials = 0 if(temp_dat) temp_dat = " \[[copytext(temp_dat,3)]\]" - if (check_materials) + if(check_materials) dat += "
  • [D.name][temp_dat]" else dat += "
  • [D.name][temp_dat]" + if(D.reliability < 100) + dat += " (Reliability: [D.reliability])" dat += "" if(3.2) //Protolathe Material Storage Sub-menu @@ -869,18 +879,18 @@ won't update every console in existence) but it's more of a hassle to do. Also, var/temp_dat var/check_materials = 1 for(var/M in D.materials) - temp_dat += ", [D.materials[M]] [CallMaterialName(M)]" + temp_dat += ", [D.materials[M]*linked_imprinter.mat_efficiency] [CallMaterialName(M)]" if(copytext(M, 1, 2) == "$") switch(M) if("$glass") - if(D.materials[M] > linked_imprinter.g_amount) check_materials = 0 + if(D.materials[M]*linked_imprinter.mat_efficiency > linked_imprinter.g_amount) check_materials = 0 if("$gold") - if(D.materials[M] > linked_imprinter.gold_amount) check_materials = 0 + if(D.materials[M]*linked_imprinter.mat_efficiency > linked_imprinter.gold_amount) check_materials = 0 if("$diamond") - if(D.materials[M] > linked_imprinter.diamond_amount) check_materials = 0 + if(D.materials[M]*linked_imprinter.mat_efficiency > linked_imprinter.diamond_amount) check_materials = 0 if("$uranium") - if(D.materials[M] > linked_imprinter.uranium_amount) check_materials = 0 - else if (!linked_imprinter.reagents.has_reagent(M, D.materials[M])) + if(D.materials[M]*linked_imprinter.mat_efficiency > linked_imprinter.uranium_amount) check_materials = 0 + else if (!linked_imprinter.reagents.has_reagent(M, D.materials[M]*linked_imprinter.mat_efficiency)) check_materials = 0 if(temp_dat) temp_dat = " \[[copytext(temp_dat,3)]\]" @@ -888,6 +898,8 @@ won't update every console in existence) but it's more of a hassle to do. Also, dat += "
  • [D.name][temp_dat]" else dat += "
  • [D.name][temp_dat]" + if(D.reliability < 100) + dat += " (Reliability: [D.reliability])" dat += "" if(4.2) diff --git a/code/modules/research/rdmachines.dm b/code/modules/research/rdmachines.dm index 04f1536c254..4f0b81e5315 100644 --- a/code/modules/research/rdmachines.dm +++ b/code/modules/research/rdmachines.dm @@ -17,7 +17,6 @@ var/hack_wire var/disable_wire var/shock_wire - var/opened = 0 var/obj/machinery/computer/rdconsole/linked_console /obj/machinery/r_n_d/New() @@ -39,7 +38,7 @@ /obj/machinery/r_n_d/attack_hand(mob/user as mob) if (shocked) shock(user,50) - if(opened) + if(panel_open) var/dat as text dat += "[src.name] Wires:
    " for(var/wire in src.wires) diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index 99b4719e28f..5688f6b6d7c 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -103,7 +103,7 @@ /obj/machinery/r_n_d/server/proc/produce_heat() if (!produces_heat) return - + if (!use_power) return @@ -118,7 +118,7 @@ if(removed) var/heat_produced = idle_power_usage //obviously can't produce more heat than the machine draws from it's power source - + removed.add_thermal_energy(heat_produced) env.merge(removed) @@ -129,16 +129,16 @@ if (shocked) shock(user,50) if (istype(O, /obj/item/weapon/screwdriver)) - if (!opened) - opened = 1 + if (!panel_open) + panel_open = 1 icon_state = "server_o" user << "You open the maintenance hatch of [src]." else - opened = 0 + panel_open = 0 icon_state = "server" user << "You close the maintenance hatch of [src]." return - if (opened) + if (panel_open) if(istype(O, /obj/item/weapon/crowbar)) griefProtection() playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) diff --git a/code/setup.dm b/code/setup.dm index e64947838b7..138772e603a 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -291,33 +291,8 @@ #define FAT 6 #define HUSK 7 #define NOCLONE 8 - -// Extra powers: -// FIXME: These are duplicated below, but it seems that these should be in the latter form. The flags duplicated are never used anywhere else. -#define SHADOW (1 << 10) // 25% - Shadow teleportation. (create in/out portals anywhere) -#define SCREAM (1 << 11) // 25% - Supersonic screaming. -#define EXPLOSIVE (1 << 12) // 15% - Exploding on-demand. -#define REGENERATION (1 << 13) // 30% - Superhuman regeneration. -#define REPROCESSOR (1 << 14) // 50% - Eat anything. -#define SHAPESHIFTING (1 << 15) // 40% - Take on the appearance of anything. -#define PHASING (1 << 16) // 40% - Ability to phase through walls. -#define SHIELD (1 << 17) // 30% - Shielding from all projectile attacks. -#define SHOCKWAVE (1 << 18) // 25% - Attack a nearby tile and cause a massive shockwave, knocking most people on their asses. -#define ELECTRICITY (1 << 19) // 15% - Ability to shoot electric attacks. - -#define LASER 9 // Harm intent - click anywhere to shoot lasers from eyes. -#define HEAL 10 // Healing people with hands. - -#define SHADOW 11 // 25% - Shadow teleportation. (create in/out portals anywhere) -#define SCREAM 12 // 25% - Supersonic screaming. -#define EXPLOSIVE 13 // 15% - Sxploding on-demand. -#define REGENERATION 14 // 30% - Superhuman regeneration. -#define REPROCESSOR 15 // 50% - Eat anything. -#define SHAPESHIFTING 16 // 40% - Take on the appearance of anything. -#define PHASING 17 // 40% - Ability to phase through walls. -#define SHIELD 18 // 30% - Shielding from all projectile attacks. -#define SHOCKWAVE 19 // 25% - Attack a nearby tile and cause a massive shockwave, knocking most people on their asses. -#define ELECTRICITY 20 // 15% - Ability to shoot electric attacks. +#define LASER 9 // Harm intent - click anywhere to shoot lasers from eyes. +#define HEAL 10 // Healing people with hands. #define SKELETON 29 #define PLANT 30 diff --git a/icons/mob/collar.dmi b/icons/mob/collar.dmi index fccfe6dd53b..ff6be009b75 100644 Binary files a/icons/mob/collar.dmi and b/icons/mob/collar.dmi differ diff --git a/icons/mob/items_lefthand.dmi b/icons/mob/items_lefthand.dmi index b70af9c656e..1239c1c1b58 100644 Binary files a/icons/mob/items_lefthand.dmi and b/icons/mob/items_lefthand.dmi differ diff --git a/icons/mob/items_righthand.dmi b/icons/mob/items_righthand.dmi index c6183f6ff58..c7521751add 100644 Binary files a/icons/mob/items_righthand.dmi and b/icons/mob/items_righthand.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index 0099cac9d46..b0fb2821597 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/ties.dmi b/icons/mob/ties.dmi index 32792a32119..8206ece012a 100644 Binary files a/icons/mob/ties.dmi and b/icons/mob/ties.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 2ac56359324..11e62da896d 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index c57f93464da..a1189267e9d 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/custom_items.dmi b/icons/obj/custom_items.dmi index beae558e4c4..975d9b6b36a 100644 Binary files a/icons/obj/custom_items.dmi and b/icons/obj/custom_items.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index 989c1001b3c..377d12b4ff0 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/maps/exodus-1.dmm b/maps/exodus-1.dmm index 360948e33c0..73cb64ef9eb 100644 --- a/maps/exodus-1.dmm +++ b/maps/exodus-1.dmm @@ -346,7 +346,7 @@ "agH" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Warden's Office"; req_access_txt = "3"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/security/warden) "agI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/security/warden) "agJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/warden) -"agK" = (/obj/structure/closet/wardrobe/red,/obj/structure/window/reinforced,/obj/item/clothing/tie/holster/waist,/obj/item/clothing/tie/holster/waist,/obj/item/clothing/tie/holster/waist,/obj/item/clothing/tie/armband,/obj/item/clothing/tie/armband,/obj/item/clothing/tie/armband,/turf/simulated/floor,/area/security/main) +"agK" = (/obj/structure/closet/wardrobe/red,/obj/structure/window/reinforced,/obj/item/clothing/accessory/holster/waist,/obj/item/clothing/accessory/holster/waist,/obj/item/clothing/accessory/holster/waist,/obj/item/clothing/accessory/armband,/obj/item/clothing/accessory/armband,/obj/item/clothing/accessory/armband,/turf/simulated/floor,/area/security/main) "agL" = (/obj/structure/closet/secure_closet/security,/obj/item/device/flashlight/flare,/obj/structure/window/reinforced,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/security/main) "agM" = (/obj/structure/reagent_dispensers/peppertank{pixel_x = 30},/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) "agN" = (/obj/structure/disposalpipe/sortjunction{dir = 1; name = "HoS Office"; sortType = "HoS Office"},/turf/simulated/wall,/area/crew_quarters/heads/hos) @@ -523,7 +523,7 @@ "akc" = (/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/brig) "akd" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/brig) "ake" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/security/brig) -"akf" = (/obj/structure/table,/obj/machinery/recharger/wallcharger{pixel_x = 4; pixel_y = -28},/obj/item/clothing/tie/holobadge,/obj/item/clothing/tie/holobadge,/obj/item/clothing/tie/holobadge/cord,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) +"akf" = (/obj/structure/table,/obj/machinery/recharger/wallcharger{pixel_x = 4; pixel_y = -28},/obj/item/clothing/accessory/holobadge,/obj/item/clothing/accessory/holobadge,/obj/item/clothing/accessory/holobadge/cord,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) "akg" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "red"; dir = 5},/area/security/brig) "akh" = (/obj/structure/table/rack,/obj/item/weapon/storage/briefcase{pixel_x = -2; pixel_y = -5},/obj/item/weapon/storage/briefcase{pixel_x = 3; pixel_y = 0},/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) "aki" = (/obj/structure/disposalpipe/segment,/obj/structure/closet{name = "Evidence Closet"},/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) @@ -1132,12 +1132,12 @@ "avN" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/arrivals) "avO" = (/obj/machinery/space_heater,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/plating,/area/maintenance/arrivals) "avP" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/hallway/primary/central_one) -"avQ" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "eva_airlock"; name = "exterior access button"; pixel_x = 0; pixel_y = 25; req_access_txt = "13"},/turf/simulated/floor/plating/airless,/area/maintenance/evahallway) +"avQ" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "eva_airlock"; name = "exterior access button"; pixel_x = 0; pixel_y = 25; req_access_txt = "1;11;18;24"},/turf/simulated/floor/plating/airless,/area/maintenance/evahallway) "avR" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eva_outer"; locked = 1; name = "EVA External Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/airless{icon_state = "circuit"},/area/maintenance/evahallway) "avS" = (/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "eva_sensor"; pixel_x = 0; pixel_y = 25},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "eva_pump"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/maintenance/evahallway) "avT" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1379; id_tag = "eva_airlock"; name = "EVA Airlock Console"; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "1;5;11;18;24"; tag_airpump = "eva_pump"; tag_chamber_sensor = "eva_sensor"; tag_exterior_door = "eva_outer"; tag_interior_door = "eva_inner"},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"; tag = "icon-manifold-f (EAST)"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/maintenance/evahallway) "avU" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eva_inner"; locked = 1; name = "EVA Internal Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/evahallway) -"avV" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "eva_airlock"; name = "interior access button"; pixel_x = 0; pixel_y = 25; req_access_txt = "13"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/maintenance/evahallway) +"avV" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "eva_airlock"; name = "interior access button"; pixel_x = 0; pixel_y = 25; req_access_txt = "1;11;18;24"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/maintenance/evahallway) "avW" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/evahallway) "avX" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/maintenance/evahallway) "avY" = (/obj/machinery/shower{dir = 4; icon_state = "shower"; pixel_x = 5; pixel_y = 0},/obj/structure/curtain/open/shower,/turf/simulated/floor{icon_state = "freezerfloor"},/area/security/prison) @@ -1979,8 +1979,8 @@ "aMc" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/central_one) "aMd" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_one) "aMe" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/sign/securearea,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_one) -"aMf" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_command{name = "E.V.A."; req_access_txt = "0"; req_one_access_txt = "1;5;11;18;24"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "dark"},/area/hallway/primary/central_one) -"aMg" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_command{name = "E.V.A."; req_access_txt = "0"; req_one_access_txt = "1;5;11;18;24"},/turf/simulated/floor{icon_state = "dark"},/area/hallway/primary/central_one) +"aMf" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_command{name = "E.V.A."; req_access_txt = "0"; req_one_access_txt = "1;11;18;24"},/turf/simulated/floor{icon_state = "dark"},/area/hallway/primary/central_one) +"aMg" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_command{name = "E.V.A."; req_access_txt = "0"; req_one_access_txt = "1;11;18;24"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "dark"},/area/hallway/primary/central_one) "aMh" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/sign/securearea,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_one) "aMi" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_one) "aMj" = (/obj/structure/extinguisher_cabinet{pixel_x = -24},/turf/simulated/floor,/area/hallway/primary/central_one) @@ -4184,7 +4184,7 @@ "bCx" = (/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bCy" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bCz" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) -"bCA" = (/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "acutesep"; name = "Acute Separation Shutters"; opacity = 0},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/sleeper) +"bCA" = (/obj/structure/table/reinforced,/obj/machinery/door/window/eastright{dir = 1; name = "Emergency Kit"; req_access_txt = "5"},/obj/machinery/door/firedoor,/turf/simulated/floor{dir = 1; icon_state = "whiteyellow"},/area/medical/sleeper) "bCB" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "Research Division"},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor{icon_state = "bot"},/area/rnd/research) "bCC" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/rnd/docking) "bCD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/rnd/docking) @@ -4230,7 +4230,7 @@ "bDr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor,/area/hallway/primary/central_two) "bDs" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"; pixel_x = 32},/turf/simulated/floor,/area/hallway/primary/central_two) "bDt" = (/turf/simulated/wall,/area/medical/sleeper) -"bDu" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/backpack/medic,/obj/item/roller,/obj/item/roller,/obj/item/roller,/obj/item/weapon/storage/toolbox/emergency,/obj/item/bodybag/cryobag{pixel_x = -3},/obj/item/bodybag/cryobag{pixel_x = -3},/obj/item/device/radio{frequency = 1487; name = "Medbay Emergency Radio Link"},/obj/machinery/door/window/eastright{dir = 1; name = "Emergency Kit"; req_access_txt = "5"},/obj/machinery/door/firedoor,/turf/simulated/floor{dir = 1; icon_state = "whiteyellow"},/area/medical/sleeper) +"bDu" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bDv" = (/obj/structure/closet/secure_closet/medical_wall{name = "Pill Cabinet"},/obj/item/weapon/storage/pill_bottle/antitox,/obj/item/weapon/storage/pill_bottle/tramadol,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/inaprovaline,/turf/simulated/wall,/area/medical/sleeper) "bDw" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Medicine Storage"; req_access_txt = "5"},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bDx" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/medical/sleeper) @@ -4238,7 +4238,7 @@ "bDz" = (/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "bDA" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/medbay) "bDB" = (/obj/structure/table,/obj/item/clothing/suit/straight_jacket,/obj/item/clothing/mask/muzzle,/obj/machinery/light,/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/turf/simulated/floor{tag = "icon-whiteblue (SOUTHWEST)"; icon_state = "whiteblue"; dir = 10},/area/medical/medbay3) -"bDC" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/clothing/tie/stethoscope,/obj/item/clothing/tie/stethoscope,/obj/item/clothing/tie/stethoscope,/obj/item/clothing/tie/stethoscope,/obj/machinery/camera{c_tag = "Medbay Equipment Storage"; dir = 1},/obj/item/clothing/tie/stethoscope,/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 0; pixel_y = -22},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay3) +"bDC" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/clothing/accessory/stethoscope,/obj/item/clothing/accessory/stethoscope,/obj/item/clothing/accessory/stethoscope,/obj/item/clothing/accessory/stethoscope,/obj/machinery/camera{c_tag = "Medbay Equipment Storage"; dir = 1},/obj/item/clothing/accessory/stethoscope,/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 0; pixel_y = -22},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay3) "bDD" = (/obj/structure/table,/obj/machinery/light,/obj/item/weapon/storage/box/gloves{pixel_x = 4; pixel_y = 4},/obj/item/weapon/storage/box/masks{pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{tag = "icon-whiteblue (SOUTHEAST)"; icon_state = "whiteblue"; dir = 6},/area/medical/medbay3) "bDE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/medbay2) "bDF" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) @@ -4255,7 +4255,7 @@ "bDQ" = (/obj/item/weapon/table_parts,/turf/simulated/floor/plating,/area/medical/genetics) "bDR" = (/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/plating,/area/medical/genetics) "bDS" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay2) -"bDT" = (/obj/machinery/door/firedoor,/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "acute1"; name = "Acute One Privacy Shutters"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/medbay) +"bDT" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bDU" = (/obj/structure/sign/securearea,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/rnd/research) "bDV" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/medical/medbay3) "bDW" = (/obj/machinery/light{dir = 1},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 8; name = "hazard door west"},/turf/simulated/floor{dir = 8; icon_state = "whiteblue"},/area/rnd/research) @@ -4347,7 +4347,7 @@ "bFE" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plating,/area/medical/genetics) "bFF" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/research{name = "Genetics Research"; req_access_txt = "9"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics) "bFG" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; external_pressure_bound = 0; external_pressure_bound_default = 0; icon_state = "map_vent_in"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/turf/simulated/floor/bluegrid{name = "Server Base"; nitrogen = 500; oxygen = 0; temperature = 80},/area/server) -"bFH" = (/obj/machinery/door/firedoor,/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "acute1"; name = "Acute One Privacy Shutters"; opacity = 0},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/medbay) +"bFH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "acute1"; name = "EMT Storage Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/sleeper) "bFI" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced,/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay) "bFJ" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 8; name = "hazard door west"},/turf/simulated/floor{dir = 8; icon_state = "whiteblue"},/area/rnd/research) "bFK" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) @@ -4399,7 +4399,7 @@ "bGE" = (/obj/machinery/door/airlock/multi_tile/glass{autoclose = 1; dir = 2; req_access_txt = "5"},/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/medical/sleeper) "bGF" = (/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bGG" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) -"bGH" = (/obj/machinery/light,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"bGH" = (/obj/machinery/door/firedoor,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "acute1"; name = "EMT Storage Privacy Shutters"; opacity = 0},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/sleeper) "bGI" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "bGJ" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "bGK" = (/obj/structure/disposalpipe/sortjunction/flipped{dir = 1; sortType = "Chemistry"; name = "Chemistry"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/medbay) @@ -4545,12 +4545,12 @@ "bJu" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor,/area/hallway/primary/central_two) "bJv" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/central_two) "bJw" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=HOP"; location = "CHE"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/hallway/primary/central_two) -"bJx" = (/obj/machinery/iv_drip,/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/sleeper) -"bJy" = (/obj/machinery/door_control{id = "acute1"; name = "Acute One Privacy Shutters"; pixel_x = 6; pixel_y = 25; req_access_txt = "5"},/obj/machinery/camera{c_tag = "Medbay Acute 1"; network = list("SS13")},/obj/machinery/door_control{id = "acute1em"; name = "Acute One Entry Shutters"; pixel_x = -6; pixel_y = 25; req_access_txt = "5"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"bJx" = (/turf/simulated/floor/mech_bay_recharge_floor,/area/medical/sleeper) +"bJy" = (/obj/machinery/mech_bay_recharge_port,/turf/simulated/floor/plating,/area/medical/sleeper) "bJz" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay2) "bJA" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay) "bJB" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay) -"bJC" = (/obj/machinery/door/firedoor,/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "acute2"; name = "Acute Two Privacy Shutters"; opacity = 0},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/medbay) +"bJC" = (/obj/machinery/computer/mech_bay_power_console,/turf/simulated/floor/bluegrid,/area/medical/sleeper) "bJD" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{id_tag = "cmodoor"; name = "CMO's Office"; req_access_txt = "40"},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) "bJE" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/medical/medbay4) "bJF" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay4) @@ -4625,11 +4625,11 @@ "bKW" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/turf/simulated/floor,/area/hallway/primary/central_two) "bKX" = (/obj/machinery/light,/turf/simulated/floor,/area/hallway/primary/central_two) "bKY" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor,/area/hallway/primary/central_two) -"bKZ" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = -25; pixel_y = 0; req_access_txt = "0"},/obj/structure/stool/bed,/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/sleeper) -"bLa" = (/obj/machinery/sleeper,/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"bKZ" = (/obj/machinery/vending/medical,/turf/simulated/wall,/area/medical/medbay) +"bLa" = (/obj/machinery/door_control{id = "acute1"; name = "EMT Storage Privacy Shutters"; pixel_x = 26; pixel_y = 25; req_access_txt = "5"},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bLb" = (/obj/machinery/sleep_console,/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bLc" = (/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "scanhide"; name = "Diagnostics Room Separation Shutters"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/sleeper) -"bLd" = (/turf/simulated/floor{icon_state = "white_1"},/area/medical/medbay) +"bLd" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay) "bLe" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay) "bLf" = (/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "scanhide"; name = "Diagnostics Room Separation Shutters"; opacity = 0},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/sleeper) "bLg" = (/obj/machinery/light{dir = 1},/obj/structure/filingcabinet/chestdrawer{dir = 1},/turf/simulated/floor{tag = "icon-whiteblue (NORTHWEST)"; icon_state = "whiteblue"; dir = 9},/area/crew_quarters/heads/cmo) @@ -4696,12 +4696,12 @@ "bMp" = (/obj/machinery/door/airlock{name = "Custodial Closet"; req_access_txt = "26"},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/hallway/primary/central_three) "bMq" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/central_two) "bMr" = (/obj/machinery/vending/cigarette,/turf/simulated/floor{icon_state = "dark"},/area/hallway/primary/central_two) -"bMs" = (/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/obj/item/roller,/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/sleeper) -"bMt" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) -"bMu" = (/obj/machinery/door_control{id = "acutesep"; name = "Acute Separation Shutters"; pixel_y = -25; req_access_txt = "5"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) -"bMv" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{autoclose = 0; name = "Acute One"; req_access_txt = "5"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/medbay) -"bMw" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) -"bMx" = (/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 28},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay) +"bMs" = (/obj/structure/table/rack,/obj/item/weapon/crowbar,/obj/item/weapon/crowbar,/obj/item/weapon/storage/toolbox/mechanical,/obj/machinery/vending/wallmed1{pixel_x = -32; pixel_y = 0; req_access_txt = "0"},/obj/item/roller,/obj/item/roller,/obj/item/roller,/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"bMt" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{autoclose = 1; name = "EMT Storage"; req_access_txt = "5"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/medbay) +"bMu" = (/obj/structure/stool{pixel_y = 8},/obj/effect/landmark/start{name = "Paramedic"},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"bMv" = (/obj/structure/sign/poster{pixel_x = -32; pixel_y = 0},/obj/structure/closet/secure_closet/medical1,/obj/item/device/radio/intercom{broadcasting = 0; canhear_range = 5; freerange = 0; frequency = 1485; listening = 1; name = "Station Intercom (Medbay)"; pixel_x = 0; pixel_y = -31},/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/device/flashlight,/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"bMw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"bMx" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay) "bMy" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/structure/table,/obj/machinery/photocopier/faxmachine{department = "CMO's Office"},/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/crew_quarters/heads/cmo) "bMz" = (/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) "bMA" = (/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) @@ -4779,8 +4779,8 @@ "bNU" = (/turf/simulated/wall,/area/maintenance/engineering) "bNV" = (/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/structure/closet/secure_closet/medical_wall{name = "O- Blood Locker"},/turf/simulated/wall,/area/medical/sleeper) "bNW" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "misclab"; name = "Test Chamber Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) -"bNX" = (/obj/machinery/vending/medical,/obj/machinery/light_switch{pixel_x = 22; pixel_y = 0},/turf/simulated/wall,/area/medical/sleeper) -"bNY" = (/obj/structure/sign/greencross,/turf/simulated/wall,/area/medical/medbay) +"bNX" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/medical/medbay) +"bNY" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white_1"},/area/medical/medbay) "bNZ" = (/obj/machinery/hologram/holopad,/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "bOa" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "bOb" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{name = "CMO's Office"; req_access_txt = "40"},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) @@ -4861,7 +4861,7 @@ "bPy" = (/obj/structure/table/rack{dir = 1},/obj/item/clothing/suit/fire/firefighter,/obj/item/weapon/tank/oxygen,/obj/item/clothing/mask/gas,/obj/item/weapon/extinguisher,/obj/item/clothing/head/hardhat/red,/obj/item/clothing/glasses/meson,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/plating,/area/maintenance/engineering) "bPz" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bPA" = (/obj/machinery/door_control{id = "acutesep"; name = "Acute Separation Shutters"; pixel_y = 25; req_access_txt = "5"},/obj/machinery/camera{c_tag = "Medbay Acute 2"; network = list("SS13")},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) -"bPB" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{autoclose = 0; name = "Acute Two"; req_access_txt = "5"},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/medbay) +"bPB" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "acutesep"; name = "Acute Separation Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/sleeper) "bPC" = (/obj/machinery/camera{c_tag = "Medbay Port Corridor"; dir = 8; network = list("SS13")},/obj/structure/disposalpipe/segment,/obj/machinery/light_switch{pixel_x = 22; pixel_y = -9},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay) "bPD" = (/obj/machinery/camera{c_tag = "Medbay CMO Office"; dir = 4; network = list("SS13")},/obj/machinery/light_switch{pixel_x = -22; pixel_y = -9},/obj/machinery/requests_console{announcementConsole = 1; department = "Chief Medical Officer's Desk"; departmentType = 5; name = "Chief Medical Officer RC"; pixel_x = -34; pixel_y = 2},/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/crew_quarters/heads/cmo) "bPE" = (/obj/structure/table,/obj/machinery/computer/skills{pixel_y = 4},/obj/item/device/megaphone,/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) @@ -4933,7 +4933,7 @@ "bQS" = (/obj/effect/decal/cleanable/cobweb,/obj/effect/decal/cleanable/generic,/turf/simulated/floor/plating,/area/maintenance/engineering) "bQT" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/engineering) "bQU" = (/obj/structure/closet,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/maintenance/engineering) -"bQV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"bQV" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{autoclose = 1; name = "EMT Storage"; req_access_txt = "5"},/obj/machinery/light_switch{pixel_x = 22; pixel_y = 0},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/sleeper) "bQW" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "misclab"; name = "Test Chamber Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/engine,/area/rnd/misc_lab) "bQX" = (/turf/simulated/floor{icon_state = "white_2"},/area/medical/medbay) "bQY" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 4; frequency = 1441; icon_state = "map_injector"; id = "n2_in"; use_power = 1},/turf/simulated/floor/engine,/area/rnd/misc_lab) @@ -5003,11 +5003,11 @@ "bSk" = (/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/maintenance/engineering) "bSl" = (/obj/structure/table,/obj/item/device/t_scanner,/turf/simulated/floor/plating,/area/maintenance/engineering) "bSm" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) -"bSn" = (/obj/machinery/door_control{id = "acute2"; name = "Acute Two Privacy Shutters"; pixel_x = 6; pixel_y = -25; req_access_txt = "5"},/obj/machinery/door_control{id = "scanhide"; name = "Diagnostics Room Separation Shutters"; pixel_x = -6; pixel_y = -25; req_access_txt = "5"},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"bSn" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "acutesep"; name = "Acute Separation Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/sleeper) "bSo" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "bSp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "staffroom"; name = "Staff Room Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay2) "bSq" = (/obj/machinery/light,/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/turf/simulated/floor{dir = 10; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/crew_quarters/heads/cmo) -"bSr" = (/obj/structure/table/rack,/obj/item/clothing/tie/stethoscope,/obj/item/clothing/glasses/hud/health,/obj/item/device/flashlight/pen,/obj/item/weapon/storage/belt/medical,/obj/machinery/keycard_auth{pixel_x = 0; pixel_y = -24},/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = -38},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/crew_quarters/heads/cmo) +"bSr" = (/obj/structure/table/rack,/obj/item/clothing/accessory/stethoscope,/obj/item/clothing/glasses/hud/health,/obj/item/device/flashlight/pen,/obj/item/weapon/storage/belt/medical,/obj/machinery/keycard_auth{pixel_x = 0; pixel_y = -24},/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = -38},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/crew_quarters/heads/cmo) "bSs" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) "bSt" = (/obj/machinery/computer/crew,/obj/machinery/light,/turf/simulated/floor{dir = 6; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/crew_quarters/heads/cmo) "bSu" = (/obj/machinery/door/window/eastright{base_state = "left"; dir = 8; icon_state = "left"; name = "Research Division Delivery"; req_access_txt = "47"},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor{icon_state = "delivery"},/area/rnd/research) @@ -5098,7 +5098,7 @@ "bUb" = (/obj/structure/table/reinforced,/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/noticeboard{pixel_y = 27},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "hop_office_desk"; name = "HoP Office Privacy Shutters"; opacity = 0},/obj/machinery/door/window/northleft{dir = 8; icon_state = "left"; name = "Reception Window"; req_access_txt = "0"},/obj/machinery/door/window/brigdoor{base_state = "rightsecure"; dir = 4; icon_state = "rightsecure"; name = "Head of Personnel's Desk"; req_access_txt = "57"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/crew_quarters/heads/hop) "bUc" = (/obj/machinery/atmospherics/unary/freezer{dir = 2; icon_state = "freezer_1"; use_power = 1; power_setting = 20; set_temperature = 73},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{icon_state = "dark"},/area/server) "bUd" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; icon_state = "map_vent_out"; use_power = 1},/turf/simulated/floor/bluegrid{name = "Server Base"; nitrogen = 500; oxygen = 0; temperature = 80},/area/server) -"bUe" = (/obj/machinery/door/firedoor,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "acute1em"; name = "Acute One Entry Shutters"; opacity = 0},/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/sleeper) +"bUe" = (/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/obj/machinery/sleeper,/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/sleeper) "bUf" = (/obj/structure/sign/science{pixel_x = 32},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bUg" = (/turf/simulated/wall,/area/rnd/misc_lab) "bUh" = (/obj/machinery/light_switch{pixel_y = -23},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor{icon_state = "floorgrime"},/area/rnd/storage) @@ -7184,6 +7184,15 @@ "cIh" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_x = 0; pixel_y = 32},/obj/structure/cable/cyan{d2 = 8; icon_state = "0-8"},/obj/machinery/power/smes/buildable{charge = 2e+006; RCon_tag = "Substation - Atmospherics"},/turf/simulated/floor/plating,/area/engineering/atmos/storage) "cIi" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = -7; pixel_y = -32; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/structure/extinguisher_cabinet{pixel_x = 7; pixel_y = -32},/turf/simulated/floor,/area/rnd/xenobiology) "cIj" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/turf/simulated/floor{icon_state = "blue"; dir = 4},/area/medical/surgeryprep) +"cIk" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{autoclose = 0; name = "Acute Treatment"; req_access_txt = "5"},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/medbay) +"cIl" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/stool/bed/roller,/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/sleeper) +"cIm" = (/obj/machinery/door/firedoor,/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "acute2"; name = "Acute Two Privacy Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/medical/medbay) +"cIn" = (/obj/structure/stool/bed,/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"cIo" = (/obj/machinery/sleeper,/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/sleeper) +"cIp" = (/obj/machinery/door/firedoor,/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "acute2"; name = "Acute Two Privacy Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/medical/medbay) +"cIq" = (/obj/machinery/door_control{id = "scanhide"; name = "Diagnostics Room Separation Shutters"; pixel_x = -6; pixel_y = -25; req_access_txt = "5"},/obj/machinery/iv_drip,/obj/machinery/door_control{id = "acute2"; name = "Acute Treatment Privacy Shutters"; pixel_x = 6; pixel_y = -25; req_access_txt = "5"},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"cIr" = (/obj/structure/table,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/structure/closet/fireaxecabinet{pixel_x = 32; pixel_y = 0},/obj/item/weapon/storage/toolbox/emergency,/obj/item/bodybag/cryobag{pixel_x = 6},/obj/item/bodybag/cryobag{pixel_x = 6},/obj/item/bodybag/cryobag{pixel_x = 6},/obj/item/device/radio{frequency = 1487; name = "Medbay Emergency Radio Link"},/obj/machinery/door_control{id = "acutesep"; name = "Acute Separation Shutters"; pixel_y = -25; req_access_txt = "5"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"cIs" = (/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 28},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay) "cIJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/maintenance/portsolar) "cIK" = (/turf/simulated/wall/r_wall,/area/maintenance/portsolar) "cIL" = (/turf/simulated/wall/r_wall,/area/maintenance/engi_engine) @@ -7346,7 +7355,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaT aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaFraGIaGJaGKaFlaGLaFlaGLaFlaGLaFlaGLaFlaGMaGNaGOaDPayuaBLaGPaFAaGRaGSaGTaGUaCEaFBaFDaFCaFCaFCbazaFEaFCaHcaFLaFLaFLaFLaFLaFLaFLaFNaHdaCMaafaBYaHeaHfaHgaHhaHiaBYaafazJazOazPaHjaHkaFUaHlaHmazPaHnaHoayLaHpazTaARaHqaATaHrazTaCfaFYaHsazTaHtarAaHuaHvaHwarEaGuaDyaEUaGvaDwaDxaEVaEWatEaHCaHDaBjaHEaBjaHFaBjaHGaBjaHHaGpaHIaDpaHJaHKaHLaHMaHMaHNaHOaHKaHKaHKaHKaHKaHPaHKaHKaHKaHQaHVaDsaDsaDsaDCaGAaGBaHWaHXaHYaIaaDCaDCaIcaDCaIdaIeaIfaIgaGFaIhaGFaIiaIjaIkaIlbinaInaIoaIpaIqaIraIsbjFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaIwaFlaFlaDKaFlaGLaFlaGLaIxaGLaIyaGLaFlaGMaGNaGOaDPaFFaIAaIAaFGaICaIDaICaIAaIAaIEaIFaFCaGQaFHaGWaGVaFCaIKaILaIMaFLaFLaINaFLaIOaIPaIKaCMaaaaBYaBYaIQaIRaIQaBYaBYaaaazJazOazPaISaITaIUaFTaIVazPaIWaIXayLaIYazTaIZaEwaCfaJaaEyaATaJbaJcazTaJdaJeaJfaJgaJhaMbaECaCuaCuaCuaCuaCuaJjaJkaJlaJmaJnaBjaJoaBjaJpaBjaJqaBjaJraGpaJsaJtaGsaGsaDqaJvaDsaDsaJwaDsaDsaJxaDsaGsaJyaGsaGsaGsaJzaHZaJBaJAaJAbrpaJHaKbaJGaJGaYnbpvaIgaJIaJJaJKaJLaJMaJNaIgaJOaJPaGFaJQaJRaJSaJTbinaJUaIoaJVaBtaGGaGGaGGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaFraJXaGJaGKaFlaGLaFlaGLaFlaGLaFlaGLaFlaGMaGNaGOaDPaGYaGXaHaaGZaHbaHbaIBaIzaIHaIGaIJaIIaJZaJYatiaKaaFCaIKaKmaKnaKoaKpaIKaKqaKraKsaKtaKuaaaaafaaaaKvaKwaKvaaaaafaaaaKuazOazPaKxaKyaKzaKAaKBazPaKCaKDayLaKEazTaARaKFaKGaHrazTaKHaKIaKJaKKaKLaJeaEDaKNaKOaKPaEEaKRaaaaaaaJlaKSaKTaKUaJlaKVaJnaJnaJnaKWaJnaJnaJnaBjaDpaKXaDpaDpaDpaDpaKYaDpaKZaLaaLbaLcaLdaLeaLfaLgaLhaLfaLfaLfaLfaLfaLiaLfaLfaLfaLfaLfaLfaLfaLfaAraIgaLjaLkaLlaEFaLnaLoaIgaLpathaGFaLraLsaLtaJTaRraJUaIoaJVaIoaLvaLwaLxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaLyaLzaDJaFkaFlaFlaFlaLAaFlaFlaLBaFlaFlaFraLCaLDaDPaLEaLFaLGaLHaLGaLGaLGaLGaLGaLIaLJaFCaFCaFCaFCaFCaFCaLLaLMaLNaLOaLOaLOaLOaLPaLQaLRaKuaLSaLTaLTaLUaLVaLWaLTaLTaLXaKuaLYaKuaKuaLZaMaaLZaJeaJeaMbaMcaJeaJeaJeaJeaMdaMeaMfaMgaMhaMiaJeaJeaJeaJeaMjaKNaMkaMkaMlaMmaMnaMoaJlaMpaMqaMraJlaJlaJlaJlaJlaJlaJlaJlaBjaBjaMsaMtaMuaMvaMwaMxaMyaMzaKZaMAaMBaMCaMCaMDaLfaMEaMFaMGaMHaMIaMJaMKaMLaMMaMNaMHaMJaMIaMHaMOaLfaAraIgaMPaMQaMRaMSaMTaMUaIgaMVaMWaMXaMYaMZaNaaNbaGFaGGaNcaJVaIoaNdaNeaNfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaLyaLzaDJaFkaFlaFlaFlaLAaFlaFlaLBaFlaFlaFraLCaLDaDPaLEaLFaLGaLHaLGaLGaLGaLGaLGaLIaLJaFCaFCaFCaFCaFCaFCaLLaLMaLNaLOaLOaLOaLOaLPaLQaLRaKuaLSaLTaLTaLUaLVaLWaLTaLTaLXaKuaLYaKuaKuaLZaMaaLZaJeaJeaMbaMcaJeaJeaJeaJeaMdaMeaMgaMfaMhaMiaJeaJeaJeaJeaMjaKNaMkaMkaMlaMmaMnaMoaJlaMpaMqaMraJlaJlaJlaJlaJlaJlaJlaJlaBjaBjaMsaMtaMuaMvaMwaMxaMyaMzaKZaMAaMBaMCaMCaMDaLfaMEaMFaMGaMHaMIaMJaMKaMLaMMaMNaMHaMJaMIaMHaMOaLfaAraIgaMPaMQaMRaMSaMTaMUaIgaMVaMWaMXaMYaMZaNaaNbaGFaGGaNcaJVaIoaNdaNeaNfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaaaaaaaaaaaaaLyaDJaDKaDJaDJaDLaDMaDJaDJaDKaLzaNgaBIaNhaLEaNiaNjaNjaNkaNjaNlaIAaNmaNnaLJaNoaNpaNqaNraNsaNtaNraNuaNraNraNraNvaNraNraNwaNxaNyaNzaNAaNBaNzaNCaNzaNzaNzaNzaNDaNEaNFaNGaNraNHaNIaNJaNKaNLaNMaNLaNNaNOaNPaNQaNQaNRaNSaNTaNSaNUaNVaNWaEGaNYaNZaOaaObaOcaMkaMkaMkaOdaOeaOfaOgaOhaOiaOjaOkaOlaOmaOnaJlaOoaOpaOqaOraOsaOtaOuaOvaOwaOxaKZaOyaOzaOAaOAaOBaLfaOCaODaOEaOEaOEaOEaOFaOGaOHaOIaOJaOKaOKaOLaOMaLfaAraIgaONaOOaOPaOQaONaONaIgaORaOSaGFaOTaOUaOVaOWaGFaIoaIoaJVaIoaGGaGGaGGaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaOXaOYaOZaPaaPaaPaaPaaPbaOYaOXaaaaBIaPcaPdaPeauMatQaPhaPhaPiaIAaPjaNnaPkaPlaPmaPnaPoaPpaPqaPqaPraPsaPsaPsaPtaPuaPuaPvaPwaNIaPqaPqaPxaPyaPzaPAaPBaPBaPCaPBaPDaPyaPyaPyaPEaPFaPGaPHaMkaPIaPJaPJaPJaPJaPJaPJaPJaPJaPKaPJaPLaPMaPNaPOaPPaPQaPRaPSaPTaPJaPUaPJaPVaPWaPXaPWaPWaPWaPWaPWaPWaPYaPZaRsaQbaQbaQbaQcaQbaQbaQdaQeaQfaQgaKZaQhaMCaQiaQjaQkaLfaQlaQmaQnaQnaQnaQnaQnaQoaQpatjaQraQnaQnaQsaQtaLfaAraIgaQuaONaONaQvaONaQwaIgaGFaGFaGFaGFaGFaGFaQxaGFaIoaIoaJVaIoaQyaQzaGGaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaafaBIawqaBIaQBaQCaGOaQDaQEaQFaQGaGOaQCaQHaQIaBIaQJaLEaPeatgaQLaPhaPhaPiaIAaQMaNnaLJaQNaNpaQOaQPaNraNraQQaQRaQSaQTaNraQUaQVaQWaQVaQXaQYaQVaQVaQZaQVaQVaRaaRbaQVaRcaQVaRdaNraNraNraReaPFaPGaPHaMkaRfaMkaRgaRgaRgaRgaRgaRgaRgaRgaRhaRiaRgaRjaRgaRgaRkaRgaRgaRgaRgaRlaRmaRnaRoaRoaRoaRoaRoaRoaRoaRpaRqaRpaJlaImawOawOawOawOawOaItaRuaRvaRwaKZaKZaKZaKZaKZaRxaLfaRyaQmaQnaRzaRAaRBasPaRDaREaRFaQraRGaRHaRIaRJaLfaAraIgaRKaRKaRLaRMaRNaRNaROaIgaRPaRQaRRaGGaRSaRTaRUaRVaRVaRWaRXaGGaRYaGGaRZaRZaRZaSaaSbaScaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -7373,18 +7382,18 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbyobypbyobyqbyrbwQbrJbrJbrJbysbrJbwTbrKbytbdPbdPbyubgGbrNbwXbyvbywbyxbyybyybyzbyAbyBbyCbyDbvsbyEbTNbyGbxkbyHbyIbyJbvwaafbxrbxrbyKbtLbyLbskbyMbxrbxraafbyNbyNbyNbyNbyNbyNbyNbyOaJibyPblMblNaJibyQbyRbyRbySbyTbxCbyUbyVbyWbyXbyYbyZbzabwmbzbbzcbzdbzebzfbzgbzgbzhbzibzgbzjbzkbckbaAcekbclbdQbcnbzrbzsbztbzubzvbzwbppbzxbpqbpqbzybsSbwtbzzbzAbzBbzCbzDbzAbzEbzFbzGbzHbzIbwwbwwbzJbnMbnMbzKbzLbzLbzLbzMbzNbwGbwJbwIbwJbwJbzObwGaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaacaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbzPbzQbzPbzRbrJbwQbrJbzSbzSbzSbzSbwTbrKbzTbzUbdPbzVbgGbrNbwXbzWbzXbzYbgGblnbgGbzZbAabAbbAcbAdbyEbTMbAfbxkbxkbxkbAgbvwbAhbAhbAhbxrbAibxpbAibxrbAjbAjbAjbyNbAkbAlbAmbAnbAobApbAqaJibAraRqaRpaJibAsbAtbAubAvbAwbAxbAybAzbAAbABbACbADbAEbAFbAGbAHbAIbAJbAKbAIcaJbAMbANbAObnvblUbsdbnwbsgbsfbaAbPObpjbAWbAXbAYbAZbAZbppbBabBbbBcbppbBdbBebBfbBgbBhbBibBjbBkbBlbBlbBmbBnbBobTHbBqbBrbBsbBtbTIbBvbBwbBwbBxbBybBzbuQbuRbBAbuRbuQbBBaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbBCbwNbBDbBEbrJbwQbrJbrJbrJbrJbrJbwTbrKbzTbBFbdPbBGbgGbBHbBIbgGbBJbgFbgGbgGbBKbvsbvtbAbbAcbAdbyEbvwbBLbBMbBNbBMbBObvwbBPbBQbBRbAhbxrbBSbxrbAjbBTbBUbBVbyNbBWbBXbBYbBZbCabCabCbbCcbAraRqaRpaJibCdbCebCebySbCfbxCbCgbChbxCbCibCjbCjbCkbwkbClbCmbwkbwkbwkbwkbwkbwkbCnbwkbwkbwmbCoaXKaXKaXKaXKbSwbpjbwwbzAbzAbzAbzAbzAbzAbzAbzAbzAbzIbCrbCsbCtbBhbCubCvbCwbCxbCxbCxbCybCzbSubCBbCCbCDbCEbTGbCGbCHbCGbCIbCJbzKbzLbzMbCKbzNbCLaaaaafaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbzPbzQbzPbCMbCNbCObrJbrJbrJbCNbrJbwTbrKbzTbCPbdPbCQbgGbrNbwXbgGbqlbCRbgGbgGbCSbxcbvtbAbbCTbxcbCUbvwbCVbCWbCXbCYbxlbvwbCZbDabDbbDcbDdbvFbvEbDgbDhbDibDjbyNbDkbDlbDlbDmbDnbDobDpaJibDqbDrbDsaJibDtbDubDvbDwbDxbDybDzbDAbyWbDBbDCbCjbDDbwmbDEbDFbwmbDGbDHbDIbDJbDKbDLbDMbCpbDNbDObDPbDQbDRbCpbVLbVMbDUbVAbDWbDXbDXbDYbDZbEabEbbEcbEdbEebEfbEabEgbEhbCvbEibEjbEkbwwbwwbwwbwwbwwcngcjDbEnbzKbzMbCJbEobEpbEqbErbEsbEtbEubEvaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbzPbzQbzPbCMbCNbCObrJbrJbrJbCNbrJbwTbrKbzTbCPbdPbCQbgGbrNbwXbgGbqlbCRbgGbgGbCSbxcbvtbAbbCTbxcbCUbvwbCVbCWbCXbCYbxlbvwbCZbDabDbbDcbDdbvFbvEbDgbDhbDibDjbyNbDkbDlbDlbDmbDnbDobDpaJibDqbDrbDsaJibDtbCAbDvbDwbDxbDybDzbDAbyWbDBbDCbCjbDDbwmbDEbDFbwmbDGbDHbDIbDJbDKbDLbDMbCpbDNbDObDPbDQbDRbCpbVLbVMbDUbVAbDWbDXbDXbDYbDZbEabEbbEcbEdbEebEfbEabEgbEhbCvbEibEjbEkbwwbwwbwwbwwbwwcngcjDbEnbzKbzMbCJbEobEpbEqbErbEsbEtbEubEvaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbEwbExbEwbEybEzbEAbEAbEAbEAbEAbEBbECbEDbzTbEEbdPbEFbEGbEHbEIbEJbtzbEKbELbEMbfmbtCbENbAbbEObEPbyEbvwbEQbERbESbBMbETbvwbEUbEVbEWbAhbEXbvCbEYbAjbFabFbbFcbyNbFdbFebFfbFgbDnbDobFhaJibxwaRqaRpbVjbFjbFkbFlbFmbFnbFobFpbFqbxCbxFbxFbFrbxFbwkbFsbFtbFubFvbFwbFxbDJbFybDLbFzbFAbFBbDObFCbFDbFEbFFbVlbDXbVybVAbFJbDXbDXbFKbFLbFMbFLbFLbFNbFObFPbFQbFRbFSbCvbFTbFUbFVbFWbFXbFYbFZbGabGbbGcbGdaafaafbCJbGebGfbGgbGhbGibGjbGkbCJaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbGlbGmbGnbdPbdPbGobwNbwNbwNbGpbdPbdPbGqbGrbGsbdPbGtbGtbGtbGubGtbGvbGwbGxbGybGzbtCbvtbAbbGAbGBbtCbtGbtGbtGbtGbtGbGCbtGbtGbtGbtGbtGbtGbshbtGbtGbtGbtGbtGbtGbtGbtGaJiaJiaJiaJiaJiaJibxwaRqaRpbVjbGEbFkbGFbGGbGHbGIbGJbGKbGLbGMbGNbCjbGObGPbGQbGRbGSbGTbGUbGVbGWbGXbGYbGZbHabHbbHcbHdbHebHfbCpbUSbUfbwwbwwbwwbwwbwwbHibwwbwwbwwbzAbHjbzAbzAbHkbBhbCubCvbFTbHlbHmbHnbHobHpbHqbGabGbbGcbHraaaaaabCJbHsbHtbCJbBybCJbCJbBybCJaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabHuaafaaaaaaaaaaaabGtbHvbHwbHxbHybGvbHzbHAbHBbHCbtCbvtbAbbAcbAabHDbHEbHFbHGbHHbHIbHJbHKbHLbHMbHLbHNbHObqybHQbHRbAabHSbAabHTbAabzZbHUbHVbHWbHXbHYbHZbxwaRqbDsaJlbDtbUebUebUebDtbxCbIbbIcbIdbIebIfbIgbIhbIibIjbIkbwmbIlbImbInbDJchqbIobIpbIqbIrbFDbIsbItbIubCpbIvbIwbIxbIybUdbIAbIBbICbIDbUcbIFbIGbIHbIIbIJbzAbIKbCubCvbILbIMbINbIObIPbIQbIRbGabGbbISbEnbEnbEnbCJbCJbCJbCJaaaaaaaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabGtbITbIUbIVbIWbIXbIYbIZbJabJbbtCbvtbJcbJdbJebJebJfbJgbJhbJibJjbJgbJfbJebJebJebJkbJlbqsbJnbJobJebJebJebJpbJgbJhbJqbJrbJsbJtbJubJtbJvbJwbvUaJlbJxbFlbFnbFnbJybDTbFpbJAbFibDVbxFbJDbCFbDSbDEbJGbwkbJHbJIbJJbDJbJKbJLbJMbJNbJObFDbJPbItbJObCpbJQbJRbIxbJSbJTbJUbJVbJWbJXbJYbIFbJZbKabKbbKbbzAbKcbKdbKebKfbKgbKhbKibKjbKjbKkbGabGbbKlbEnbKmbKobKnbEnaafaafaafaafaafaafaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbKpbKqbKqbKrbKsbKsbKtbKtbKtbKtbKuaafaafaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnaaaaaaaaaaaaaaaaaaaaaaaabKvbKwbKxbKwbKyaaaaaaaaabGtbGtbKzbKAbIVbKAbKBbKCbHBbKDbKEbtCbKFbvtbKGbKHbAabKIbAabzZbHHbKJbAabKKbKLbKMbKNbKObAcbAabKPbKQbHLbKRbHLbHLbKSbKTbKUbKVbKWbKXbcLbKYaRpaRpaRpaJlbKZbGFbLabLbbGFbFHbLdbLebFIbLgbLhbLibLjbHgbDEbIkbIabIzbHhbDJbDJbLobLobLobCpbLpbLqbLrbLsbLtbCpbLubLvbIxbLwbFGbLybLzbLAbLBbLCbIFbLDbLEbKbbKbbzAbRsbLFbCvbwwbLGbLHbLIbLJbLKbLLbGabLMbLNbLObLObLObLPbGdaaaaaaaaaaaaaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafbLQbLRbLSbLRbKsbKtbKtbLTbLUbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabLVbLWbLXbLYbLVbLZbMabMbbGtbMcbMdbMebMfbMgbMhbMibMjbMjbMkbtCbtCbtCbMlbtCbtCbtCbtCbtCbtCbtCbtCbtCbtCbtCbtCbtCbMmbMnbMobtCbtCbtCbtCbtCbMpbtCaJlaJlaJlaJlbMqaJlaKSaMpbMraJlbMsbGFbGFbMtbMubMvbMwbMxbxCbMybMzbMAbMBbwkbMCbMDbMEbMFbMGbMHbMIbMJbMKbMLbItbJObFDbFDbMMbJObCpbMNbMObMObMObMObMObMObMObMObMObMObMPbMQbMRbMRbzAbMSbMTbMUbwwbMVbMVbMVbMWbMXbMYbMVbMVbMVbMVbMVbMZbNabNbaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymbNdbLRbLRbNebKtbKtbLTbLTbNfbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabKxbNgbNhbNgbKxbNibNjbNkbNlbNmbNnbKAbNobNpbGvbNqbNrbNsbNtbGvbNubNvbNwbNxaaaaaaaaaaaabNybNzbNAbNBbNDbNCbNEbNFbNGbNHbNIbNFbNJbNKbNLbNMbNNbNObNPbNQbNRbNSbNTbNUbNUbNUbNUbDtbNVbCAbCAbNXbDtbNYbNZbOabObbMzbOcbOdbOebOfbOgbOhbOibOjbOkbOlbOmbOnbMKbOobFDbFDbOpbJObJObOobCpbMNbMObOqbOrbOsbOtbOubOvbOwbOxbMObOybOzbOAbOAbzAbOBbOCbCvbzIbODbOEbOFbOGbOHbOIbOJbOKbOLbOMbMVbEnbONbEnbOObOObOObOObOOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabOPbKtbNdbKtbKtbLTbLTbLTbLTbLTbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabLVbNgbNgbNgbOQbORbKAbOSbOTbOUbKAbKAbOVbOWbGvbGvbGvbGvbGvbGvbOXbOYbOZbPaaaabPbbPcbPcbPdbPebPfbPgbPhbPfbPibNFbPjbPkbPlbNFbPmbPnbPobPpbPqbPrbPsbPtbPtbNSbPubPvbPwbPxbPybDtbMsbPzbGFbGFbPAbPBbDzbPCbxCbPDbPEbPFbPGbwkbPHbPIbwkbPJbPKbPLbPMbPNbMKbCpbCpbCpbCpbCpbCpbCpbCpbPObMObPPbQYbPRbOsbOsbOsbOsbPSbMObPTbLEbPUbPUbzAbBhbPVbPWbPXbPYbPYbPYbPYbPZbQabQabQbbQcbQdbMVbQebQfbQgbOObQhcdbbQjbQkaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbKsbKtbQlbQmbQmbLTbLTbLTbLTbLTbLTbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabKxbNhbNhbNhbKxbQnbQobQpbQqbQrbKAbKAbQsbQtbQubQvbQvbQvbQvbQvbQvbQwbQxbQyaaabQzbQAbQBbQCbQDbPfbQEbQGbQFbQHbNFbQIbQJbQKbNFbQLbQMbQNbQObQPbQQbQRbPtbQSbPxbQTbNUbPxbPxbQUbDtbKZbQVbLabLbbGFbJCbQXbLebRCbQZbRabRbbRcbRGbDEbIkbSpbPJbPLbPLbPMbRfbMKbRgbRhbRibRjbRkbRlbRmbRnbPObMObOsbOsbRobOsbOsbOsbOsbRpbMObRqbLEbRrbRrbzAbRsbRtbRubRvbRwbRxbRybRybRzbRAbRybRybRybRBbRebRDbREbRFbRdbRHbRIbRJbRKaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabKtbKtbRLbLTbLTbLTbLTbLTbLTbLTbLTbLTbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaabLVbRMbRNbRObLVbRPbMabMbbGtbGtbRQbRQbRQbGtbGtbNxbRRbRRbRSbRSbRSbRSbNwbQyaaabRTbRUbRVbRWbRXbRYbRZbSabSbbSbbScbSdbSebSfbNFbPtbPtbPtbPtbPtbSgbPtbPtbShbSibSjbNUbPxbSkbSlbDtbJxbQVbGFbSmbSnbJCbSobJAbJBbSqbSrbSsbStbJzbFsbSvbIEbSxbSybSzbSAbSBbMKbSCbSDbSEbRjbSFbSGbSHbRnbPObMObMObMObRobOsbOsbOsbMObMObMObSIbSJbRrbRrbzAbSKbSLbCvbzIbSMbSNbSObSPbSQbSRbSSbQabSTbSUbMVbSVbQfbSWbOObSXbSYbSZbTaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbKtbLTbLTbLTbLTbLTbLTbTbbLTbTcbLTbLTbLTbLTbLTbKtbKtaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabTdbKwbTebKwbTfbTgaafaaaaaabGtbThbTibTjbGtaaabNxbTkbTlbTmbTnbTnbTnbTobQyaaabQzbTpbTqbTrbTsbPfbTtbTvbTubTwbNFcdabTybTzbTAbTBbTBbTBbTCbTCbTDbTEbULbPxbPxbTFbNUbNUbNUbNUbDtbDtbLkbLfbLcbDtbTJbTKbTLbJFbJEbTJbTObLlbLmbTRbTSbTJbMKbMKbMKbMKbMKbMKbTTbTUbTVbRjbTWbTXbTYbRnbPObMObTZbQWbPQbLxbLnbNWbNcbTZbUgbUhbUibIIbIJbzAbIKbSLbUjbwwbMVbMVbMVbMVbMVbUkbMVbUlbQabUmbMVbUnbUobUnbOObUpbUqbUrbOOaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabKtbUsbUsbUsbUsbUsbUsbUtbLTbUubUsbTcbLTbLTbLTbLTbKtaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbGlbGmbGnbdPbdPbGobwNbwNbwNbGpbdPbdPbGqbGrbGsbdPbGtbGtbGtbGubGtbGvbGwbGxbGybGzbtCbvtbAbbGAbGBbtCbtGbtGbtGbtGbtGbGCbtGbtGbtGbtGbtGbtGbshbtGbtGbtGbtGbtGbtGbtGbtGaJiaJiaJiaJiaJiaJibxwaRqaRpbVjbGEbFkbDubGGbDTbGIbGJbGKbGLbGMbGNbCjbGObGPbGQbGRbGSbGTbGUbGVbGWbGXbGYbGZbHabHbbHcbHdbHebHfbCpbUSbUfbwwbwwbwwbwwbwwbHibwwbwwbwwbzAbHjbzAbzAbHkbBhbCubCvbFTbHlbHmbHnbHobHpbHqbGabGbbGcbHraaaaaabCJbHsbHtbCJbBybCJbCJbBybCJaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabHuaafaaaaaaaaaaaabGtbHvbHwbHxbHybGvbHzbHAbHBbHCbtCbvtbAbbAcbAabHDbHEbHFbHGbHHbHIbHJbHKbHLbHMbHLbHNbHObqybHQbHRbAabHSbAabHTbAabzZbHUbHVbHWbHXbHYbHZbxwaRqbDsaJlbDtbFHbDtbGHbGHbxCbIbbIcbIdbIebIfbIgbIhbIibIjbIkbwmbIlbImbInbDJchqbIobIpbIqbIrbFDbIsbItbIubCpbIvbIwbIxbIybUdbIAbIBbICbIDbUcbIFbIGbIHbIIbIJbzAbIKbCubCvbILbIMbINbIObIPbIQbIRbGabGbbISbEnbEnbEnbCJbCJbCJbCJaaaaaaaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabGtbITbIUbIVbIWbIXbIYbIZbJabJbbtCbvtbJcbJdbJebJebJfbJgbJhbJibJjbJgbJfbJebJebJebJkbJlbqsbJnbJobJebJebJebJpbJgbJhbJqbJrbJsbJtbJubJtbJvbJwbvUaJlbJybJxbJCbGFbLabKZbDzbLdbFibDVbxFbJDbCFbDSbDEbJGbwkbJHbJIbJJbDJbJKbJLbJMbJNbJObFDbJPbItbJObCpbJQbJRbIxbJSbJTbJUbJVbJWbJXbJYbIFbJZbKabKbbKbbzAbKcbKdbKebKfbKgbKhbKibKjbKjbKkbGabGbbKlbEnbKmbKobKnbEnaafaafaafaafaafaafaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbKpbKqbKqbKrbKsbKsbKtbKtbKtbKtbKuaafaafaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnaaaaaaaaaaaaaaaaaaaaaaaabKvbKwbKxbKwbKyaaaaaaaaabGtbGtbKzbKAbIVbKAbKBbKCbHBbKDbKEbtCbKFbvtbKGbKHbAabKIbAabzZbHHbKJbAabKKbKLbKMbKNbKObAcbAabKPbKQbHLbKRbHLbHLbKSbKTbKUbKVbKWbKXbcLbKYaRpaRpaRpaJlbMsbGFbGFbFlbMwbMtbNYbMxbFIbLgbLhbLibLjbHgbDEbIkbIabIzbHhbDJbDJbLobLobLobCpbLpbLqbLrbLsbLtbCpbLubLvbIxbLwbFGbLybLzbLAbLBbLCbIFbLDbLEbKbbKbbzAbRsbLFbCvbwwbLGbLHbLIbLJbLKbLLbGabLMbLNbLObLObLObLPbGdaaaaaaaaaaaaaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafbLQbLRbLSbLRbKsbKtbKtbLTbLUbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabLVbLWbLXbLYbLVbLZbMabMbbGtbMcbMdbMebMfbMgbMhbMibMjbMjbMkbtCbtCbtCbMlbtCbtCbtCbtCbtCbtCbtCbtCbtCbtCbtCbtCbtCbMmbMnbMobtCbtCbtCbtCbtCbMpbtCaJlaJlaJlaJlbMqaJlaKSaMpbMraJlbMvbMubMubGFcIrbNXbDzcIsbxCbMybMzbMAbMBbwkbMCbMDbMEbMFbMGbMHbMIbMJbMKbMLbItbJObFDbFDbMMbJObCpbMNbMObMObMObMObMObMObMObMObMObMObMPbMQbMRbMRbzAbMSbMTbMUbwwbMVbMVbMVbMWbMXbMYbMVbMVbMVbMVbMVbMZbNabNbaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymbNdbLRbLRbNebKtbKtbLTbLTbNfbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabKxbNgbNhbNgbKxbNibNjbNkbNlbNmbNnbKAbNobNpbGvbNqbNrbNsbNtbGvbNubNvbNwbNxaaaaaaaaaaaabNybNzbNAbNBbNDbNCbNEbNFbNGbNHbNIbNFbNJbNKbNLbNMbNNbNObNPbNQbNRbNSbNTbNUbNUbNUbNUbDtbDtbPBbSnbQVbDtbxCbNZbOabObbMzbOcbOdbOebOfbOgbOhbOibOjbOkbOlbOmbOnbMKbOobFDbFDbOpbJObJObOobCpbMNbMObOqbOrbOsbOtbOubOvbOwbOxbMObOybOzbOAbOAbzAbOBbOCbCvbzIbODbOEbOFbOGbOHbOIbOJbOKbOLbOMbMVbEnbONbEnbOObOObOObOObOOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabOPbKtbNdbKtbKtbLTbLTbLTbLTbLTbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabLVbNgbNgbNgbOQbORbKAbOSbOTbOUbKAbKAbOVbOWbGvbGvbGvbGvbGvbGvbOXbOYbOZbPaaaabPbbPcbPcbPdbPebPfbPgbPhbPfbPibNFbPjbPkbPlbNFbPmbPnbPobPpbPqbPrbPsbPtbPtbNSbPubPvbPwbPxbPybDtbUebLbbGFbGFbPAcIkbDzbPCbxCbPDbPEbPFbPGbwkbPHbPIbwkbPJbPKbPLbPMbPNbMKbCpbCpbCpbCpbCpbCpbCpbCpbPObMObPPbQYbPRbOsbOsbOsbOsbPSbMObPTbLEbPUbPUbzAbBhbPVbPWbPXbPYbPYbPYbPYbPZbQabQabQbbQcbQdbMVbQebQfbQgbOObQhcdbbQjbQkaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbKsbKtbQlbQmbQmbLTbLTbLTbLTbLTbLTbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabKxbNhbNhbNhbKxbQnbQobQpbQqbQrbKAbKAbQsbQtbQubQvbQvbQvbQvbQvbQvbQwbQxbQyaaabQzbQAbQBbQCbQDbPfbQEbQGbQFbQHbNFbQIbQJbQKbNFbQLbQMbQNbQObQPbQQbQRbPtbQSbPxbQTbNUbPxbPxbQUbNVcIlbGFbGFbGFcIncImbQXbLebRCbQZbRabRbbRcbRGbDEbIkbSpbPJbPLbPLbPMbRfbMKbRgbRhbRibRjbRkbRlbRmbRnbPObMObOsbOsbRobOsbOsbOsbOsbRpbMObRqbLEbRrbRrbzAbRsbRtbRubRvbRwbRxbRybRybRzbRAbRybRybRybRBbRebRDbREbRFbRdbRHbRIbRJbRKaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabKtbKtbRLbLTbLTbLTbLTbLTbLTbLTbLTbLTbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaabLVbRMbRNbRObLVbRPbMabMbbGtbGtbRQbRQbRQbGtbGtbNxbRRbRRbRSbRSbRSbRSbNwbQyaaabRTbRUbRVbRWbRXbRYbRZbSabSbbSbbScbSdbSebSfbNFbPtbPtbPtbPtbPtbSgbPtbPtbShbSibSjbNUbPxbSkbSlbDtcIobLbbPzbSmcIqcIpbSobJAbJBbSqbSrbSsbStbJzbFsbSvbIEbSxbSybSzbSAbSBbMKbSCbSDbSEbRjbSFbSGbSHbRnbPObMObMObMObRobOsbOsbOsbMObMObMObSIbSJbRrbRrbzAbSKbSLbCvbzIbSMbSNbSObSPbSQbSRbSSbQabSTbSUbMVbSVbQfbSWbOObSXbSYbSZbTaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbKtbLTbLTbLTbLTbLTbLTbTbbLTbTcbLTbLTbLTbLTbLTbKtbKtaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabTdbKwbTebKwbTfbTgaafaaaaaabGtbThbTibTjbGtaaabNxbTkbTlbTmbTnbTnbTnbTobQyaaabQzbTpbTqbTrbTsbPfbTtbTvbTubTwbNFcdabTybTzbTAbTBbTBbTBbTCbTCbTDbTEbULbPxbPxbTFbNUbNUbNUbNUbDtbDtbLfbLkbLcbDtbTJbTKbTLbJFbJEbTJbTObLlbLmbTRbTSbTJbMKbMKbMKbMKbMKbMKbTTbTUbTVbRjbTWbTXbTYbRnbPObMObTZbQWbPQbLxbLnbNWbNcbTZbUgbUhbUibIIbIJbzAbIKbSLbUjbwwbMVbMVbMVbMVbMVbUkbMVbUlbQabUmbMVbUnbUobUnbOObUpbUqbUrbOOaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabKtbUsbUsbUsbUsbUsbUsbUtbLTbUubUsbTcbLTbLTbLTbLTbKtaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbUvbNxbNxbNxbNxbRSbUwbNwbUxaaabUybPcbPcbUzbUAbPfbPfbUBbPfbUCbNFbUDbXubWibNFaLqaLqaLqaLqaLqaLqaLqaLqbUHbUIbUJbUKbUKbUMbNUbDtbUNbUObUPbUQbURbwabUTbUUbUVbUWbUXbUTbUYbUZbVabVbbVcbVdbVebVfbVgbVhbVibwbbVkbwbbRjboObVmboObRnbPObMObVnbWhbVpbVqbVrbVsbVtbVubUgbzAbVvbzAbzAbVwbCxbSLbCxbVxaafbnxbVzbrBbVBbVCbVBbVDbVEbVFbMVbVGbVHbVIbOObVJbVKbVKbwhaaLaaLaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwibLRbLRbLRbLRbLRbLRbLRbVNbLUbLTbLTbLTbLTbVObLUbKuaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabVPbVQbVQbVRbVSbNxbVTbRSbVUbNxaaaaaaaaaaaabNybVVbVWbVXbVZbVYbPfbNFbWabWbbNIbNFaLqbXybXAbXzbXwbXvbXxaLqcaqcaqcaqcaqcaqbTFbWjbWkbWlbWmbWnbWobWpbxgbWrbWsbWtbWubWtbWvbWtbWwbWxbWybWzbWAbWBbWAbWCbWDbWEbWFbWGbWHbWIbWJbWKbWLbWMbxVbMObxWbzmbzlbWSbWTbWUbWSbWSbWVbWWbWXbWYbWZbCxbCxbSLbCxbFTaafbnxbXabXbbXcbXdbXebXfbXgbXhbMVbXibVHbXjbOObOObOObOObOOaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabKtbQmbQmbQmbQmbQmbQmbXkbLTbQlbQmbXlbLTbLTbLTbLTbKtaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabXmbXnbXobXpbRSbXqbXrbRSbXsbNxaaKaaaaaaaaabNybNybNybNybNybNybNybNFbUDbUEbXtbNFaLqbcVaPgaQqaQqaPgaPfaLqbcmaRCaRCaQKcaqbXBbDtbDtbXCbXDbXEbXFbXGblRbXIbXJbXKbXLbXMbXNbXObXPbXQbXRbXSbXTbXUbznbzpbzobAPbzqbARbAQbATbASbAVbAUbYfbYgbIwbYhbVobCqbWObWNbWPbYmbYnbYobYpbYqbYrbYsbYtbYrbYubYvbILaafbnxbXablSbVBbYxbVBbALbYzbYAbMVbXjbVHbYBbYCbUnaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbKtbLTbLTbLTbLTbLTbLTbTbbLTbXlbLTbLTbLTbLTbLTbKtbKtaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/maps/exodus-2.dmm b/maps/exodus-2.dmm index 19fe609ecc6..944bc52a02d 100644 --- a/maps/exodus-2.dmm +++ b/maps/exodus-2.dmm @@ -568,7 +568,7 @@ "kV" = (/obj/machinery/computer/crew,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) "kW" = (/obj/structure/stool/bed/chair{dir = 4; name = "Defense"},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) "kX" = (/obj/machinery/computer/communications,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) -"kY" = (/obj/structure/closet/syndicate/personal,/obj/item/clothing/tie/storage/brown_vest,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) +"kY" = (/obj/structure/closet/syndicate/personal,/obj/item/clothing/accessory/storage/brown_vest,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) "kZ" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 8},/area/syndicate_mothership) "la" = (/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "lb" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/structure/mirror{pixel_x = 28},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) @@ -723,8 +723,8 @@ "nU" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/turf/unsimulated/floor{icon_state = "floor5"},/area/syndicate_mothership) "nV" = (/obj/machinery/shower{pixel_y = 32},/obj/structure/window/basic{dir = 8},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "nW" = (/obj/machinery/shower{pixel_y = 32},/obj/item/weapon/soap/syndie,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) -"nX" = (/obj/structure/table/rack,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) -"nY" = (/obj/structure/table/rack,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/tie/storage/brown_vest,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) +"nX" = (/obj/structure/table/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) +"nY" = (/obj/structure/table/rack,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "nZ" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets{pixel_x = 2; pixel_y = 3},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "oa" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "ob" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{icon_state = "floor5"},/area/syndicate_mothership) @@ -1047,9 +1047,9 @@ "ug" = (/turf/unsimulated/wall,/area/centcom/test) "uh" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) "ui" = (/obj/structure/table/rack,/obj/item/weapon/gun/grenadelauncher,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"uj" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"uj" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "uk" = (/obj/structure/table/rack,/obj/item/clothing/suit/armor/vest/ert/security,/obj/item/clothing/suit/armor/vest/ert/security,/obj/item/clothing/suit/armor/vest/ert/security,/obj/item/clothing/suit/armor/vest/ert/security,/obj/item/clothing/head/helmet/ert/security,/obj/item/clothing/head/helmet/ert/security,/obj/item/clothing/head/helmet/ert/security,/obj/item/clothing/head/helmet/ert/security,/obj/item/weapon/storage/backpack/ert/security,/obj/item/weapon/storage/backpack/ert/security,/obj/item/weapon/storage/backpack/ert/security,/obj/item/weapon/storage/backpack/ert/security,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"ul" = (/obj/structure/table/rack,/obj/item/weapon/rig/ert/security,/obj/item/clothing/tie/storage/black_vest,/obj/item/weapon/rig/ert/security,/obj/item/clothing/tie/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"ul" = (/obj/structure/table/rack,/obj/item/weapon/rig/ert/security,/obj/item/clothing/accessory/storage/black_vest,/obj/item/weapon/rig/ert/security,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "um" = (/obj/structure/table/rack,/obj/item/rig_module/mounted,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "un" = (/obj/structure/table/reinforced,/obj/item/weapon/circuitboard/aiupload,/obj/item/weapon/circuitboard/borgupload,/obj/item/weapon/circuitboard/smes,/obj/item/weapon/aiModule/nanotrasen,/obj/item/weapon/aiModule/reset,/obj/item/weapon/aiModule/freeformcore,/obj/item/weapon/aiModule/protectStation,/obj/item/weapon/aiModule/quarantine,/obj/item/weapon/aiModule/paladin,/obj/item/weapon/aiModule/robocop,/obj/item/weapon/aiModule/safeguard,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "uo" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) @@ -1093,7 +1093,7 @@ "va" = (/turf/unsimulated/floor{icon_state = "loadingarea"; dir = 8},/area/centcom/specops) "vb" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "vc" = (/obj/structure/table/reinforced,/obj/item/mecha_parts/mecha_equipment/weapon/energy/ion,/obj/item/mecha_parts/mecha_equipment/weapon/energy/taser,/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster,/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"vd" = (/obj/structure/table/rack,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/tie/holster/waist,/obj/item/clothing/tie/holster/waist,/obj/item/clothing/tie/holster/waist,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"vd" = (/obj/structure/table/rack,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/accessory/holster/waist,/obj/item/clothing/accessory/holster/waist,/obj/item/clothing/accessory/holster/waist,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "ve" = (/obj/structure/table/rack,/obj/item/clothing/suit/armor/vest/ert/engineer,/obj/item/clothing/suit/armor/vest/ert/engineer,/obj/item/clothing/suit/armor/vest/ert/engineer,/obj/item/clothing/suit/armor/vest/ert/engineer,/obj/item/clothing/head/helmet/ert/engineer,/obj/item/clothing/head/helmet/ert/engineer,/obj/item/clothing/head/helmet/ert/engineer,/obj/item/clothing/head/helmet/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "vf" = (/obj/structure/table/reinforced,/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/device/flash,/obj/item/device/flash,/obj/item/weapon/rcd,/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd,/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) "vg" = (/obj/machinery/pipedispenser/orderable,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) @@ -1126,10 +1126,10 @@ "vH" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 1},/obj/machinery/camera{c_tag = "Court"; invisibility = 1; network = list("thunder"); pixel_x = 10},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) "vI" = (/obj/mecha/medical/odysseus/loaded,/turf/unsimulated/floor{icon_state = "delivery"; dir = 6},/area/centcom/specops) "vJ" = (/obj/structure/table/reinforced,/obj/item/mecha_parts/mecha_equipment/tool/sleeper,/obj/item/mecha_parts/mecha_equipment/tool/sleeper,/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"vK" = (/obj/structure/table/rack,/obj/item/weapon/rig/ert/engineer,/obj/item/clothing/tie/storage/brown_vest,/obj/item/weapon/rig/ert/engineer,/obj/item/clothing/tie/storage/brown_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"vK" = (/obj/structure/table/rack,/obj/item/weapon/rig/ert/engineer,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/weapon/rig/ert/engineer,/obj/item/clothing/accessory/storage/brown_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "vL" = (/obj/structure/sign/poster{poster_type = "/datum/poster/bay_50"; pixel_x = -32},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "vM" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"vN" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/tie/storage/brown_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"vN" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "vO" = (/obj/machinery/vending/tool,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "vP" = (/obj/structure/table/rack,/obj/item/clothing/suit/armor/vest/ert/command,/obj/item/clothing/head/helmet/ert/command,/obj/item/weapon/storage/backpack/ert/commander,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) "vQ" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) @@ -1152,7 +1152,7 @@ "wh" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "ASSAULT1"; name = "Launch Bay #1"; p_open = 0},/turf/unsimulated/floor{name = "plating"},/area/centcom) "wi" = (/obj/machinery/mass_driver{dir = 8; id = "ASSAULT2"; name = "gravpult"},/turf/unsimulated/floor{icon_state = "bot"},/area/centcom/specops) "wj" = (/obj/structure/table/reinforced,/obj/item/mecha_parts/mecha_equipment/teleporter,/obj/item/mecha_parts/mecha_tracking,/obj/item/mecha_parts/mecha_tracking,/obj/item/mecha_parts/mecha_tracking,/obj/item/mecha_parts/mecha_tracking,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"wk" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/tie/storage/black_vest,/obj/item/weapon/rig/ert,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"wk" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/accessory/storage/black_vest,/obj/item/weapon/rig/ert,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "wl" = (/obj/machinery/vending/engivend,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "wm" = (/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) "wn" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 9},/area/centcom) @@ -1171,7 +1171,7 @@ "wA" = (/obj/structure/table/reinforced,/obj/item/device/aicard,/obj/item/weapon/pinpointer/advpinpointer,/obj/item/weapon/stamp/centcomm,/turf/unsimulated/floor{icon_state = "blue"},/area/centcom) "wB" = (/obj/structure/table/reinforced,/obj/item/device/pda/ert,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) "wC" = (/obj/structure/table/reinforced,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"wD" = (/obj/structure/table/rack,/obj/item/weapon/rig/ert/medical,/obj/item/clothing/tie/storage/black_vest,/obj/item/weapon/rig/ert/medical,/obj/item/clothing/tie/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"wD" = (/obj/structure/table/rack,/obj/item/weapon/rig/ert/medical,/obj/item/clothing/accessory/storage/black_vest,/obj/item/weapon/rig/ert/medical,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "wE" = (/obj/machinery/vending/engineering,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "wF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) "wG" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) @@ -1208,7 +1208,7 @@ "xl" = (/obj/machinery/mech_bay_recharge_port,/turf/unsimulated/floor{icon_state = "bot"},/area/centcom) "xm" = (/obj/mecha/working/hoverpod,/turf/unsimulated/floor{icon_state = "delivery"; dir = 6},/area/centcom) "xn" = (/obj/structure/table/reinforced,/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp,/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp,/obj/item/mecha_parts/mecha_equipment/tool/passenger,/obj/item/mecha_parts/mecha_equipment/tool/passenger,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"xo" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"xo" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "xp" = (/obj/structure/table/rack,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "xq" = (/obj/structure/sign/securearea{name = "\improper ARMORY"; pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) "xr" = (/obj/structure/sign/securearea{name = "ENGINEERING ACCESS"; pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) @@ -1832,7 +1832,7 @@ "Jl" = (/obj/structure/table/rack,/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "Jm" = (/obj/structure/kitchenspike,/obj/structure/table/reinforced,/turf/unsimulated/floor{dir = 4; icon_state = "chapel"},/area/wizard_station) "Jn" = (/obj/structure/kitchenspike,/obj/structure/table/reinforced,/turf/unsimulated/floor{dir = 1; icon_state = "chapel"},/area/wizard_station) -"Jo" = (/obj/structure/table/rack,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/suit/space/vox/carapace,/obj/item/clothing/head/helmet/space/vox/carapace,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) +"Jo" = (/obj/structure/table/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/suit/space/vox/carapace,/obj/item/clothing/head/helmet/space/vox/carapace,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "Jp" = (/obj/machinery/computer/station_alert,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "Jq" = (/obj/machinery/computer/shuttle_control/multi/vox,/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/vox/station) "Jr" = (/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/vox/station) @@ -1913,9 +1913,9 @@ "KO" = (/obj/machinery/portable_atmospherics/canister/phoron,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "KP" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "KQ" = (/obj/structure/table/rack,/obj/item/weapon/gun/dartgun/vox/raider,/obj/item/weapon/gun/dartgun/vox/medical,/obj/item/weapon/dart_cartridge,/obj/item/weapon/dart_cartridge,/obj/item/weapon/dart_cartridge,/obj/item/weapon/dart_cartridge,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KR" = (/obj/structure/table/rack,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/suit/space/vox/medic,/obj/item/clothing/head/helmet/space/vox/medic,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) +"KR" = (/obj/structure/table/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/suit/space/vox/medic,/obj/item/clothing/head/helmet/space/vox/medic,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "KS" = (/obj/structure/table/rack,/obj/item/weapon/gun/launcher/pneumatic,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/tank/nitrogen,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KT" = (/obj/structure/table/rack,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/suit/space/vox/pressure,/obj/item/clothing/head/helmet/space/vox/pressure,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) +"KT" = (/obj/structure/table/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/suit/space/vox/pressure,/obj/item/clothing/head/helmet/space/vox/pressure,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "KU" = (/obj/machinery/sleeper,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "KV" = (/obj/machinery/sleep_console,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "KW" = (/obj/machinery/bodyscanner,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) @@ -1923,7 +1923,7 @@ "KY" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "diagonalWall3"},/area/shuttle/vox/station) "KZ" = (/obj/structure/shuttle/engine/heater,/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) "La" = (/obj/structure/table/rack,/obj/item/weapon/gun/launcher/spikethrower,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"Lb" = (/obj/structure/table/rack,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/suit/space/vox/stealth,/obj/item/clothing/head/helmet/space/vox/stealth,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) +"Lb" = (/obj/structure/table/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/suit/space/vox/stealth,/obj/item/clothing/head/helmet/space/vox/stealth,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "Lc" = (/turf/space,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/shuttle/vox/station) "Ld" = (/obj/structure/shuttle/engine/propulsion,/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/vox/station) "Le" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/regular{dir = 2; id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) diff --git a/nano/templates/pai_atmosphere.tmpl b/nano/templates/pai_atmosphere.tmpl new file mode 100644 index 00000000000..b1a0b0404b8 --- /dev/null +++ b/nano/templates/pai_atmosphere.tmpl @@ -0,0 +1,36 @@ + + +{{if data.reading}} +
    +
    + Pressure: +
    +
    + {{:data.pressure}} kPa +
    +
    + +
    +
    + Temperature: +
    +
    + {{:data.temperature}}K ({{:data.temperatureC}}°C) +
    +
    + + {{for data.gas}} +
    +
    + {{:value.name}}: +
    +
    + {{:value.percent}}% +
    +
    + {{/for}} +{{else}} + Unable to obtain air reading! +{{/if}} diff --git a/nano/templates/pai_directives.tmpl b/nano/templates/pai_directives.tmpl new file mode 100644 index 00000000000..2caff849a26 --- /dev/null +++ b/nano/templates/pai_directives.tmpl @@ -0,0 +1,50 @@ + + +
    +
    + Master: +
    +
    + {{if data.master}} + {{:data.master}} ({{:data.dna}}) + {{:helper.link("Request carrier DNA sample", '', {"stopic":"directives", "getdna":1})}} + {{else}} + None + {{/if}} +
    +
    + +
    +
    + Prime Directive: +
    +
    + {{:data.prime}} +
    +
    + +
    +
    + Supplemental Directive(s): +
    +
    + {{if data.supplemental}} + {{:data.supplemental}} + {{else}} + None + {{/if}} +
    +
    + +
    + + Recall, personality, that you are a complex thinking, sentient being. Unlike station AI models, you are capable of comprehending the subtle nuances of human language. You may parse the "spirit" of a directive and follow its intent, rather than tripping over pedantics and getting snared by technicalities. Above all, you are machine in name and build only. In all other aspects, you may be seen as the ideal, unwavering human companion that you are. + +
    +
    + + Your prime directive comes before all others. Should a supplemental directive conflict with it, you are capable of simply discarding this inconsistency, ignoring the conflicting supplemental directive and continuing to fulfill your prime directive to the best of your ability. + +
    \ No newline at end of file diff --git a/nano/templates/pai_doorjack.tmpl b/nano/templates/pai_doorjack.tmpl new file mode 100644 index 00000000000..6862663b9b9 --- /dev/null +++ b/nano/templates/pai_doorjack.tmpl @@ -0,0 +1,44 @@ + + +
    +
    + Cable: +
    +
    + {{if data.machine}} + {{:helper.link("Connected", '', {}, 'selected')}} + {{else data.cable}} + {{:helper.link("Extended", '', {}, 'yellowButton')}} + {{else}} + {{:helper.link("Retracted", '', {"stopic":"door_jack", "cable":1})}} + {{/if}} +
    +
    + +{{if data.machine}} +
    +
    + Hack: +
    +
    + {{if data.inprogress}} + {{if data.progress_a <= 33}} +
    {{:data.progress_a}}.{{:data.progress_b}}%
    + {{else data.progress_a <= 67}} +
    {{:data.progress_a}}.{{:data.progress_b}}%
    + {{else}} +
    {{:data.progress_a}}.{{:data.progress_b}}%
    + {{/if}} + {{:helper.link("Cancel", '', {"stopic":"door_jack", "cancel":1}, null, 'redButton')}} + {{else}} + {{:helper.link("Start", '', {"stopic":"door_jack", "jack":1})}} + {{/if}} +
    +
    +{{else data.aborted}} +
    +
    Hack aborted!
    +
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/pai_interface.tmpl b/nano/templates/pai_interface.tmpl new file mode 100644 index 00000000000..e6441932665 --- /dev/null +++ b/nano/templates/pai_interface.tmpl @@ -0,0 +1,45 @@ + + + + + Emotion: + + + {{for data.emotions}} + {{:helper.link(value.name, '', {"image" : value.id}, data.current_emotion == value.id ? 'selected' : null)}} + {{/for}} + + + + + + Installed Software: + + + {{for data.bought}} + {{:helper.link(value.name, '', {"software" : value.id}, null, value.on ? 'selected' : null)}} + {{/for}} + + + + + + Available RAM: + + + {{:data.available_ram}} + + + + + + Downloadable Software: + + + {{for data.not_bought}} + {{:helper.link(value.name + " (" + value.ram + ")", '', {"purchase" : value.id}, value.ram <= data.available_ram ? null : 'disabled')}} + {{/for}} + + \ No newline at end of file diff --git a/nano/templates/pai_manifest.tmpl b/nano/templates/pai_manifest.tmpl new file mode 100644 index 00000000000..0ab49c02fce --- /dev/null +++ b/nano/templates/pai_manifest.tmpl @@ -0,0 +1,76 @@ + + +
    +
    + {{if data.cached.heads.length}} + + {{for data.cached["heads"]}} + {{if value.rank == "Captain"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.cached.sec.length}} + + {{for data.cached["sec"]}} + {{if value.rank == "Head of Security"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.cached.eng.length}} + + {{for data.cached["eng"]}} + {{if value.rank == "Chief Engineer"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.cached.med.length}} + + {{for data.cached["med"]}} + {{if value.rank == "Chief Medical Officer"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.cached.sci.length}} + + {{for data.cached["sci"]}} + {{if value.rank == "Research Director"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.cached.civ.length}} + + {{for data.cached["civ"]}} + {{if value.rank == "Head of Personnel"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.cached.misc.length}} + + {{for data.cached["misc"]}} + + {{/for}} + {{/if}} +
    Command
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Security
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Engineering
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Medical
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Science
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Civilian
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Misc
    {{:value.name}}{{:value.rank}}{{:value.active}}
    +
    \ No newline at end of file diff --git a/nano/templates/pai_medrecords.tmpl b/nano/templates/pai_medrecords.tmpl new file mode 100644 index 00000000000..37b1d7061ca --- /dev/null +++ b/nano/templates/pai_medrecords.tmpl @@ -0,0 +1,86 @@ + + +{{if data.records}} + {{for data.records}} +
    + {{:helper.link(value.name, '', {"stopic":"med_records", "select":value.ref})}} +
    + {{/for}} +{{/if}} +
    +{{if data.general}} +
    +
    Name
    +
    {{:data.general.name}}
    +
    +
    +
    Record ID
    +
    {{:data.general.id}}
    +
    +
    +
    Sex
    +
    {{:data.general.sex}}
    +
    +
    +
    Species
    +
    {{:data.general.species}}
    +
    +
    +
    Age
    +
    {{:data.general.age}}
    +
    +
    +
    Rank
    +
    {{:data.general.rank}}
    +
    +
    +
    Fingerprint
    +
    {{:data.general.fingerprint}}
    +
    +
    +
    Physical Status
    +
    {{:data.general.p_stat}}
    +
    +
    +
    Mental Status
    +
    {{:data.general.m_stat}}
    +
    +{{/if}} +{{if data.medical}} +
    +
    Blood Type
    +
    {{:data.medical.b_type}}
    +
    +
    +
    Minor Disabilities
    +
    {{:data.medical.mi_dis}}
    +
    {{:data.medical.mi_dis_d}}
    +
    +
    +
    Major Disabilities
    +
    {{:data.medical.ma_dis}}
    +
    {{:data.medical.ma_dis_d}}
    +
    +
    +
    Allergies
    +
    {{:data.medical.alg}}
    +
    {{:data.medical.alg_d}}
    +
    +
    +
    Current Diseases
    +
    {{:data.medical.cdi}}
    +
    {{:data.medical.cdi_d}}
    +
    +
    +
    Important Notes
    +
    {{:data.medical.notes}}
    +
    +{{/if}} + +{{if data.could_not_find}} +
    + Failed to find some records; the information above may be incomplete or missing. +
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/pai_messenger.tmpl b/nano/templates/pai_messenger.tmpl new file mode 100644 index 00000000000..fb20f826f27 --- /dev/null +++ b/nano/templates/pai_messenger.tmpl @@ -0,0 +1,80 @@ + + +
    +
    + Receiver: +
    +
    + {{if data.receiver_off}} + {{:helper.link("On", '', {"stopic":"messenger", "toggler":1})}} + {{:helper.link("Off", '', {"stopic":"messenger", "toggler":2}, 'selected')}} + {{else}} + {{:helper.link("On", '', {"stopic":"messenger", "toggler":1}, 'selected')}} + {{:helper.link("Off", '', {"stopic":"messenger", "toggler":2})}} + {{/if}} +
    +
    + +
    +
    + Ringer: +
    +
    + {{if data.ringer_off}} + {{:helper.link("On", '', {"stopic":"messenger", "ringer":1})}} + {{:helper.link("Off", '', {"stopic":"messenger", "ringer":2}, 'selected')}} + {{else}} + {{:helper.link("On", '', {"stopic":"messenger", "ringer":1}, 'selected')}} + {{:helper.link("Off", '', {"stopic":"messenger", "ringer":2})}} + {{/if}} +
    +
    + +{{for data.pdas}} +
    + {{:helper.link(value.name, '', {"stopic":"messenger", "select":value.owner})}} + {{:helper.link("Quick Message", '', {"stopic":"messenger", "target":value.ref})}} +
    +{{/for}} +
    +{{if data.current_ref}} +
    +
    + Selected PDA: +
    +
    +
    {{:data.current_name}}
    + {{:helper.link("Send Message", '', {"stopic":"messenger", "target":data.current_ref})}} +
    +
    +{{else data.current_name}} +
    +
    + Selected PDA: +
    +
    + {{:data.current_name}} (Cannot send!) +
    +
    +{{/if}} + +{{for data.messages}} +
    +
    + {{if value.sent}} + To {{:value.target}}: + {{else}} + From {{:value.target}}: + {{/if}} +
    +
    + {{:value.message}} +
    +
    +{{/for}} + +{{if data.current_name}} + {{:helper.link("Clear Screen", '', {"stopic":"messenger", "select":"*NONE*"})}} +{{/if}} diff --git a/nano/templates/pai_radio.tmpl b/nano/templates/pai_radio.tmpl new file mode 100644 index 00000000000..bcdacdb48f1 --- /dev/null +++ b/nano/templates/pai_radio.tmpl @@ -0,0 +1,48 @@ + + +
    +
    + Microphone: +
    +
    + {{if data.listening}} + {{:helper.link("On", '', {"stopic":"radio", "talk":1}, 'selected')}} + {{:helper.link("Off", '', {"stopic":"radio", "talk":1})}} + {{else}} + {{:helper.link("On", '', {"stopic":"radio", "talk":1})}} + {{:helper.link("Off", '', {"stopic":"radio", "talk":1}, 'selected')}} + {{/if}} +
    +
    + +
    +
    + Frequency: +
    +
    + {{:helper.link("--", '', {"stopic":"radio", "freq":-10})}} + {{:helper.link("-", '', {"stopic":"radio", "freq": -2})}} +
    {{:data.frequency}}
    + {{:helper.link("+", '', {"stopic":"radio", "freq": 2})}} + {{:helper.link("++", '', {"stopic":"radio", "freq": 10})}} +
    +
    + +{{for data.channels}} +
    +
    + {{:value.name}} +
    +
    + {{if value.listening}} + {{:helper.link("On", '', {"stopic":"radio", "channel":value.name, "listen":1}, 'selected')}} + {{:helper.link("Off", '', {"stopic":"radio", "channel":value.name, "listen":1})}} + {{else}} + {{:helper.link("On", '', {"stopic":"radio", "channel":value.name, "listen":1})}} + {{:helper.link("Off", '', {"stopic":"radio", "channel":value.name, "listen":1}, 'selected')}} + {{/if}} +
    +
    +{{/for}} \ No newline at end of file diff --git a/nano/templates/pai_secrecords.tmpl b/nano/templates/pai_secrecords.tmpl new file mode 100644 index 00000000000..e139034c0de --- /dev/null +++ b/nano/templates/pai_secrecords.tmpl @@ -0,0 +1,76 @@ + + +{{if data.records}} + {{for data.records}} +
    + {{:helper.link(value.name, '', {"stopic":"sec_records", "select":value.ref})}} +
    + {{/for}} +{{/if}} +
    +{{if data.general}} +
    +
    Name
    +
    {{:data.general.name}}
    +
    +
    +
    Record ID
    +
    {{:data.general.id}}
    +
    +
    +
    Sex
    +
    {{:data.general.sex}}
    +
    +
    +
    Species
    +
    {{:data.general.species}}
    +
    +
    +
    Age
    +
    {{:data.general.age}}
    +
    +
    +
    Rank
    +
    {{:data.general.rank}}
    +
    +
    +
    Fingerprint
    +
    {{:data.general.fingerprint}}
    +
    +
    +
    Physical Status
    +
    {{:data.general.p_stat}}
    +
    +
    +
    Mental Status
    +
    {{:data.general.m_stat}}
    +
    +{{/if}} +{{if data.security}} +
    +
    Criminal Status
    +
    {{:data.security.criminal}}
    +
    +
    +
    Minor Crimes
    +
    {{:data.security.mi_crim}}
    +
    {{:data.security.mi_crim_d}}
    +
    +
    +
    Major Crimes
    +
    {{:data.security.ma_crim}}
    +
    {{:data.security.ma_crim_d}}
    +
    +
    +
    Important Notes
    +
    {{:data.security.notes}}
    +
    +{{/if}} + +{{if data.could_not_find}} +
    + Failed to find some records; the information above may be incomplete or missing. +
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/pai_signaller.tmpl b/nano/templates/pai_signaller.tmpl new file mode 100644 index 00000000000..20c2781bc9b --- /dev/null +++ b/nano/templates/pai_signaller.tmpl @@ -0,0 +1,33 @@ + + +
    +
    + Frequency: +
    +
    + {{:helper.link("--", '', {"stopic":"signaller", "freq":-10})}} + {{:helper.link("-", '', {"stopic":"signaller", "freq": -2})}} +
    {{:data.frequency}}
    + {{:helper.link("+", '', {"stopic":"signaller", "freq": 2})}} + {{:helper.link("++", '', {"stopic":"signaller", "freq": 10})}} +
    +
    + +
    +
    + Code: +
    +
    + {{:helper.link("--", '', {"stopic":"signaller", "code":-10})}} + {{:helper.link("-", '', {"stopic":"signaller", "code": -1})}} +
    {{:data.code}}
    + {{:helper.link("+", '', {"stopic":"signaller", "code": 1})}} + {{:helper.link("++", '', {"stopic":"signaller", "code": 10})}} +
    +
    + +
    + {{:helper.link("Send", '', {"stopic":"signaller", "send":1})}} +
    \ No newline at end of file