diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 6dac55213d7..a692639d802 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -313,7 +313,8 @@ proc/isInSight(var/atom/A, var/atom/B) return M return null -/proc/get_candidates(be_special_flag=0, afk_bracket=3000, jobban=0, department_jobban=0, override_age=0) +/proc/get_candidates(be_special_flag=0, afk_bracket=3000, override_age=0, override_jobban=0) + var/roletext = get_roletext(be_special_flag) var/list/candidates = list() // Keep looping until we find a non-afk candidate within the time bracket (we limit the bracket to 10 minutes (6000)) while(!candidates.len && afk_bracket < 6000) @@ -321,7 +322,7 @@ proc/isInSight(var/atom/A, var/atom/B) if(G.client != null) if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD)) if(!G.client.is_afk(afk_bracket) && (G.client.prefs.be_special & be_special_flag)) - if(!jobban && !department_jobban || !jobban_isbanned(G, jobban) && !jobban_isbanned(G,department_jobban)) + if(!override_jobban || (!jobban_isbanned(G, roletext) && !jobban_isbanned(G,"Syndicate"))) if(override_age || player_old_enough_antag(G.client,be_special_flag)) candidates += G.client afk_bracket += 600 // Add a minute to the bracket, for every attempt diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 1553550e362..cb2fad75ddb 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -82,7 +82,7 @@ // Used to get a sanitized input. /proc/stripped_input(var/mob/user, var/message = "", var/title = "", var/default = "", var/max_length=MAX_MESSAGE_LEN) var/name = input(user, message, title, default) - return strip_html_simple(name, max_length) + return strip_html_properly(name, max_length) //Filters out undesirable characters from names /proc/reject_bad_name(var/t_in, var/allow_numbers=0, var/max_length=MAX_NAME_LEN) @@ -311,4 +311,34 @@ proc/checkhtml(var/t) var/new_text = "" for(var/i = length(text); i > 0; i--) new_text += copytext(text, i, i+1) - return new_text + return new_text + +//This proc strips html properly, but it's not lazy like the other procs. +//This means that it doesn't just remove < and > and call it a day. +//Also limit the size of the input, if specified. +/proc/strip_html_properly(var/input, var/max_length = MAX_MESSAGE_LEN) + if(!input) + return + var/opentag = 1 //These store the position of < and > respectively. + var/closetag = 1 + while(1) + opentag = findtext(input, "<") + closetag = findtext(input, ">") + if(closetag && opentag) + if(closetag < opentag) + input = copytext(input, (closetag + 1)) + else + input = copytext(input, 1, opentag) + copytext(input, (closetag + 1)) + else if(closetag || opentag) + if(opentag) + input = copytext(input, 1, opentag) + else + input = copytext(input, (closetag + 1)) + else + break + if(max_length) + input = copytext(input,1,max_length) + return sanitize(input) + +/proc/trim_strip_html_properly(var/input, var/max_length = MAX_MESSAGE_LEN) + return trim(strip_html_properly(input, max_length)) diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index c26d2e8d7b8..634697b8e44 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -227,7 +227,7 @@ proc/tg_text2list(text, glue=",", assocglue=";") . += copytext(text, last_found, found) last_found = found + delim_len while(found) - + /proc/text2numlist(text, delimiter="\n") var/list/num_list = list() for(var/x in text2list(text, delimiter)) @@ -347,6 +347,7 @@ proc/tg_text2list(text, glue=",", assocglue=";") if(rights & R_SOUNDS) . += "[seperator]+SOUND" if(rights & R_SPAWN) . += "[seperator]+SPAWN" if(rights & R_MOD) . += "[seperator]+MODERATOR" + if(rights & R_MENTOR) . += "[seperator]+MENTOR" return . /proc/ui_style2icon(ui_style) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index ac841e220df..fec0900cf1b 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -411,13 +411,7 @@ Turf and target are seperate in case you want to teleport some distance from a t //world << "[newname] is the AI!" //world << sound('sound/AI/newAI.ogg') // Set eyeobj name - if(A.eyeobj) - A.eyeobj.name = "[newname] (AI Eye)" - - // Set ai pda name - if(A.aiPDA) - A.aiPDA.owner = newname - A.aiPDA.name = newname + " (" + A.aiPDA.ownjob + ")" + A.SetName(newname) fully_replace_character_name(oldname,newname) diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 52b16ad6dcf..1e07b13142a 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -503,8 +503,7 @@ if("Crew Monitoring") if(isAI(usr)) var/mob/living/silicon/ai/AI = usr - var/obj/machinery/computer/crew/C = locate(/obj/machinery/computer/crew) - C.attack_ai(AI) + AI.nano_crew_monitor() if("Show Crew Manifest") if(isAI(usr)) diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 1fd31a5bd18..d8b5617d2a1 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -66,7 +66,7 @@ /obj/machinery/teleport/hub/attack_ghost(mob/user as mob) var/atom/l = loc var/obj/machinery/computer/teleporter/com = locate(/obj/machinery/computer/teleporter, locate(l.x - 2, l.y, l.z)) - if(com.locked) + if(com && com.locked) user.loc = get_turf(com.locked) /obj/effect/portal/attack_ghost(mob/user as mob) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 5806da2e51a..160137a2e5b 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -135,6 +135,11 @@ var/default_laws = 0 //Controls what laws the AI spawns with. + var/list/station_levels = list(1) // Defines which Z-levels the station exists on. + var/list/admin_levels= list(2) // Defines which Z-levels which are for admin functionality, for example including such areas as Central Command and the Syndicate Shuttle + var/list/contact_levels = list(1, 5) // Defines which Z-levels which, for example, a Code Red announcement may affect + var/list/player_levels = list(1, 3, 4, 5, 6) // Defines all Z-levels a character can typically reach + var/const/minutes_to_ticks = 60 * 10 // Event settings var/expected_round_length = 60 * 2 * minutes_to_ticks // 2 hours @@ -458,6 +463,18 @@ if("max_maint_drones") config.max_maint_drones = text2num(value) + if("station_levels") + config.station_levels = text2numlist(value, ";") + + if("admin_levels") + config.admin_levels = text2numlist(value, ";") + + if("contact_levels") + config.contact_levels = text2numlist(value, ";") + + if("player_levels") + config.player_levels = text2numlist(value, ";") + if("expected_round_length") config.expected_round_length = MinutesToTicks(text2num(value)) diff --git a/code/controllers/emergency_shuttle_controller.dm b/code/controllers/emergency_shuttle_controller.dm index 55b325eba3c..83a9d379434 100644 --- a/code/controllers/emergency_shuttle_controller.dm +++ b/code/controllers/emergency_shuttle_controller.dm @@ -18,7 +18,10 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle var/deny_shuttle = 0 //allows admins to prevent the shuttle from being called var/departed = 0 //if the shuttle has left the station at least once - + + var/datum/announcement/priority/emergency_shuttle_docked = new(0, new_sound = sound('sound/AI/shuttledock.ogg')) + var/datum/announcement/priority/emergency_shuttle_called = new(0, new_sound = sound('sound/AI/shuttlecalled.ogg')) + var/datum/announcement/priority/emergency_shuttle_recalled = new(0, new_sound = sound('sound/AI/shuttlerecalled.ogg')) /datum/emergency_shuttle_controller/proc/process() if (wait_for_launch) @@ -29,7 +32,7 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle if (!shuttle.location) //leaving from the station if(is_stranded()) - captain_announce("Hostile environment detected. Departure has been postponed indefinitely pending conflict resolution.") + priority_announcement.Announce("Hostile environment detected. Departure has been postponed indefinitely pending conflict resolution.") wait_for_launch = 0 return //launch the pods! @@ -49,10 +52,9 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle set_launch_countdown(SHUTTLE_LEAVETIME) //get ready to return if (evac) - captain_announce("The Emergency Shuttle has docked with the station. You have approximately [round(estimate_launch_time()/60,1)] minutes to board the Emergency Shuttle.") - world << sound('sound/AI/shuttledock.ogg') + emergency_shuttle_docked.Announce("The Emergency Shuttle has docked with the station. You have approximately [round(estimate_launch_time()/60,1)] minutes to board the Emergency Shuttle.") else - captain_announce("The scheduled Crew Transfer Shuttle has docked with the station. It will depart in approximately [round(emergency_shuttle.estimate_launch_time()/60,1)] minutes.") + priority_announcement.Announce("The scheduled Crew Transfer Shuttle has docked with the station. It will depart in approximately [round(emergency_shuttle.estimate_launch_time()/60,1)] minutes.") //arm the escape pods if (evac) @@ -81,8 +83,7 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle shuttle.move_time = SHUTTLE_TRANSIT_DURATION evac = 1 - captain_announce("An emergency evacuation shuttle has been called. It will arrive in approximately [round(estimate_arrival_time()/60)] minutes.") - world << sound('sound/AI/shuttlecalled.ogg') + emergency_shuttle_called.Announce("An emergency evacuation shuttle has been called. It will arrive in approximately [round(estimate_arrival_time()/60)] minutes.") for(var/area/A in world) if(istype(A, /area/hallway)) A.readyalert() @@ -101,7 +102,7 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle //reset the shuttle transit time if we need to shuttle.move_time = SHUTTLE_TRANSIT_DURATION - captain_announce("A crew transfer has been scheduled. The shuttle has been called. It will arrive in approximately [round(estimate_arrival_time()/60)] minutes.") + priority_announcement.Announce("A crew transfer has been scheduled. The shuttle has been called. It will arrive in approximately [round(estimate_arrival_time()/60)] minutes.") //recalls the shuttle /datum/emergency_shuttle_controller/proc/recall() @@ -111,15 +112,14 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle shuttle.cancel_launch(src) if (evac) - captain_announce("The emergency shuttle has been recalled.") - world << sound('sound/AI/shuttlerecalled.ogg') + emergency_shuttle_recalled.Announce("The emergency shuttle has been recalled.") for(var/area/A in world) if(istype(A, /area/hallway)) A.readyreset() evac = 0 else - captain_announce("The scheduled crew transfer has been cancelled.") + priority_announcement.Announce("The scheduled crew transfer has been cancelled.") /datum/emergency_shuttle_controller/proc/can_call() if (deny_shuttle) diff --git a/code/datums/cargoprofile.dm b/code/datums/cargoprofile.dm index 8bf2e281bbb..d2c11e8984b 100644 --- a/code/datums/cargoprofile.dm +++ b/code/datums/cargoprofile.dm @@ -238,7 +238,7 @@ /obj/item/clothing/mask/facehugger) // NOT CLOTHING AT ALLLLL whitelist = list(/obj/item/clothing,/obj/item/weapon/storage/belt,/obj/item/weapon/storage/backpack, /obj/item/device/radio/headset,/obj/item/device/pda,/obj/item/weapon/card/id,/obj/item/weapon/tank, - /obj/item/weapon/handcuffs, /obj/item/weapon/legcuffs) + /obj/item/weapon/restraints/handcuffs, /obj/item/weapon/restraints/legcuffs) /datum/cargoprofile/trash name = "Trash" diff --git a/code/datums/crafting/recipes.dm b/code/datums/crafting/recipes.dm index 4322fcc9f4a..c2f882eec08 100644 --- a/code/datums/crafting/recipes.dm +++ b/code/datums/crafting/recipes.dm @@ -35,7 +35,7 @@ /datum/crafting_recipe/table/stunprod name = "Stunprod" result_path = /obj/item/weapon/melee/baton/cattleprod - reqs = list(/obj/item/weapon/handcuffs/cable = 1, + reqs = list(/obj/item/weapon/restraints/handcuffs/cable = 1, /obj/item/stack/rods = 1, /obj/item/weapon/wirecutters = 1, /obj/item/weapon/stock_parts/cell = 1) diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index a4cde9f99e0..23d9ff5aa18 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -190,7 +190,7 @@ teleatom.visible_message("\red The [teleatom] bounces off of the portal!") return 0 - if(destination.z == 2) //centcomm z-level + if((destination.z in config.admin_levels)) //centcomm z-level if(istype(teleatom, /obj/mecha)) var/obj/mecha/MM = teleatom MM.occupant << "\red The mech would not survive the jump to a location so far away!" @@ -200,6 +200,6 @@ return 0 - if(destination.z > 7) //Away mission z-levels + if(!(destination.z in config.player_levels)) //Away mission z-levels return 0 return 1 \ No newline at end of file diff --git a/code/datums/periodic_news.dm b/code/datums/periodic_news.dm index 976ef536cb4..ffa52bffdc6 100644 --- a/code/datums/periodic_news.dm +++ b/code/datums/periodic_news.dm @@ -8,6 +8,7 @@ author = "Nanotrasen Editor" channel_name = "Tau Ceti Daily" can_be_redacted = 0 + message_type = "Story" revolution_inciting_event @@ -129,12 +130,6 @@ proc/check_for_newscaster_updates(type) proc/announce_newscaster_news(datum/news_announcement/news) - var/datum/feed_message/newMsg = new /datum/feed_message - newMsg.author = news.author - newMsg.is_admin_message = !news.can_be_redacted - - newMsg.body = news.message - var/datum/feed_channel/sendto for(var/datum/feed_channel/FC in news_network.network_channels) if(FC.channel_name == news.channel_name) @@ -148,6 +143,12 @@ proc/announce_newscaster_news(datum/news_announcement/news) sendto.locked = 1 sendto.is_admin_channel = 1 news_network.network_channels += sendto + + var/datum/feed_message/newMsg = new /datum/feed_message + newMsg.author = news.author ? news.author : sendto.author + newMsg.is_admin_message = !news.can_be_redacted + newMsg.body = news.message + newMsg.message_type = news.message_type sendto.messages += newMsg diff --git a/code/datums/spell.dm b/code/datums/spell.dm index d6c2350510d..d131db35dda 100644 --- a/code/datums/spell.dm +++ b/code/datums/spell.dm @@ -60,7 +60,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin caster.reset_view(0) return 0 - if(user.z == 2 && !centcom_cancast) //Certain spells are not allowed on the centcom zlevel + if((user.z in config.admin_levels) && !centcom_cancast) //Certain spells are not allowed on the centcom zlevel return 0 if(!skipcharge) diff --git a/code/datums/sun.dm b/code/datums/sun.dm index 1379a7b9d87..794e2dd8668 100644 --- a/code/datums/sun.dm +++ b/code/datums/sun.dm @@ -16,7 +16,7 @@ rate = -rate solar_next_update = world.time // init the timer angle = rand (0,360) // the station position to the sun is randomised at round start - + /hook/startup/proc/createSun() sun = new /datum/sun() return 1 @@ -50,54 +50,9 @@ dx = s/abs(s) dy = c / abs(s) - - for(var/obj/machinery/power/M in solars_list) - - if(!M.powernet) - solars_list.Remove(M) + //now tell the solar control computers to update their status and linked devices + for(var/obj/machinery/power/solar_control/SC in solars_list) + if(!SC.powernet) + solars_list.Remove(SC) continue - - // Solar Tracker - if(istype(M, /obj/machinery/power/tracker)) - var/obj/machinery/power/tracker/T = M - T.set_angle(angle) - - // Solar Control - else if(istype(M, /obj/machinery/power/solar_control)) - var/obj/machinery/power/solar_control/C = M - if(C.track == 1) //if manual tracking... - C.tracker_update() //...update the position (not passing an angle, it is handled internally for manual tracking) - - // Solar Panel - else if(istype(M, /obj/machinery/power/solar)) - var/obj/machinery/power/solar/S = M - if(S.control) - occlusion(S) - - -// for a solar panel, trace towards sun to see if we're in shadow -/datum/sun/proc/occlusion(var/obj/machinery/power/solar/S) - - var/ax = S.x // start at the solar panel - var/ay = S.y - var/turf/T = null - - for(var/i = 1 to 20) // 20 steps is enough - ax += dx // do step - ay += dy - - T = locate( round(ax,0.5),round(ay,0.5),S.z) - - if(T.x == 1 || T.x==world.maxx || T.y==1 || T.y==world.maxy) // not obscured if we reach the edge - break - - if(T.density) // if we hit a solid turf, panel is obscured - S.obscured = 1 - return - - S.obscured = 0 // if hit the edge or stepped 20 times, not obscured - S.update_solar_exposure() - - - - + SC.update() diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm old mode 100755 new mode 100644 index 19a01eb7a6e..a3fbd9c9f86 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -1,11 +1,41 @@ //SUPPLY PACKS //NOTE: only secure crate types use the access var (and are lockable) //NOTE: hidden packs only show up when the computer has been hacked. -//ANOTER NOTE: Contraband is obtainable through modified supplycomp circuitboards. +//ANOTHER NOTE: Contraband is obtainable through modified supplycomp circuitboards. //BIG NOTE: Don't add living things to crates, that's bad, it will break the shuttle. //NEW NOTE: Do NOT set the price of any crates below 7 points. Doing so allows infinite points. -var/list/all_supply_groups = list("Operations","Security","Hospitality","Engineering","Medical / Science","Hydroponics","Organic") +// Supply Groups +var/const/supply_emergency = 1 +var/const/supply_security = 2 +var/const/supply_engineer = 3 +var/const/supply_medical = 4 +var/const/supply_science = 5 +var/const/supply_organic = 6 +var/const/supply_materials = 7 +var/const/supply_misc = 8 + +var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engineer,supply_medical,supply_science,supply_organic,supply_materials,supply_misc) + +/proc/get_supply_group_name(var/cat) + switch(cat) + if(1) + return "Emergency" + if(2) + return "Security" + if(3) + return "Engineering" + if(4) + return "Medical" + if(5) + return "Science" + if(6) + return "Food & Livestock" + if(7) + return "Raw Materials" + if(8) + return "Miscellaneous" + /datum/supply_packs var/name = null @@ -13,23 +43,104 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee var/manifest = "" var/amount = null var/cost = null - var/containertype = null + var/containertype = /obj/structure/closet/crate var/containername = null var/access = null var/hidden = 0 var/contraband = 0 - var/group = "Operations" + var/group = supply_misc + /datum/supply_packs/New() manifest += "" -/datum/supply_packs/specialops +////// Use the sections to keep things tidy please /Malkevin + +////////////////////////////////////////////////////////////////////////////// +//////////////////////////// Emergency /////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_packs/emergency // Section header - use these to set default supply group and crate type for sections + name = "HEADER" // Use "HEADER" to denote section headers, this is needed for the supply computers to filter them + containertype = /obj/structure/closet/crate/internals + group = supply_emergency + + +/datum/supply_packs/emergency/evac + name = "Emergency equipment" + contains = list(/obj/machinery/bot/floorbot, + /obj/machinery/bot/floorbot, + /obj/machinery/bot/medbot, + /obj/machinery/bot/medbot, + /obj/item/weapon/tank/air, + /obj/item/weapon/tank/air, + /obj/item/weapon/tank/air, + /obj/item/weapon/tank/air, + /obj/item/weapon/tank/air, + /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) + cost = 35 + containertype = /obj/structure/closet/crate/internals + containername = "emergency crate" + group = supply_emergency + +/datum/supply_packs/emergency/internals + name = "Internals Crate" + contains = list(/obj/item/clothing/mask/gas, + /obj/item/clothing/mask/gas, + /obj/item/clothing/mask/gas, + /obj/item/weapon/tank/air, + /obj/item/weapon/tank/air, + /obj/item/weapon/tank/air) + cost = 10 + containername = "internals crate" + +/datum/supply_packs/emergency/firefighting + name = "Firefighting Crate" + contains = list(/obj/item/clothing/suit/fire/firefighter, + /obj/item/clothing/suit/fire/firefighter, + /obj/item/clothing/mask/gas, + /obj/item/clothing/mask/gas, + /obj/item/device/flashlight, + /obj/item/device/flashlight, + /obj/item/weapon/tank/oxygen/red, + /obj/item/weapon/tank/oxygen/red, + /obj/item/weapon/extinguisher, + /obj/item/weapon/extinguisher, + /obj/item/clothing/head/hardhat/red, + /obj/item/clothing/head/hardhat/red) + cost = 10 + containertype = /obj/structure/closet/crate + containername = "firefighting crate" + +/datum/supply_packs/emergency/atmostank + name = "Firefighting Watertank" + contains = list(/obj/item/weapon/watertank/atmos) + cost = 10 + containertype = /obj/structure/closet/crate/secure + containername = "firefighting watertank crate" + access = access_atmospherics + +/datum/supply_packs/emergency/weedcontrol + name = "Weed Control Crate" + contains = list(/obj/item/weapon/scythe, + /obj/item/clothing/mask/gas, + /obj/item/weapon/grenade/chem_grenade/antiweed, + /obj/item/weapon/grenade/chem_grenade/antiweed) + cost = 15 + containertype = /obj/structure/closet/crate/secure/hydrosec + containername = "weed control crate" + access = access_hydroponics + +/datum/supply_packs/emergency/specialops name = "Special Ops supplies" contains = list(/obj/item/weapon/storage/box/emps, /obj/item/weapon/grenade/smokebomb, @@ -39,11 +150,10 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/item/weapon/grenade/chem_grenade/incendiary) cost = 20 containertype = /obj/structure/closet/crate - containername = "Special Ops crate" - group = "Security" + containername = "special ops crate" hidden = 1 -/datum/supply_packs/syndicate +/datum/supply_packs/emergency/syndicate name = "ERROR_NULL_ENTRY" contains = list(/obj/item/weapon/storage/box/syndicate) cost = 140 @@ -51,471 +161,281 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee containername = "crate" hidden = 1 -/datum/supply_packs/food - name = "Food crate" - contains = list(/obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/drinks/milk, - /obj/item/weapon/reagent_containers/food/drinks/milk, - /obj/item/weapon/storage/fancy/egg_box, - /obj/item/weapon/reagent_containers/food/snacks/grown/banana, - /obj/item/weapon/reagent_containers/food/snacks/grown/banana) +////////////////////////////////////////////////////////////////////////////// +//////////////////////////// Security //////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_packs/security + name = "HEADER" + containertype = /obj/structure/closet/crate/secure/gear + access = access_security + group = supply_security + + +/datum/supply_packs/security/supplies + name = "Security Supplies Crate" + contains = list(/obj/item/weapon/storage/box/flashbangs, + /obj/item/weapon/storage/box/teargas, + /obj/item/weapon/storage/box/flashes, + /obj/item/weapon/storage/box/handcuffs) cost = 10 - containertype = /obj/structure/closet/crate/freezer - containername = "Food crate" - group = "Hospitality" + containername = "security supply crate" -/datum/supply_packs/monkey - name = "Monkey crate" - contains = list (/obj/item/weapon/storage/box/monkeycubes) - cost = 20 - containertype = /obj/structure/closet/crate/freezer - containername = "Monkey crate" - group = "Hydroponics" +////// Armor: Basic -/datum/supply_packs/farwa - name = "Farwa crate" - contains = list (/obj/item/weapon/storage/box/farwacubes) - cost = 30 - containertype = /obj/structure/closet/crate/freezer - containername = "Farwa crate" - group = "Hydroponics" - -/datum/supply_packs/skrell - name = "Neaera crate" - contains = list (/obj/item/weapon/storage/box/neaeracubes) - cost = 30 - containertype = /obj/structure/closet/crate/freezer - containername = "Neaera crate" - group = "Hydroponics" - -/datum/supply_packs/stok - name = "Stok crate" - contains = list (/obj/item/weapon/storage/box/stokcubes) - cost = 30 - containertype = /obj/structure/closet/crate/freezer - containername = "Stok crate" - group = "Hydroponics" - -/datum/supply_packs/beanbagammo - name = "Beanbag shells" - contains = list(/obj/item/ammo_casing/shotgun/beanbag, - /obj/item/ammo_casing/shotgun/beanbag, - /obj/item/ammo_casing/shotgun/beanbag, - /obj/item/ammo_casing/shotgun/beanbag, - /obj/item/ammo_casing/shotgun/beanbag, - /obj/item/ammo_casing/shotgun/beanbag, - /obj/item/ammo_casing/shotgun/beanbag, - /obj/item/ammo_casing/shotgun/beanbag, - /obj/item/ammo_casing/shotgun/beanbag, - /obj/item/ammo_casing/shotgun/beanbag) +/datum/supply_packs/security/helmets + name = "Helmets Crate" + contains = list(/obj/item/clothing/head/helmet, + /obj/item/clothing/head/helmet, + /obj/item/clothing/head/helmet) cost = 10 - containertype = /obj/structure/closet/crate - containername = "Beanbag shells" - group = "Security" + containername = "helmet crate" -/datum/supply_packs/toner - name = "Toner Cartridges" - contains = list(/obj/item/device/toner, - /obj/item/device/toner, - /obj/item/device/toner, - /obj/item/device/toner, - /obj/item/device/toner, - /obj/item/device/toner) +/datum/supply_packs/security/armor + name = "Armor Crate" + contains = list(/obj/item/clothing/suit/armor/vest, + /obj/item/clothing/suit/armor/vest, + /obj/item/clothing/suit/armor/vest) cost = 10 - containertype = /obj/structure/closet/crate - containername = "Toner Cartridges" - group = "Operations" + containername = "armor crate" -/datum/supply_packs/party - name = "Party equipment" - contains = list(/obj/item/weapon/storage/box/drinkingglasses, - /obj/item/weapon/reagent_containers/food/drinks/shaker, - /obj/item/weapon/reagent_containers/food/drinks/bottle/patron, - /obj/item/weapon/reagent_containers/food/drinks/bottle/goldschlager, - /obj/item/weapon/storage/fancy/cigarettes/dromedaryco, - /obj/item/weapon/lipstick/random, - /obj/item/weapon/reagent_containers/food/drinks/cans/ale, - /obj/item/weapon/reagent_containers/food/drinks/cans/ale, - /obj/item/weapon/reagent_containers/food/drinks/cans/beer, - /obj/item/weapon/reagent_containers/food/drinks/cans/beer, - /obj/item/weapon/reagent_containers/food/drinks/cans/beer, - /obj/item/weapon/reagent_containers/food/drinks/cans/beer) - cost = 20 - containertype = /obj/structure/closet/crate - containername = "Party equipment" - group = "Hospitality" +////// Weapons: Basic -/datum/supply_packs/internals - name = "Internals crate" - contains = list(/obj/item/clothing/mask/gas, - /obj/item/clothing/mask/gas, - /obj/item/clothing/mask/gas, - /obj/item/weapon/tank/air, - /obj/item/weapon/tank/air, - /obj/item/weapon/tank/air) +/datum/supply_packs/security/baton + name = "Stun Batons Crate" + contains = list(/obj/item/weapon/melee/baton/loaded, + /obj/item/weapon/melee/baton/loaded, + /obj/item/weapon/melee/baton/loaded) cost = 10 - containertype = /obj/structure/closet/crate/internals - containername = "Internals crate" - group = "Engineering" + containername = "stun baton crate" -/datum/supply_packs/evacuation - name = "Emergency equipment" - contains = list(/obj/item/weapon/storage/toolbox/emergency, - /obj/item/weapon/storage/toolbox/emergency, - /obj/item/clothing/suit/storage/hazardvest, - /obj/item/clothing/suit/storage/hazardvest, - /obj/item/weapon/tank/emergency_oxygen, - /obj/item/weapon/tank/emergency_oxygen, - /obj/item/weapon/tank/emergency_oxygen, - /obj/item/weapon/tank/emergency_oxygen, - /obj/item/weapon/tank/emergency_oxygen, - /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) - cost = 35 - containertype = /obj/structure/closet/crate/internals - containername = "Emergency Crate" - group = "Engineering" - -/datum/supply_packs/inflatable - name = "Inflatable barriers" - contains = list(/obj/item/weapon/storage/briefcase/inflatable, - /obj/item/weapon/storage/briefcase/inflatable, - /obj/item/weapon/storage/briefcase/inflatable) - cost = 20 - containertype = /obj/structure/closet/crate - containername = "Inflatable Barrier Crate" - group = "Engineering" - -/datum/supply_packs/janitor - name = "Janitorial supplies" - contains = list(/obj/item/weapon/reagent_containers/glass/bucket, - /obj/item/weapon/reagent_containers/glass/bucket, - /obj/item/weapon/reagent_containers/glass/bucket, - /obj/item/weapon/mop, - /obj/item/weapon/caution, - /obj/item/weapon/caution, - /obj/item/weapon/caution, - /obj/item/weapon/storage/bag/trash, - /obj/item/weapon/reagent_containers/spray/cleaner, - /obj/item/weapon/reagent_containers/glass/rag, - /obj/item/weapon/grenade/chem_grenade/cleaner, - /obj/item/weapon/grenade/chem_grenade/cleaner, - /obj/item/weapon/grenade/chem_grenade/cleaner) - cost = 10 - containertype = /obj/structure/closet/crate - containername = "Janitorial supplies" - group = "Operations" - -/datum/supply_packs/janicart - name = "Janitorial Cart and Galoshes crate" - contains = list(/obj/structure/janitorialcart, - /obj/item/clothing/shoes/galoshes) - cost = 10 - containertype = /obj/structure/largecrate - containername = "janitorial cart crate" - -/datum/supply_packs/lightbulbs - name = "Replacement lights" - contains = list(/obj/item/weapon/storage/box/lights/mixed, - /obj/item/weapon/storage/box/lights/mixed, - /obj/item/weapon/storage/box/lights/mixed) - cost = 10 - containertype = /obj/structure/closet/crate - containername = "Replacement lights" - group = "Engineering" - -/datum/supply_packs/costume - name = "Standard Costume crate" - contains = list(/obj/item/weapon/storage/backpack/clown, - /obj/item/clothing/shoes/clown_shoes, - /obj/item/clothing/mask/gas/clown_hat, - /obj/item/clothing/under/rank/clown, - /obj/item/weapon/bikehorn, - /obj/item/clothing/under/mime, - /obj/item/clothing/shoes/black, - /obj/item/clothing/gloves/color/white, - /obj/item/clothing/mask/gas/mime, - /obj/item/clothing/head/beret, - /obj/item/clothing/suit/suspenders, - /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing) - cost = 10 - containertype = /obj/structure/closet/crate/secure - containername = "Standard Costumes" - access = access_theatre - group = "Operations" - -/datum/supply_packs/wizard - name = "Wizard costume" - contains = list(/obj/item/weapon/staff, - /obj/item/clothing/suit/wizrobe/fake, - /obj/item/clothing/shoes/sandal, - /obj/item/clothing/head/wizard/fake) - cost = 20 - containertype = /obj/structure/closet/crate - containername = "Wizard costume crate" - group = "Operations" - -/datum/supply_packs/mule - name = "MULEbot Crate" - contains = list(/obj/machinery/bot/mulebot) - cost = 20 - containertype = /obj/structure/largecrate/mule - containername = "MULEbot Crate" - group = "Operations" - -/datum/supply_packs/cargotrain - name = "Cargo Train Tug" - contains = list(/obj/vehicle/train/cargo/engine) - cost = 45 - containertype = /obj/structure/largecrate - containername = "Cargo Train Tug Crate" - group = "Operations" - -/datum/supply_packs/cargotrailer - name = "Cargo Train Trolley" - contains = list(/obj/vehicle/train/cargo/trolley) +/datum/supply_packs/security/laser + name = "Lasers Crate" + contains = list(/obj/item/weapon/gun/energy/laser, + /obj/item/weapon/gun/energy/laser, + /obj/item/weapon/gun/energy/laser) cost = 15 - containertype = /obj/structure/largecrate - containername = "Cargo Train Trolley Crate" - group = "Operations" + containername = "laser crate" -/datum/supply_packs/hydroponics // -- Skie - name = "Hydroponics Supply Crate" - contains = list(/obj/item/weapon/reagent_containers/spray/plantbgone, - /obj/item/weapon/reagent_containers/spray/plantbgone, - /obj/item/weapon/reagent_containers/glass/bottle/ammonia, - /obj/item/weapon/reagent_containers/glass/bottle/ammonia, - /obj/item/weapon/hatchet, - /obj/item/weapon/minihoe, - /obj/item/device/analyzer/plant_analyzer, - /obj/item/clothing/gloves/botanic_leather, - /obj/item/clothing/suit/apron, - /obj/item/weapon/minihoe, - /obj/item/weapon/storage/box/botanydisk - ) // Updated with new things +/datum/supply_packs/security/taser + name = "Stun Guns Crate" + contains = list(/obj/item/weapon/gun/energy/advtaser, + /obj/item/weapon/gun/energy/advtaser, + /obj/item/weapon/gun/energy/advtaser) cost = 15 - containertype = /obj/structure/closet/crate/hydroponics - containername = "Hydroponics crate" - access = access_hydroponics - group = "Hydroponics" + containername = "stun gun crate" -//////// livestock -/datum/supply_packs/organic/cow - name = "Cow Crate" - cost = 30 - containertype = /obj/structure/largecrate/cow - containername = "cow crate" - group = "Organic" +/datum/supply_packs/security/disabler + name = "Disabler Crate" + contains = list(/obj/item/weapon/gun/energy/disabler, + /obj/item/weapon/gun/energy/disabler, + /obj/item/weapon/gun/energy/disabler) + cost = 10 + containername = "disabler crate" -/datum/supply_packs/organic/goat - name = "Goat Crate" +///// Armory stuff + +/datum/supply_packs/security/armory + name = "HEADER" + containertype = /obj/structure/closet/crate/secure/weapon + access = access_armory + +///// Armor: Specialist + +/datum/supply_packs/security/armory/riothelmets + name = "Riot Helmets Crate" + contains = list(/obj/item/clothing/head/helmet/riot, + /obj/item/clothing/head/helmet/riot, + /obj/item/clothing/head/helmet/riot) + cost = 15 + containername = "riot helmets crate" + +/datum/supply_packs/security/armory/riotarmor + name = "Riot Armor Crate" + contains = list(/obj/item/clothing/suit/armor/riot, + /obj/item/clothing/suit/armor/riot, + /obj/item/clothing/suit/armor/riot) + cost = 15 + containername = "riot armor crate" + +/datum/supply_packs/security/armory/riotshields + name = "Riot Shields Crate" + contains = list(/obj/item/weapon/shield/riot, + /obj/item/weapon/shield/riot, + /obj/item/weapon/shield/riot) + cost = 20 + containername = "riot shields crate" + +/datum/supply_packs/security/bullethelmets + name = "Bulletproof Helmets Crate" + contains = list(/obj/item/clothing/head/helmet/alt, + /obj/item/clothing/head/helmet/alt, + /obj/item/clothing/head/helmet/alt) + cost = 10 + containername = "bulletproof helmet crate" + +/datum/supply_packs/security/armory/bulletarmor + name = "Bulletproof Armor Crate" + contains = list(/obj/item/clothing/suit/armor/bulletproof, + /obj/item/clothing/suit/armor/bulletproof, + /obj/item/clothing/suit/armor/bulletproof) + cost = 15 + containername = "tactical armor crate" + +/datum/supply_packs/security/armory/laserarmor + name = "Ablative Armor Crate" + contains = list(/obj/item/clothing/suit/armor/laserproof, + /obj/item/clothing/suit/armor/laserproof) // Only two vests to keep costs down for balance + cost = 20 + containertype = /obj/structure/closet/crate/secure/plasma + containername = "ablative armor crate" + +/////// Weapons: Specialist + +/datum/supply_packs/security/armory/ballistic + name = "Combat Shotguns Crate" + contains = list(/obj/item/weapon/gun/projectile/shotgun/combat, + /obj/item/weapon/gun/projectile/shotgun/combat, + /obj/item/weapon/gun/projectile/shotgun/combat, + /obj/item/weapon/storage/belt/bandolier, + /obj/item/weapon/storage/belt/bandolier, + /obj/item/weapon/storage/belt/bandolier) + cost = 20 + containername = "combat shotgun crate" + +/datum/supply_packs/security/armory/expenergy + name = "Energy Guns Crate" + contains = list(/obj/item/weapon/gun/energy/gun, + /obj/item/weapon/gun/energy/gun) // Only two guns to keep costs down cost = 25 - containertype = /obj/structure/largecrate/goat - containername = "goat crate" - group = "Organic" + containertype = /obj/structure/closet/crate/secure/plasma + containername = "energy gun crate" -/datum/supply_packs/organic/chicken - name = "Chicken Crate" +/datum/supply_packs/security/armory/eweapons + name = "Incendiary Weapons Crate" + contains = list(/obj/item/weapon/flamethrower/full, + /obj/item/weapon/tank/plasma, + /obj/item/weapon/tank/plasma, + /obj/item/weapon/tank/plasma, + /obj/item/weapon/grenade/chem_grenade/incendiary, + /obj/item/weapon/grenade/chem_grenade/incendiary, + /obj/item/weapon/grenade/chem_grenade/incendiary) + cost = 15 // its a fecking flamethrower and some plasma, why the shit did this cost so much before!? + containertype = /obj/structure/closet/crate/secure/plasma + containername = "incendiary weapons crate" + access = access_heads + +/////// Implants & etc + +/datum/supply_packs/security/armory/loyalty + name = "Loyalty Implants Crate" + contains = list (/obj/item/weapon/storage/lockbox/loyalty) + cost = 40 + containername = "loyalty implant crate" + +/datum/supply_packs/security/armory/trackingimp + name = "Tracking Implants Crate" + contains = list (/obj/item/weapon/storage/box/trackimp) cost = 20 - containertype = /obj/structure/largecrate/chick - containername = "chicken crate" - group = "Organic" + containername = "tracking implant crate" -/datum/supply_packs/organic/corgi - name = "Corgi Crate" - cost = 50 - containertype = /obj/structure/largecrate/lisa - containername = "corgi crate" - group = "Organic" - -/datum/supply_packs/organic/cat - name = "Cat crate" - cost = 50 //Cats are worth as much as corgis. - containertype = /obj/structure/largecrate/cat - containername = "cat crate" - group = "Organic" - -/datum/supply_packs/organic/fox - name = "Fox Crate" - cost = 55 //Foxes are cool. - containertype = /obj/structure/closet/critter/fox - containername = "fox crate" - group = "Organic" - -/datum/supply_packs/seeds - name = "Seeds Crate" - contains = list(/obj/item/seeds/chiliseed, - /obj/item/seeds/berryseed, - /obj/item/seeds/cornseed, - /obj/item/seeds/eggplantseed, - /obj/item/seeds/tomatoseed, - /obj/item/seeds/soyaseed, - /obj/item/seeds/wheatseed, - /obj/item/seeds/carrotseed, - /obj/item/seeds/sunflowerseed, - /obj/item/seeds/chantermycelium, - /obj/item/seeds/potatoseed, - /obj/item/seeds/sugarcaneseed) - cost = 10 - containertype = /obj/structure/closet/crate/hydroponics - containername = "Seeds crate" - access = access_hydroponics - group = "Hydroponics" - -/datum/supply_packs/weedcontrol - name = "Weed Control Crate" - contains = list(/obj/item/weapon/scythe, - /obj/item/clothing/mask/gas, - /obj/item/weapon/grenade/chem_grenade/antiweed, - /obj/item/weapon/grenade/chem_grenade/antiweed) +/datum/supply_packs/security/armory/chemimp + name = "Chemical Implants Crate" + contains = list (/obj/item/weapon/storage/box/chemimp) cost = 20 - containertype = /obj/structure/closet/crate/secure/hydrosec - containername = "Weed control crate" - access = access_hydroponics - group = "Hydroponics" + containername = "chemical implant crate" -/datum/supply_packs/exoticseeds - name = "Exotic Seeds Crate" - contains = list(/obj/item/seeds/nettleseed, - /obj/item/seeds/replicapod, - /obj/item/seeds/replicapod, - /obj/item/seeds/replicapod, - /obj/item/seeds/plumpmycelium, - /obj/item/seeds/libertymycelium, - /obj/item/seeds/amanitamycelium, - /obj/item/seeds/reishimycelium, - /obj/item/seeds/bananaseed, - /obj/item/seeds/eggyseed, - /obj/item/seeds/bloodtomatoseed) - cost = 15 - containertype = /obj/structure/closet/crate/hydroponics - containername = "Exotic Seeds crate" - access = access_hydroponics - group = "Hydroponics" +/datum/supply_packs/security/armory/exileimp + name = "Exile Implants Crate" + contains = list (/obj/item/weapon/storage/box/exileimp) + cost = 30 + containername = "exile implant crate" -/datum/supply_packs/medical - name = "Medical crate" - contains = list(/obj/item/weapon/storage/firstaid/regular, - /obj/item/weapon/storage/firstaid/fire, - /obj/item/weapon/storage/firstaid/toxin, - /obj/item/weapon/storage/firstaid/o2, - /obj/item/weapon/storage/firstaid/adv, - /obj/item/weapon/reagent_containers/glass/bottle/antitoxin, - /obj/item/weapon/reagent_containers/glass/bottle/inaprovaline, - /obj/item/weapon/reagent_containers/glass/bottle/stoxin, - /obj/item/weapon/storage/box/syringes, - /obj/item/weapon/storage/box/autoinjectors) - cost = 10 - containertype = /obj/structure/closet/crate/medical - containername = "Medical crate" - group = "Medical / Science" +/datum/supply_packs/security/securitybarriers + name = "Security Barriers Crate" + contains = list(/obj/machinery/deployable/barrier, + /obj/machinery/deployable/barrier, + /obj/machinery/deployable/barrier, + /obj/machinery/deployable/barrier) + cost = 20 + containername = "security barriers crate" -/datum/supply_packs/virus - name = "Virus crate" -/* contains = list(/obj/item/weapon/reagent_containers/glass/bottle/flu_virion, - /obj/item/weapon/reagent_containers/glass/bottle/cold, - /obj/item/weapon/reagent_containers/glass/bottle/epiglottis_virion, - /obj/item/weapon/reagent_containers/glass/bottle/liver_enhance_virion, - /obj/item/weapon/reagent_containers/glass/bottle/fake_gbs, - /obj/item/weapon/reagent_containers/glass/bottle/magnitis, - /obj/item/weapon/reagent_containers/glass/bottle/pierrot_throat, - /obj/item/weapon/reagent_containers/glass/bottle/brainrot, - /obj/item/weapon/reagent_containers/glass/bottle/hullucigen_virion, - /obj/item/weapon/storage/box/syringes, - /obj/item/weapon/storage/box/beakers, - /obj/item/weapon/reagent_containers/glass/bottle/mutagen)*/ - contains = list(/obj/item/weapon/virusdish/random, - /obj/item/weapon/virusdish/random, - /obj/item/weapon/virusdish/random, - /obj/item/weapon/virusdish/random) - cost = 25 - containertype = "/obj/structure/closet/crate/secure" - containername = "Virus crate" - access = access_cmo - group = "Medical / Science" +/datum/supply_packs/security/securityclothes + name = "Security Clothing Crate" + contains = list(/obj/item/clothing/under/rank/security/corp, + /obj/item/clothing/under/rank/security/corp, + /obj/item/clothing/head/soft/sec/corp, + /obj/item/clothing/head/soft/sec/corp, + /obj/item/clothing/under/rank/warden/corp, + /obj/item/clothing/head/beret/sec/warden, + /obj/item/clothing/under/rank/head_of_security/corp, + /obj/item/clothing/head/HoS/beret) + cost = 30 + containername = "security clothing crate" -/datum/supply_packs/metal50 - name = "50 Metal Sheets" - contains = list(/obj/item/stack/sheet/metal) - amount = 50 - cost = 10 - containertype = /obj/structure/closet/crate - containername = "Metal sheets crate" - group = "Engineering" -/datum/supply_packs/glass50 - name = "50 Glass Sheets" - contains = list(/obj/item/stack/sheet/glass) - amount = 50 - cost = 10 - containertype = /obj/structure/closet/crate - containername = "Glass sheets crate" - group = "Engineering" +////////////////////////////////////////////////////////////////////////////// +//////////////////////////// Engineering ///////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// -/datum/supply_packs/electrical - name = "Electrical maintenance crate" - contains = list(/obj/item/weapon/storage/toolbox/electrical, - /obj/item/weapon/storage/toolbox/electrical, - /obj/item/clothing/gloves/yellow, - /obj/item/clothing/gloves/yellow, - /obj/item/weapon/stock_parts/cell, - /obj/item/weapon/stock_parts/cell, - /obj/item/weapon/stock_parts/cell/high, - /obj/item/weapon/stock_parts/cell/high) - cost = 15 - containertype = /obj/structure/closet/crate - containername = "Electrical maintenance crate" - group = "Engineering" +/datum/supply_packs/engineering + name = "HEADER" + group = supply_engineer -/datum/supply_packs/mechanical - name = "Mechanical maintenance crate" - contains = list(/obj/item/weapon/storage/belt/utility/full, - /obj/item/weapon/storage/belt/utility/full, - /obj/item/weapon/storage/belt/utility/full, - /obj/item/clothing/suit/storage/hazardvest, - /obj/item/clothing/suit/storage/hazardvest, - /obj/item/clothing/suit/storage/hazardvest, - /obj/item/clothing/head/welding, - /obj/item/clothing/head/welding, - /obj/item/clothing/head/hardhat) - cost = 10 - containertype = /obj/structure/closet/crate - containername = "Mechanical maintenance crate" - group = "Engineering" -/datum/supply_packs/watertank - name = "Water tank crate" - contains = list(/obj/structure/reagent_dispensers/watertank) - cost = 8 - containertype = /obj/structure/largecrate - containername = "water tank crate" - group = "Hydroponics" - -/datum/supply_packs/fueltank - name = "Fuel tank crate" +/datum/supply_packs/engineering/fueltank + name = "Fuel Tank Crate" contains = list(/obj/structure/reagent_dispensers/fueltank) cost = 8 containertype = /obj/structure/largecrate containername = "fuel tank crate" - group = "Engineering" -/datum/supply_packs/coolanttank - name = "Coolant tank crate" - contains = list(/obj/structure/reagent_dispensers/coolanttank) - cost = 16 - containertype = /obj/structure/largecrate - containername = "coolant tank crate" - group = "Medical / Science" +/datum/supply_packs/engineering/tools //the most robust crate + name = "Toolbox Crate" + contains = list(/obj/item/weapon/storage/toolbox/electrical, + /obj/item/weapon/storage/toolbox/electrical, + /obj/item/weapon/storage/toolbox/mechanical, + /obj/item/weapon/storage/toolbox/electrical, + /obj/item/weapon/storage/toolbox/mechanical, + /obj/item/weapon/storage/toolbox/mechanical) + cost = 10 + containername = "electrical maintenance crate" +/datum/supply_packs/engineering/powergamermitts + name = "Insulated Gloves Crate" + contains = list(/obj/item/clothing/gloves/yellow, + /obj/item/clothing/gloves/yellow, + /obj/item/clothing/gloves/yellow) + cost = 20 //Made of pure-grade bullshittinium + containername = "insulated gloves crate" -/datum/supply_packs/solar - name = "Solar Pack crate" +/datum/supply_packs/engineering/power + name = "Powercell Crate" + contains = list(/obj/item/weapon/stock_parts/cell/high, //Changed to an extra high powercell because normal cells are useless + /obj/item/weapon/stock_parts/cell/high, + /obj/item/weapon/stock_parts/cell/high) + cost = 10 + containername = "electrical maintenance crate" + +/datum/supply_packs/engineering/engiequipment + name = "Engineering Gear Crate" + contains = list(/obj/item/weapon/storage/belt/utility, + /obj/item/weapon/storage/belt/utility, + /obj/item/weapon/storage/belt/utility, + /obj/item/clothing/suit/storage/hazardvest, + /obj/item/clothing/suit/storage/hazardvest, + /obj/item/clothing/suit/storage/hazardvest, + /obj/item/clothing/head/welding, + /obj/item/clothing/head/welding, + /obj/item/clothing/head/welding, + /obj/item/clothing/head/hardhat, + /obj/item/clothing/head/hardhat, + /obj/item/clothing/head/hardhat) + cost = 10 + containername = "engineering gear crate" + +/datum/supply_packs/engineering/solar + name = "Solar Pack Crate" contains = list(/obj/item/solar_assembly, /obj/item/solar_assembly, /obj/item/solar_assembly, @@ -541,48 +461,40 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/item/weapon/tracker_electronics, /obj/item/weapon/paper/solar) cost = 20 - containertype = /obj/structure/closet/crate containername = "solar pack crate" - group = "Engineering" -/datum/supply_packs/engine - name = "Emitter crate" +/datum/supply_packs/engineering/engine + name = "Emitter Crate" contains = list(/obj/machinery/power/emitter, /obj/machinery/power/emitter) cost = 10 containertype = /obj/structure/closet/crate/secure - containername = "Emitter crate" + containername = "emitter crate" access = access_ce - group = "Engineering" -/datum/supply_packs/engine/field_gen - name = "Field Generator crate" +/datum/supply_packs/engineering/engine/field_gen + name = "Field Generator Crate" contains = list(/obj/machinery/field_generator, /obj/machinery/field_generator) - containertype = /obj/structure/closet/crate/secure - containername = "Field Generator crate" - access = access_ce - group = "Engineering" + cost = 10 + containername = "field generator crate" -/datum/supply_packs/engine/sing_gen - name = "Singularity Generator crate" +/datum/supply_packs/engineering/engine/sing_gen + name = "Singularity Generator Crate" contains = list(/obj/machinery/the_singularitygen) - containertype = /obj/structure/closet/crate/secure - containername = "Singularity Generator crate" - access = access_ce - group = "Engineering" + cost = 10 + containername = "singularity generator crate" -/datum/supply_packs/engine/collector - name = "Collector crate" +/datum/supply_packs/engineering/engine/collector + name = "Collector Crate" contains = list(/obj/machinery/power/rad_collector, /obj/machinery/power/rad_collector, /obj/machinery/power/rad_collector) - containername = "Collector crate" - group = "Engineering" + cost = 10 + containername = "collector crate" -/datum/supply_packs/engine/PA - name = "Particle Accelerator crate" - cost = 40 +/datum/supply_packs/engineering/engine/PA + name = "Particle Accelerator Crate" contains = list(/obj/structure/particle_accelerator/fuel_chamber, /obj/machinery/particle_accelerator/control_box, /obj/structure/particle_accelerator/particle_emitter/center, @@ -590,53 +502,195 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/structure/particle_accelerator/particle_emitter/right, /obj/structure/particle_accelerator/power_box, /obj/structure/particle_accelerator/end_cap) - containertype = /obj/structure/closet/crate/secure - containername = "Particle Accelerator crate" - access = access_ce - group = "Engineering" + cost = 25 + containername = "particle accelerator crate" -/datum/supply_packs/mecha_ripley +/datum/supply_packs/engineering/engine/spacesuit + name = "Space Suit Crate" + contains = list(/obj/item/clothing/suit/space, + /obj/item/clothing/head/helmet/space, + /obj/item/clothing/mask/breath,) + cost = 80 + containertype = /obj/structure/closet/crate/secure + containername = "space suit crate" + access = access_eva + +/datum/supply_packs/engineering/inflatable + name = "Inflatable barriers" + contains = list(/obj/item/weapon/storage/briefcase/inflatable, + /obj/item/weapon/storage/briefcase/inflatable, + /obj/item/weapon/storage/briefcase/inflatable) + cost = 20 + containername = "Inflatable Barrier Crate" + +////////////////////////////////////////////////////////////////////////////// +//////////////////////////// Medical ///////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_packs/medical + name = "HEADER" + containertype = /obj/structure/closet/crate/medical + group = supply_medical + + +/datum/supply_packs/medical/supplies + name = "Medical Supplies Crate" + contains = list(/obj/item/weapon/reagent_containers/glass/bottle/antitoxin, + /obj/item/weapon/reagent_containers/glass/bottle/antitoxin, + /obj/item/weapon/reagent_containers/glass/bottle/inaprovaline, + /obj/item/weapon/reagent_containers/glass/bottle/inaprovaline, + /obj/item/weapon/reagent_containers/glass/bottle/stoxin, + /obj/item/weapon/reagent_containers/glass/bottle/stoxin, + /obj/item/weapon/reagent_containers/glass/bottle/toxin, + /obj/item/weapon/reagent_containers/glass/bottle/toxin, + /obj/item/weapon/reagent_containers/glass/beaker/large, + /obj/item/weapon/reagent_containers/glass/beaker/large, + /obj/item/stack/medical/bruise_pack, + /obj/item/weapon/storage/box/beakers, + /obj/item/weapon/storage/box/syringes, + /obj/item/weapon/storage/box/bodybags) + cost = 20 + containertype = /obj/structure/closet/crate/medical + containername = "medical supplies crate" + +/datum/supply_packs/medical/firstaid + name = "First Aid Kits Crate" + contains = list(/obj/item/weapon/storage/firstaid/regular, + /obj/item/weapon/storage/firstaid/regular, + /obj/item/weapon/storage/firstaid/regular, + /obj/item/weapon/storage/firstaid/regular) + cost = 10 + containername = "first aid kits crate" + +/datum/supply_packs/medical/firstaidadv + name = "Advaced First Aid Kits Crate" + contains = list(/obj/item/weapon/storage/firstaid/adv, + /obj/item/weapon/storage/firstaid/adv, + /obj/item/weapon/storage/firstaid/adv, + /obj/item/weapon/storage/firstaid/adv) + cost = 10 + containername = "advaced first aid kits crate" + +/datum/supply_packs/medical/firstaidburns + name = "Burns Treatment Kits Crate" + contains = list(/obj/item/weapon/storage/firstaid/fire, + /obj/item/weapon/storage/firstaid/fire, + /obj/item/weapon/storage/firstaid/fire) + cost = 10 + containername = "fire first aid kits crate" + +/datum/supply_packs/medical/firstaidtoxins + name = "Toxin Treatment Kits Crate" + contains = list(/obj/item/weapon/storage/firstaid/toxin, + /obj/item/weapon/storage/firstaid/toxin, + /obj/item/weapon/storage/firstaid/toxin) + cost = 10 + containername = "toxin first aid kits crate" + +/datum/supply_packs/medical/firstaidoxygen + name = "Oxygen Deprivation Kits Crate" + contains = list(/obj/item/weapon/storage/firstaid/o2, + /obj/item/weapon/storage/firstaid/o2, + /obj/item/weapon/storage/firstaid/o2) + cost = 10 + containername = "oxygen deprivation kits crate" + + +/datum/supply_packs/medical/virus + name = "Virus Crate" + contains = list(/obj/item/weapon/virusdish/random, + /obj/item/weapon/virusdish/random, + /obj/item/weapon/virusdish/random, + /obj/item/weapon/virusdish/random) + cost = 25 + containertype = /obj/structure/closet/crate/secure/plasma + containername = "virus crate" + access = access_cmo + + +/datum/supply_packs/medical/bloodpacks + name = "Blood Pack Variety Crate" + contains = list(/obj/item/weapon/reagent_containers/blood/empty, + /obj/item/weapon/reagent_containers/blood/empty, + /obj/item/weapon/reagent_containers/blood/APlus, + /obj/item/weapon/reagent_containers/blood/AMinus, + /obj/item/weapon/reagent_containers/blood/BPlus, + /obj/item/weapon/reagent_containers/blood/BMinus, + /obj/item/weapon/reagent_containers/blood/OPlus, + /obj/item/weapon/reagent_containers/blood/OMinus) + cost = 35 + containertype = /obj/structure/closet/crate/freezer + containername = "blood pack crate" + +/datum/supply_packs/medical/iv_drip + name = "IV Drip Crate" + contains = list(/obj/machinery/iv_drip) + cost = 30 + containertype = /obj/structure/closet/crate/secure + containername = "iv drip crate" + access = access_cmo + +/datum/supply_packs/medical/surgery + name = "Surgery crate" + contains = list(/obj/item/weapon/cautery, + /obj/item/weapon/surgicaldrill, + /obj/item/clothing/mask/breath/medical, + /obj/item/weapon/tank/anesthetic, + /obj/item/weapon/FixOVein, + /obj/item/weapon/hemostat, + /obj/item/weapon/scalpel, + /obj/item/weapon/bonegel, + /obj/item/weapon/retractor, + /obj/item/weapon/bonesetter, + /obj/item/weapon/circular_saw) + cost = 25 + containertype = /obj/structure/closet/crate/secure + containername = "Surgery crate" + access = access_medical + + +////////////////////////////////////////////////////////////////////////////// +//////////////////////////// Science ///////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_packs/science + name = "HEADER" + group = supply_science + + +/datum/supply_packs/science/robotics + name = "Robotics Assembly Crate" + contains = list(/obj/item/device/assembly/prox_sensor, + /obj/item/device/assembly/prox_sensor, + /obj/item/device/assembly/prox_sensor, + /obj/item/weapon/storage/toolbox/electrical, + /obj/item/weapon/storage/box/flashes, + /obj/item/weapon/stock_parts/cell/high, + /obj/item/weapon/stock_parts/cell/high) + cost = 10 + containertype = /obj/structure/closet/crate/secure + containername = "robotics assembly crate" + access = access_robotics + +/datum/supply_packs/science/robotics/mecha_ripley name = "Circuit Crate (\"Ripley\" APLU)" contains = list(/obj/item/weapon/book/manual/ripley_build_and_repair, /obj/item/weapon/circuitboard/mecha/ripley/main, //TEMPORARY due to lack of circuitboard printer /obj/item/weapon/circuitboard/mecha/ripley/peripherals) //TEMPORARY due to lack of circuitboard printer cost = 30 containertype = /obj/structure/closet/crate/secure - containername = "APLU \"Ripley\" Circuit Crate" - access = access_robotics - group = "Engineering" + containername = "\improper APLU \"Ripley\" circuit crate" -/datum/supply_packs/mecha_odysseus +/datum/supply_packs/science/robotics/mecha_odysseus name = "Circuit Crate (\"Odysseus\")" contains = list(/obj/item/weapon/circuitboard/mecha/odysseus/peripherals, //TEMPORARY due to lack of circuitboard printer /obj/item/weapon/circuitboard/mecha/odysseus/main) //TEMPORARY due to lack of circuitboard printer cost = 25 containertype = /obj/structure/closet/crate/secure - containername = "\"Odysseus\" Circuit Crate" - access = access_robotics - group = "Engineering" + containername = "\improper \"Odysseus\" circuit crate" - -/datum/supply_packs/robotics - name = "Robotics Assembly Crate" - contains = list(/obj/item/device/assembly/prox_sensor, - /obj/item/device/assembly/prox_sensor, - /obj/item/device/assembly/prox_sensor, - /obj/item/weapon/storage/toolbox/electrical, - /obj/item/device/flash, - /obj/item/device/flash, - /obj/item/device/flash, - /obj/item/device/flash, - /obj/item/weapon/stock_parts/cell/high, - /obj/item/weapon/stock_parts/cell/high) - cost = 10 - containertype = /obj/structure/closet/crate/secure/gear - containername = "Robotics Assembly" - access = access_robotics - group = "Engineering" - -/datum/supply_packs/plasma - name = "Plasma assembly crate" +/datum/supply_packs/science/plasma + name = "Plasma Assembly Crate" contains = list(/obj/item/weapon/tank/plasma, /obj/item/weapon/tank/plasma, /obj/item/weapon/tank/plasma, @@ -646,175 +700,16 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/item/device/assembly/prox_sensor, /obj/item/device/assembly/prox_sensor, /obj/item/device/assembly/prox_sensor, - /obj/item/device/transfer_valve, - /obj/item/device/transfer_valve, - /obj/item/device/transfer_valve, /obj/item/device/assembly/timer, /obj/item/device/assembly/timer, /obj/item/device/assembly/timer) cost = 10 containertype = /obj/structure/closet/crate/secure/plasma - containername = "Plasma assembly crate" + containername = "plasma assembly crate" access = access_tox_storage - group = "Medical / Science" + group = supply_science -/datum/supply_packs/weapons - name = "Weapons crate" - contains = list(/obj/item/weapon/melee/baton/loaded, - /obj/item/weapon/melee/baton/loaded, - /obj/item/weapon/gun/energy/laser, - /obj/item/weapon/gun/energy/laser, - /obj/item/weapon/gun/energy/advtaser, - /obj/item/weapon/gun/energy/advtaser, - /obj/item/weapon/storage/box/flashbangs, - /obj/item/weapon/storage/box/flashbangs) - cost = 30 - containertype = /obj/structure/closet/crate/secure/weapon - containername = "Weapons crate" - access = access_security - group = "Security" - -/datum/supply_packs/disabler - name = "Disabler Crate" - contains = list(/obj/item/weapon/gun/energy/disabler, - /obj/item/weapon/gun/energy/disabler, - /obj/item/weapon/gun/energy/disabler) - cost = 10 - containertype = /obj/structure/closet/crate/secure/weapon - containername = "disabler crate" - access = access_security - group = "Security" - -/datum/supply_packs/eweapons - name = "Experimental weapons crate" - contains = list(/obj/item/weapon/flamethrower/full, - /obj/item/weapon/tank/plasma, - /obj/item/weapon/tank/plasma, - /obj/item/weapon/tank/plasma, - /obj/item/weapon/grenade/chem_grenade/incendiary, - /obj/item/weapon/grenade/chem_grenade/incendiary, - /obj/item/weapon/grenade/chem_grenade/incendiary) - cost = 25 - containertype = /obj/structure/closet/crate/secure/weapon - containername = "Experimental weapons crate" - access = access_heads - group = "Security" - -/datum/supply_packs/armor - name = "Armor crate" - contains = list(/obj/item/clothing/head/helmet, - /obj/item/clothing/head/helmet, - /obj/item/clothing/suit/armor/vest, - /obj/item/clothing/suit/armor/vest) - cost = 15 - containertype = /obj/structure/closet/crate/secure - containername = "Armor crate" - access = access_security - group = "Security" - -/datum/supply_packs/riot - name = "Riot gear crate" - contains = list(/obj/item/weapon/melee/baton/loaded, - /obj/item/weapon/melee/baton/loaded, - /obj/item/weapon/melee/baton/loaded, - /obj/item/weapon/shield/riot, - /obj/item/weapon/shield/riot, - /obj/item/weapon/shield/riot, - /obj/item/weapon/storage/box/flashbangs, - /obj/item/weapon/storage/box/flashbangs, - /obj/item/weapon/storage/box/flashbangs, - /obj/item/weapon/handcuffs, - /obj/item/weapon/handcuffs, - /obj/item/weapon/handcuffs, - /obj/item/clothing/head/helmet/riot, - /obj/item/clothing/suit/armor/riot, - /obj/item/clothing/head/helmet/riot, - /obj/item/clothing/suit/armor/riot, - /obj/item/clothing/head/helmet/riot, - /obj/item/clothing/suit/armor/riot) - cost = 60 - containertype = /obj/structure/closet/crate/secure - containername = "Riot gear crate" - access = access_armory - group = "Security" - -/datum/supply_packs/loyalty - name = "Loyalty implant crate" - contains = list (/obj/item/weapon/storage/lockbox/loyalty) - cost = 60 - containertype = /obj/structure/closet/crate/secure - containername = "Loyalty implant crate" - access = access_armory - group = "Security" - -/datum/supply_packs/ballistic - name = "Ballistic gear crate" - contains = list(/obj/item/clothing/suit/armor/bulletproof, - /obj/item/clothing/suit/armor/bulletproof, - /obj/item/weapon/storage/belt/bandolier, - /obj/item/weapon/storage/belt/bandolier, - /obj/item/weapon/gun/projectile/shotgun/combat, - /obj/item/weapon/gun/projectile/shotgun/combat) - cost = 50 - containertype = /obj/structure/closet/crate/secure - containername = "Ballistic gear crate" - access = access_armory - group = "Security" - -/datum/supply_packs/shotgunammo - name = "Shotgun shells" - contains = list(/obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/shotgun) - cost = 20 - containertype = /obj/structure/closet/crate/secure - containername = "Shotgun shells" - access = access_armory - group = "Security" - -/datum/supply_packs/expenergy - name = "Experimental energy gear crate" - contains = list(/obj/item/clothing/suit/armor/laserproof, - /obj/item/clothing/suit/armor/laserproof, - /obj/item/weapon/gun/energy/gun, - /obj/item/weapon/gun/energy/gun) - cost = 50 - containertype = /obj/structure/closet/crate/secure - containername = "Experimental energy gear crate" - access = access_armory - group = "Security" - -/datum/supply_packs/exparmor - name = "Experimental armor crate" - contains = list(/obj/item/clothing/suit/armor/laserproof, - /obj/item/clothing/suit/armor/bulletproof, - /obj/item/clothing/head/helmet/riot, - /obj/item/clothing/suit/armor/riot) - cost = 35 - containertype = /obj/structure/closet/crate/secure - containername = "Experimental armor crate" - access = access_armory - group = "Security" - -/datum/supply_packs/securitybarriers - name = "Security Barriers" - contains = list(/obj/machinery/deployable/barrier, - /obj/machinery/deployable/barrier, - /obj/machinery/deployable/barrier, - /obj/machinery/deployable/barrier) - cost = 20 - containertype = /obj/structure/closet/crate/secure/gear - containername = "Security Barriers crate" - group = "Security" - -/datum/supply_packs/securitybarriers +/datum/supply_packs/science/shieldwalls name = "Shield Generators" contains = list(/obj/machinery/shieldwallgen, /obj/machinery/shieldwallgen, @@ -822,11 +717,502 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/machinery/shieldwallgen) cost = 20 containertype = /obj/structure/closet/crate/secure - containername = "Shield Generators crate" + containername = "shield generators crate" access = access_teleporter - group = "Security" -/datum/supply_packs/randomised + +/datum/supply_packs/science/transfer_valves + name = "Tank Transfer Valves" + contains = list(/obj/item/device/transfer_valve, + /obj/item/device/transfer_valve) + cost = 60 + containertype = /obj/structure/closet/crate/secure + containername = "transfer valves crate" + access = access_rd + + +////////////////////////////////////////////////////////////////////////////// +//////////////////////////// Organic ///////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_packs/organic + name = "HEADER" + group = supply_organic + containertype = /obj/structure/closet/crate/freezer + + +/datum/supply_packs/organic/food + name = "Food Crate" + contains = list(/obj/item/weapon/reagent_containers/food/snacks/flour, + /obj/item/weapon/reagent_containers/food/snacks/flour, + /obj/item/weapon/reagent_containers/food/snacks/flour, + /obj/item/weapon/reagent_containers/food/snacks/flour, + /obj/item/weapon/reagent_containers/food/drinks/milk, + /obj/item/weapon/reagent_containers/food/drinks/soymilk, + /obj/item/weapon/storage/fancy/egg_box, + /obj/item/weapon/reagent_containers/food/condiment/enzyme, + /obj/item/weapon/reagent_containers/food/condiment/sugar, + /obj/item/weapon/reagent_containers/food/snacks/meat/monkey, + /obj/item/weapon/reagent_containers/food/snacks/grown/banana, + /obj/item/weapon/reagent_containers/food/snacks/grown/banana, + /obj/item/weapon/reagent_containers/food/snacks/grown/banana) + cost = 10 + containername = "food crate" + +/datum/supply_packs/organic/pizza + name = "Pizza Crate" + contains = list(/obj/item/pizzabox/margherita, + /obj/item/pizzabox/mushroom, + /obj/item/pizzabox/meat, + /obj/item/pizzabox/vegetable) + cost = 60 + containername = "Pizza crate" + +/datum/supply_packs/organic/monkey + name = "Monkey Crate" + contains = list (/obj/item/weapon/storage/box/monkeycubes) + cost = 20 + containername = "monkey crate" + +/datum/supply_packs/organic/farwa + name = "Farwa crate" + contains = list (/obj/item/weapon/storage/box/farwacubes) + cost = 30 + containername = "farwa crate" + +/datum/supply_packs/organic/skrell + name = "Neaera crate" + contains = list (/obj/item/weapon/storage/box/neaeracubes) + cost = 30 + containername = "neaera crate" + +/datum/supply_packs/organic/stok + name = "Stok crate" + contains = list (/obj/item/weapon/storage/box/stokcubes) + cost = 30 + containername = "stok crate" + +/datum/supply_packs/organic/party + name = "Party equipment" + contains = list(/obj/item/weapon/storage/box/drinkingglasses, + /obj/item/weapon/reagent_containers/food/drinks/shaker, + /obj/item/weapon/reagent_containers/food/drinks/bottle/patron, + /obj/item/weapon/reagent_containers/food/drinks/bottle/goldschlager, + /obj/item/weapon/reagent_containers/food/drinks/cans/ale, + /obj/item/weapon/reagent_containers/food/drinks/cans/ale, + /obj/item/weapon/reagent_containers/food/drinks/cans/beer, + /obj/item/weapon/reagent_containers/food/drinks/cans/beer, + /obj/item/weapon/reagent_containers/food/drinks/cans/beer, + /obj/item/weapon/reagent_containers/food/drinks/cans/beer) + cost = 20 + containername = "party equipment" + +//////// livestock +/datum/supply_packs/organic/cow + name = "Cow Crate" + cost = 30 + containertype = /obj/structure/closet/critter/cow + containername = "cow crate" + +/datum/supply_packs/organic/goat + name = "Goat Crate" + cost = 25 + containertype = /obj/structure/closet/critter/goat + containername = "goat crate" + +/datum/supply_packs/organic/chicken + name = "Chicken Crate" + cost = 20 + containertype = /obj/structure/closet/critter/chick + containername = "chicken crate" + +/datum/supply_packs/organic/corgi + name = "Corgi Crate" + cost = 50 + containertype = /obj/structure/closet/critter/corgi + containername = "corgi crate" + +/datum/supply_packs/organic/cat + name = "Cat Crate" + cost = 50 //Cats are worth as much as corgis. + containertype = /obj/structure/closet/critter/cat + containername = "cat crate" + +/datum/supply_packs/organic/pug + name = "Pug Crate" + cost = 50 + containertype = /obj/structure/closet/critter/pug + containername = "pug crate" + +/datum/supply_packs/organic/fox + name = "Fox Crate" + cost = 55 //Foxes are cool. + containertype = /obj/structure/closet/critter/fox + containername = "fox crate" + +/datum/supply_packs/organic/butterfly + name = "Butterflies Crate" + cost = 50 + containertype = /obj/structure/closet/critter/butterfly + containername = "butterflies crate" + contraband = 1 + +////// hippy gear + +/datum/supply_packs/organic/hydroponics // -- Skie + name = "Hydroponics Supply Crate" + contains = list(/obj/item/weapon/reagent_containers/spray/plantbgone, + /obj/item/weapon/reagent_containers/spray/plantbgone, + /obj/item/weapon/reagent_containers/glass/bottle/ammonia, + /obj/item/weapon/reagent_containers/glass/bottle/ammonia, + /obj/item/weapon/hatchet, + /obj/item/weapon/minihoe, + /obj/item/device/analyzer/plant_analyzer, + /obj/item/clothing/gloves/botanic_leather, + /obj/item/clothing/suit/apron) // Updated with new things + cost = 15 + containertype = /obj/structure/closet/crate/hydroponics + containername = "hydroponics crate" + +/datum/supply_packs/misc/hydroponics/hydrotank + name = "Hydroponics Watertank Backpack Crate" + contains = list(/obj/item/weapon/watertank) + cost = 10 + containertype = /obj/structure/closet/crate/secure + containername = "hydroponics watertank crate" + access = access_hydroponics + +/datum/supply_packs/organic/hydroponics/seeds + name = "Seeds Crate" + contains = list(/obj/item/seeds/chiliseed, + /obj/item/seeds/berryseed, + /obj/item/seeds/cornseed, + /obj/item/seeds/eggplantseed, + /obj/item/seeds/tomatoseed, + /obj/item/seeds/soyaseed, + /obj/item/seeds/wheatseed, + /obj/item/seeds/carrotseed, + /obj/item/seeds/sunflowerseed, + /obj/item/seeds/chantermycelium, + /obj/item/seeds/potatoseed, + /obj/item/seeds/sugarcaneseed) + cost = 10 + containername = "seeds crate" + +/datum/supply_packs/organic/hydroponics/exoticseeds + name = "Exotic Seeds Crate" + contains = list(/obj/item/seeds/nettleseed, + /obj/item/seeds/replicapod, + /obj/item/seeds/replicapod, + /obj/item/seeds/replicapod, + /obj/item/seeds/plumpmycelium, + /obj/item/seeds/libertymycelium, + /obj/item/seeds/amanitamycelium, + /obj/item/seeds/reishimycelium, + /obj/item/seeds/bananaseed, + /obj/item/seeds/eggyseed) + cost = 15 + containername = "exotic seeds crate" + +/datum/supply_packs/organic/bee_keeper + name = "Beekeeping Crate" + contains = list(/obj/item/beezeez, + /obj/item/beezeez, + /obj/item/weapon/bee_net, + /obj/item/apiary, + /obj/item/queen_bee, + /obj/item/queen_bee, + /obj/item/queen_bee) + cost = 20 + containertype = /obj/structure/closet/crate/hydroponics + containername = "Beekeeping crate" + access = access_hydroponics + +/datum/supply_packs/organic/vending + name = "Bartending Supply Crate" + contains = list(/obj/item/weapon/vending_refill/boozeomat, + /obj/item/weapon/vending_refill/boozeomat, + /obj/item/weapon/vending_refill/boozeomat, + /obj/item/weapon/vending_refill/coffee, + /obj/item/weapon/vending_refill/coffee, + /obj/item/weapon/vending_refill/coffee) + cost = 20 + containername = "bartending supply crate" + +/datum/supply_packs/organic/foodcart + name = "Food Cart crate" + contains = list(/obj/structure/foodcart) + cost = 10 + containertype = /obj/structure/largecrate + containername = "food cart crate" + +/datum/supply_packs/organic/vending/snack + name = "Snack Supply Crate" + contains = list(/obj/item/weapon/vending_refill/snack, + /obj/item/weapon/vending_refill/snack, + /obj/item/weapon/vending_refill/snack) + cost = 15 + containername = "snacks supply crate" + +/datum/supply_packs/organic/vending/cola + name = "Softdrinks Supply Crate" + contains = list(/obj/item/weapon/vending_refill/cola, + /obj/item/weapon/vending_refill/cola, + /obj/item/weapon/vending_refill/cola) + cost = 15 + containername = "softdrinks supply crate" + +/datum/supply_packs/organic/vending/cigarette + name = "Cigarette Supply Crate" + contains = list(/obj/item/weapon/vending_refill/cigarette, + /obj/item/weapon/vending_refill/cigarette, + /obj/item/weapon/vending_refill/cigarette) + cost = 15 + containername = "cigarette supply crate" + +////////////////////////////////////////////////////////////////////////////// +//////////////////////////// Materials /////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_packs/materials + name = "HEADER" + group = supply_materials + + +/datum/supply_packs/materials/metal50 + name = "50 Metal Sheets" + contains = list(/obj/item/stack/sheet/metal) + amount = 50 + cost = 10 + containername = "metal sheets crate" + +/datum/supply_packs/materials/plasteel20 + name = "20 Plasteel Sheets" + contains = list(/obj/item/stack/sheet/plasteel) + amount = 20 + cost = 30 + containername = "plasteel sheets crate" + +/datum/supply_packs/materials/plasteel50 + name = "50 Plasteel Sheets" + contains = list(/obj/item/stack/sheet/plasteel) + amount = 50 + cost = 50 + containername = "plasteel sheets crate" + +/datum/supply_packs/materials/glass50 + name = "50 Glass Sheets" + contains = list(/obj/item/stack/sheet/glass) + amount = 50 + cost = 10 + containername = "glass sheets crate" + +/datum/supply_packs/materials/cardboard50 + name = "50 Cardboard Sheets" + contains = list(/obj/item/stack/sheet/cardboard) + amount = 50 + cost = 10 + containername = "cardboard sheets crate" + +/datum/supply_packs/materials/sandstone30 + name = "30 Sandstone Blocks" + contains = list(/obj/item/stack/sheet/mineral/sandstone) + amount = 30 + cost = 20 + containername = "sandstone blocks crate" + + +////////////////////////////////////////////////////////////////////////////// +//////////////////////////// Miscellaneous /////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_packs/misc + name = "HEADER" + group = supply_misc + +/datum/supply_packs/misc/mule + name = "MULEbot Crate" + contains = list(/obj/machinery/bot/mulebot) + cost = 20 + containertype = /obj/structure/largecrate/mule + containername = "\improper MULEbot Crate" + +/datum/supply_packs/misc/watertank + name = "Water Tank Crate" + contains = list(/obj/structure/reagent_dispensers/watertank) + cost = 8 + containertype = /obj/structure/largecrate + containername = "water tank crate" + +/datum/supply_packs/misc/lasertag + name = "Laser Tag Crate" + contains = list(/obj/item/weapon/gun/energy/laser/redtag, + /obj/item/weapon/gun/energy/laser/redtag, + /obj/item/weapon/gun/energy/laser/redtag, + /obj/item/weapon/gun/energy/laser/bluetag, + /obj/item/weapon/gun/energy/laser/bluetag, + /obj/item/weapon/gun/energy/laser/bluetag, + /obj/item/clothing/suit/redtag, + /obj/item/clothing/suit/redtag, + /obj/item/clothing/suit/redtag, + /obj/item/clothing/suit/bluetag, + /obj/item/clothing/suit/bluetag, + /obj/item/clothing/suit/bluetag, + /obj/item/clothing/head/helmet/redtaghelm, + /obj/item/clothing/head/helmet/bluetaghelm) + cost = 15 + containername = "laser tag crate" + +/datum/supply_packs/misc/religious_supplies + name = "Religious Supplies Crate" + contains = list(/obj/item/weapon/reagent_containers/food/drinks/bottle/holywater, + /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater, + /obj/item/weapon/storage/bible/booze, + /obj/item/weapon/storage/bible/booze, + /obj/item/clothing/suit/chaplain_hoodie, + /obj/item/clothing/head/chaplain_hood, + /obj/item/clothing/suit/chaplain_hoodie, + /obj/item/clothing/head/chaplain_hood) + cost = 40 + containername = "religious supplies crate" + + +///////////// Paper Work + +/datum/supply_packs/misc/paper + name = "Bureaucracy Crate" + contains = list(/obj/structure/filingcabinet/chestdrawer, + /obj/item/device/camera_film, + /obj/item/weapon/hand_labeler, + /obj/item/weapon/paper_bin, + /obj/item/weapon/pen, + /obj/item/weapon/pen/blue, + /obj/item/weapon/pen/red, + /obj/item/weapon/folder/blue, + /obj/item/weapon/folder/red, + /obj/item/weapon/folder/yellow, + /obj/item/weapon/clipboard, + /obj/item/weapon/clipboard) + cost = 15 + containername = "bureaucracy crate" + +/datum/supply_packs/misc/toner + name = "Toner Cartridges crate" + contains = list(/obj/item/device/toner, + /obj/item/device/toner, + /obj/item/device/toner, + /obj/item/device/toner, + /obj/item/device/toner, + /obj/item/device/toner) + cost = 10 + containername = "toner cartridges crate" + +/datum/supply_packs/misc/artscrafts + name = "Arts and Crafts supplies" + contains = list(/obj/item/weapon/storage/fancy/crayons, + /obj/item/device/camera, + /obj/item/device/camera_film, + /obj/item/device/camera_film, + /obj/item/weapon/storage/photo_album, + /obj/item/weapon/packageWrap, + /obj/item/weapon/reagent_containers/glass/paint/red, + /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/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, + /obj/item/weapon/wrapping_paper) + cost = 10 + containername = "Arts and Crafts crate" + +///////////// Janitor Supplies + +/datum/supply_packs/misc/janitor + name = "Janitorial Supplies Crate" + contains = list(/obj/item/weapon/reagent_containers/glass/bucket, + /obj/item/weapon/reagent_containers/glass/bucket, + /obj/item/weapon/reagent_containers/glass/bucket, + /obj/item/weapon/mop, + /obj/item/weapon/caution, + /obj/item/weapon/caution, + /obj/item/weapon/caution, + /obj/item/weapon/storage/bag/trash, + /obj/item/weapon/reagent_containers/spray/cleaner, + /obj/item/weapon/reagent_containers/glass/rag, + /obj/item/weapon/grenade/chem_grenade/cleaner, + /obj/item/weapon/grenade/chem_grenade/cleaner, + /obj/item/weapon/grenade/chem_grenade/cleaner) + cost = 10 + containername = "janitorial supplies crate" + +/datum/supply_packs/misc/janitor/janicart + name = "Janitorial Cart and Galoshes Crate" + contains = list(/obj/structure/janitorialcart, + /obj/item/clothing/shoes/galoshes) + cost = 10 + containertype = /obj/structure/largecrate + containername = "janitorial cart crate" + +/datum/supply_packs/misc/janitor/janitank + name = "Janitor Watertank Backpack" + contains = list(/obj/item/weapon/watertank/janitor) + cost = 10 + containertype = /obj/structure/closet/crate/secure + containername = "janitor watertank crate" + access = access_janitor + +/datum/supply_packs/misc/janitor/lightbulbs + name = "Replacement Lights" + contains = list(/obj/item/weapon/storage/box/lights/mixed, + /obj/item/weapon/storage/box/lights/mixed, + /obj/item/weapon/storage/box/lights/mixed) + cost = 10 + containername = "replacement lights" + +///////////// Costumes + +/datum/supply_packs/misc/costume + name = "Standard Costume Crate" + contains = list(/obj/item/weapon/storage/backpack/clown, + /obj/item/clothing/shoes/clown_shoes, + /obj/item/clothing/mask/gas/clown_hat, + /obj/item/clothing/under/rank/clown, + /obj/item/weapon/bikehorn, + /obj/item/clothing/under/mime, + /obj/item/clothing/shoes/black, + /obj/item/clothing/gloves/color/white, + /obj/item/clothing/mask/gas/mime, + /obj/item/clothing/head/beret, + /obj/item/clothing/suit/suspenders, + /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing) + cost = 10 + containertype = /obj/structure/closet/crate/secure + containername = "standard costumes" + access = access_theatre + +/datum/supply_packs/misc/wizard + name = "Wizard Costume Crate" + contains = list(/obj/item/weapon/staff, + /obj/item/clothing/suit/wizrobe/fake, + /obj/item/clothing/shoes/sandal, + /obj/item/clothing/head/wizard/fake) + cost = 20 + containername = "wizard costume crate" + +/datum/supply_packs/misc/mafia + name = "Mafia Supply crate" + contains = list(/obj/item/clothing/suit/browntrenchcoat =1,/obj/item/clothing/suit/blacktrenchcoat =1,/obj/item/clothing/head/fedora/whitefedora =1, + /obj/item/clothing/head/fedora/brownfedora =1,/obj/item/clothing/head/fedora =1,/obj/item/clothing/under/flappers =1,/obj/item/clothing/under/mafia =1,/obj/item/clothing/under/mafia/vest =1,/obj/item/clothing/under/mafia/white =1, + /obj/item/clothing/under/mafia/sue =1,/obj/item/clothing/under/mafia/tan =1, /obj/item/toy/crossbow/tommygun =2) + cost = 15 + containername = "mafia supply crate" + +/datum/supply_packs/misc/randomised var/num_contained = 3 //number of items picked to be contained in a randomised crate contains = list(/obj/item/clothing/head/collectable/chef, /obj/item/clothing/head/collectable/paper, @@ -850,360 +1236,61 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/item/clothing/head/collectable/petehat) name = "Collectable hat crate!" cost = 200 - containertype = /obj/structure/closet/crate - containername = "Collectable hats crate! Brought to you by Bass.inc!" - group = "Operations" + containername = "collectable hats crate! Brought to you by Bass.inc!" -/datum/supply_packs/randomised/New() +/datum/supply_packs/misc/randomised/New() manifest += "Contains any [num_contained] of:" ..() -/datum/supply_packs/artscrafts - name = "Arts and Crafts supplies" - contains = list(/obj/item/weapon/storage/fancy/crayons, - /obj/item/device/camera, - /obj/item/device/camera_film, - /obj/item/device/camera_film, - /obj/item/weapon/storage/photo_album, - /obj/item/weapon/packageWrap, - /obj/item/weapon/reagent_containers/glass/paint/red, - /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/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, - /obj/item/weapon/wrapping_paper) - cost = 10 - containertype = "/obj/structure/closet/crate" - containername = "Arts and Crafts crate" - group = "Operations" - -/datum/supply_packs/randomised/contraband - num_contained = 6 +/datum/supply_packs/misc/randomised/contraband + num_contained = 5 contains = list(/obj/item/weapon/storage/pill_bottle/zoom, /obj/item/weapon/storage/pill_bottle/happy, /obj/item/weapon/storage/pill_bottle/random_drug_bottle, + /obj/item/weapon/contraband/poster, /obj/item/weapon/storage/fancy/cigarettes/dromedaryco, - /obj/item/weapon/storage/fancy/cigarettes/cigpack_shadyjims, - /obj/item/weapon/grenade/smokebomb, - /obj/item/clothing/mask/cigarette/cigar/cohiba, - /obj/item/weapon/reagent_containers/food/drinks/cans/ale, - /obj/item/weapon/reagent_containers/food/drinks/bottle/patron, - /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, - /obj/item/weapon/lipstick/random) - - name = "Contraband crate" + /obj/item/weapon/storage/fancy/cigarettes/cigpack_shadyjims) + name = "Contraband Crate" cost = 30 - containertype = /obj/structure/closet/crate - containername = "Unlabeled crate" + containername = "crate" //let's keep it subtle, eh? contraband = 1 - group = "Operations" -/datum/supply_packs/boxes - name = "Empty Box supplies" - contains = list(/obj/item/weapon/storage/box, - /obj/item/weapon/storage/box, - /obj/item/weapon/storage/box, - /obj/item/weapon/storage/box, - /obj/item/weapon/storage/box, - /obj/item/weapon/storage/box, - /obj/item/weapon/storage/box, - /obj/item/weapon/storage/box, - /obj/item/weapon/storage/box, - /obj/item/weapon/storage/box) - cost = 10 - containertype = "/obj/structure/closet/crate" - containername = "Empty Box crate" - group = "Operations" - -/datum/supply_packs/surgery - name = "Surgery crate" - contains = list(/obj/item/weapon/cautery, - /obj/item/weapon/surgicaldrill, - /obj/item/clothing/mask/breath/medical, - /obj/item/weapon/tank/anesthetic, - /obj/item/weapon/FixOVein, - /obj/item/weapon/hemostat, - /obj/item/weapon/scalpel, - /obj/item/weapon/bonegel, - /obj/item/weapon/retractor, - /obj/item/weapon/bonesetter, - /obj/item/weapon/circular_saw) - cost = 25 - containertype = "/obj/structure/closet/crate/secure" - containername = "Surgery crate" - access = access_medical - group = "Medical / Science" - -/datum/supply_packs/sterile - name = "Sterile equipment crate" - contains = list(/obj/item/clothing/under/rank/medical/green, - /obj/item/clothing/under/rank/medical/green, - /obj/item/weapon/storage/box/masks, - /obj/item/weapon/storage/box/gloves) - cost = 15 - containertype = "/obj/structure/closet/crate" - containername = "Sterile equipment crate" - group = "Medical / Science" - -/datum/supply_packs/randomised/pizza - num_contained = 5 - contains = list(/obj/item/pizzabox/margherita, - /obj/item/pizzabox/mushroom, - /obj/item/pizzabox/meat, - /obj/item/pizzabox/vegetable) - name = "Surprise pack of five dozen pizzas" - cost = 15 - containertype = /obj/structure/closet/crate/freezer - containername = "Pizza crate" - group = "Hospitality" - -/datum/supply_packs/foodcart - name = "Food Cart crate" - contains = list(/obj/structure/foodcart) - cost = 10 - containertype = /obj/structure/largecrate - containername = "food cart crate" - group = "Hospitality" - -/datum/supply_packs/formal_wear - contains = list(/obj/item/clothing/head/that, - /obj/item/clothing/suit/storage/lawyer/bluejacket, - /obj/item/clothing/suit/storage/lawyer/purpjacket, - /obj/item/clothing/under/suit_jacket, - /obj/item/clothing/under/suit_jacket/female, - /obj/item/clothing/under/suit_jacket/really_black, - /obj/item/clothing/under/suit_jacket/red, - /obj/item/clothing/shoes/black, - /obj/item/clothing/shoes/black, - /obj/item/clothing/suit/wcoat) - name = "Formalwear closet" - cost = 30 - containertype = /obj/structure/closet - containername = "Formalwear for the best occasions." - group = "Operations" -/* -/datum/supply_packs/rust_injector - contains = list(/obj/machinery/power/rust_fuel_injector) - name = "RUST fuel injector" - cost = 50 - containertype = /obj/structure/closet/crate/secure/large - containername = "RUST injector crate" - group = "Engineering" - access = access_engine -/datum/supply_packs/rust_compressor - contains = list(/obj/item/weapon/module/rust_fuel_compressor) - name = "RUST fuel compressor circuitry" - cost = 60 - containertype = /obj/structure/closet/crate/secure - containername = "RUST fuel compressor circuitry" - group = "Engineering" - access = access_engine -/datum/supply_packs/rust_assembly_port - contains = list(/obj/item/weapon/module/rust_fuel_port) - name = "RUST fuel assembly port circuitry" - cost = 40 - containertype = /obj/structure/closet/crate/secure - containername = "RUST fuel assembly port circuitry" - group = "Engineering" - access = access_engine -/datum/supply_packs/rust_core - contains = list(/obj/machinery/power/rust_core) - name = "RUST Tokamak Core" - cost = 75 - containertype = /obj/structure/closet/crate/secure/large - containername = "RUST tokamak crate" - group = "Engineering" - access = access_engine -*/ -/datum/supply_packs/shield_gen - contains = list(/obj/item/weapon/circuitboard/shield_gen) - name = "Experimental shield generator circuitry" - cost = 50 - containertype = /obj/structure/closet/crate/secure - containername = "Experimental shield generator" - group = "Engineering" - access = access_ce - -/datum/supply_packs/shield_cap - contains = list(/obj/item/weapon/circuitboard/shield_cap) - name = "Experimental shield capacitor circuitry" - cost = 50 - containertype = /obj/structure/closet/crate/secure - containername = "Experimental shield capacitor" - group = "Engineering" - access = access_ce - -/datum/supply_packs/eftpos - contains = list(/obj/item/device/eftpos) - name = "EFTPOS scanner" - cost = 10 - containertype = /obj/structure/closet/crate - containername = "EFTPOS crate" - group = "Operations" - -/datum/supply_packs/teg - contains = list(/obj/machinery/power/generator) - name = "Mark I Thermoelectric Generator" - cost = 75 - containertype = /obj/structure/closet/crate/secure/large - containername = "Mk1 TEG crate" - group = "Engineering" - access = access_engine - -/datum/supply_packs/circulator - contains = list(/obj/machinery/atmospherics/binary/circulator) - name = "Binary atmospheric circulator" - cost = 60 - containertype = /obj/structure/closet/crate/secure/large - containername = "Atmospheric circulator crate" - group = "Engineering" - access = access_engine - -/datum/supply_packs/bee_keeper - name = "Beekeeping Crate" - contains = list(/obj/item/beezeez, - /obj/item/beezeez, - /obj/item/weapon/bee_net, - /obj/item/apiary, - /obj/item/queen_bee, - /obj/item/queen_bee, - /obj/item/queen_bee) - cost = 20 - containertype = /obj/structure/closet/crate/hydroponics - containername = "Beekeeping crate" - access = access_hydroponics - group = "Hydroponics" - -/datum/supply_packs/misc/lasertag - name = "Laser Tag Crate" - contains = list(/obj/item/weapon/gun/energy/laser/redtag, - /obj/item/weapon/gun/energy/laser/redtag, - /obj/item/weapon/gun/energy/laser/redtag, - /obj/item/weapon/gun/energy/laser/bluetag, - /obj/item/weapon/gun/energy/laser/bluetag, - /obj/item/weapon/gun/energy/laser/bluetag, - /obj/item/clothing/suit/redtag, - /obj/item/clothing/suit/redtag, - /obj/item/clothing/suit/redtag, - /obj/item/clothing/suit/bluetag, - /obj/item/clothing/suit/bluetag, - /obj/item/clothing/suit/bluetag, - /obj/item/clothing/head/helmet/redtaghelm, - /obj/item/clothing/head/helmet/bluetaghelm) - cost = 15 - containertype = /obj/structure/closet/crate - containername = "laser tag crate" - group = "Operations" - -/datum/supply_packs/vending - name = "Bartending Supply Crate" - contains = list(/obj/item/weapon/vending_refill/boozeomat, - /obj/item/weapon/vending_refill/boozeomat, - /obj/item/weapon/vending_refill/boozeomat, - /obj/item/weapon/vending_refill/coffee, - /obj/item/weapon/vending_refill/coffee, - /obj/item/weapon/vending_refill/coffee) - cost = 15 - containertype = /obj/structure/closet/crate - containername = "bartending supply crate" - group = "Operations" - -/datum/supply_packs/vending/snack - name = "Snack Supply Crate" - contains = list(/obj/item/weapon/vending_refill/snack, - /obj/item/weapon/vending_refill/snack, - /obj/item/weapon/vending_refill/snack) - cost = 15 - containertype = /obj/structure/closet/crate - containername = "snacks supply crate" - group = "Operations" - -/datum/supply_packs/vending/cola - name = "Softdrinks Supply Crate" - contains = list(/obj/item/weapon/vending_refill/cola, - /obj/item/weapon/vending_refill/cola, - /obj/item/weapon/vending_refill/cola) - cost = 15 - containertype = /obj/structure/closet/crate - containername = "softdrinks supply crate" - group = "Operations" - -/datum/supply_packs/vending/cigarette - name = "Cigarette Supply Crate" - contains = list(/obj/item/weapon/vending_refill/cigarette, - /obj/item/weapon/vending_refill/cigarette, - /obj/item/weapon/vending_refill/cigarette) - cost = 15 - containertype = /obj/structure/closet/crate - containername = "cigarette supply crate" - group = "Operations" - -/datum/supply_packs/autodrobe - name = "Autodrobe Supply crate" +/datum/supply_packs/misc/autodrobe + name = "Autodrobe Supply Crate" contains = list(/obj/item/weapon/vending_refill/autodrobe, - /obj/item/weapon/vending_refill/autodrobe, /obj/item/weapon/vending_refill/autodrobe) cost = 15 - containertype = /obj/structure/closet/crate containername = "autodrobe supply crate" - group = "Operations" -/datum/supply_packs/clothingvendor - name = "Clothing Vendor Supply crate" - contains = list(/obj/item/weapon/vending_refill/hatdispenser, - /obj/item/weapon/vending_refill/hatdispenser, - /obj/item/weapon/vending_refill/hatdispenser, - /obj/item/weapon/vending_refill/suitdispenser, - /obj/item/weapon/vending_refill/suitdispenser, - /obj/item/weapon/vending_refill/suitdispenser, - /obj/item/weapon/vending_refill/shoedispenser, - /obj/item/weapon/vending_refill/shoedispenser, - /obj/item/weapon/vending_refill/shoedispenser) - cost = 30 - containertype = /obj/structure/closet/crate - containername = "clothing vendor supply crate" - group = "Operations" - -/datum/supply_packs/mafia - name = "Mafia Supply crate" - contains = list(/obj/item/clothing/suit/browntrenchcoat =1,/obj/item/clothing/suit/blacktrenchcoat =1,/obj/item/clothing/head/fedora/whitefedora =1, - /obj/item/clothing/head/fedora/brownfedora =1,/obj/item/clothing/head/fedora =1,/obj/item/clothing/under/flappers =1,/obj/item/clothing/under/mafia =1,/obj/item/clothing/under/mafia/vest =1,/obj/item/clothing/under/mafia/white =1, - /obj/item/clothing/under/mafia/sue =1,/obj/item/clothing/under/mafia/tan =1, /obj/item/toy/crossbow/tommygun =2) - cost = 15 - containertype = /obj/structure/closet/crate - containername = "mafia supply crate" - group = "Operations" - -/datum/supply_packs/fabric - name = "Fabric crate" - contains = list(/obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric) - cost = 30 - containertype = /obj/structure/closet/crate - containername = "Fabric crate" - group = "Operations" \ No newline at end of file +/datum/supply_packs/misc/formalwear //This is a very classy crate. + name = "Formal-wear Crate" + contains = list(/obj/item/clothing/under/blacktango, + /obj/item/clothing/under/assistantformal, + /obj/item/clothing/under/assistantformal, + /obj/item/clothing/under/lawyer/bluesuit, + /obj/item/clothing/suit/storage/lawyer/bluejacket, + /obj/item/clothing/under/lawyer/purpsuit, + /obj/item/clothing/suit/storage/lawyer/purpjacket, + /obj/item/clothing/under/lawyer/black, + /obj/item/clothing/suit/storage/lawyer/blackjacket, + /obj/item/clothing/accessory/waistcoat, + /obj/item/clothing/accessory/blue, + /obj/item/clothing/accessory/red, + /obj/item/clothing/accessory/black, + /obj/item/clothing/head/bowlerhat, + /obj/item/clothing/head/fedora, + /obj/item/clothing/head/flatcap, + /obj/item/clothing/head/beret, + /obj/item/clothing/head/that, + /obj/item/clothing/shoes/laceup, + /obj/item/clothing/shoes/laceup, + /obj/item/clothing/shoes/laceup, + /obj/item/clothing/under/suit_jacket/charcoal, + /obj/item/clothing/under/suit_jacket/navy, + /obj/item/clothing/under/suit_jacket/burgundy, + /obj/item/clothing/under/suit_jacket/checkered, + /obj/item/clothing/under/suit_jacket/tan, + /obj/item/weapon/lipstick/random) + cost = 30 //Lots of very expensive items. You gotta pay up to look good! + containername = "formal-wear crate" diff --git a/code/datums/wires/vending.dm b/code/datums/wires/vending.dm index c0c76cd89ae..574c7961e09 100644 --- a/code/datums/wires/vending.dm +++ b/code/datums/wires/vending.dm @@ -1,3 +1,5 @@ +#define CAT_HIDDEN 2 // Also in code/game/machinery/vending.dm + /datum/wires/vending holder_type = /obj/machinery/vending wire_count = 4 @@ -17,17 +19,12 @@ var/const/VENDING_WIRE_IDSCAN = 8 return 1 return 0 -/datum/wires/vending/Interact(var/mob/living/user) - if(CanUse(user)) - var/obj/machinery/vending/V = holder - V.attack_hand(user) - /datum/wires/vending/GetInteractWindow() var/obj/machinery/vending/V = holder . += ..() . += "
The orange light is [V.seconds_electrified ? "on" : "off"].
" . += "The red light is [V.shoot_inventory ? "off" : "blinking"].
" - . += "The green light is [V.extended_inventory ? "on" : "off"].
" + . += "The green light is [(V.categories & CAT_HIDDEN) ? "on" : "off"].
" . += "A [V.scan_id ? "purple" : "yellow"] light is on.
" /datum/wires/vending/UpdatePulsed(var/index) @@ -36,7 +33,7 @@ var/const/VENDING_WIRE_IDSCAN = 8 if(VENDING_WIRE_THROW) V.shoot_inventory = !V.shoot_inventory if(VENDING_WIRE_CONTRABAND) - V.extended_inventory = !V.extended_inventory + V.categories ^= CAT_HIDDEN if(VENDING_WIRE_ELECTRIFY) V.seconds_electrified = 30 if(VENDING_WIRE_IDSCAN) @@ -48,7 +45,7 @@ var/const/VENDING_WIRE_IDSCAN = 8 if(VENDING_WIRE_THROW) V.shoot_inventory = !mended if(VENDING_WIRE_CONTRABAND) - V.extended_inventory = 0 + V.categories &= ~CAT_HIDDEN if(VENDING_WIRE_ELECTRIFY) if(mended) V.seconds_electrified = 0 diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm index c3d07013d14..04c3541dc7e 100644 --- a/code/datums/wires/wires.dm +++ b/code/datums/wires/wires.dm @@ -72,8 +72,11 @@ var/list/wireColours = list("red", "blue", "green", "black", "orange", "brown", html = GetInteractWindow() if(html) user.set_machine(holder) - //user << browse(html, "window=wires;size=[window_x]x[window_y]") - //onclose(user, "wires") + else + user.unset_machine() + // No content means no window. + user << browse(null, "window=wires") + return var/datum/browser/popup = new(user, "wires", holder.name, window_x, window_y) popup.set_content(html) popup.set_title_image(user.browse_rsc_icon(holder.icon, holder.icon_state)) diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm new file mode 100644 index 00000000000..7cb7799a372 --- /dev/null +++ b/code/defines/procs/announce.dm @@ -0,0 +1,121 @@ +/var/datum/announcement/priority/priority_announcement = new(do_log = 0) +/var/datum/announcement/priority/command/command_announcement = new(do_log = 0, do_newscast = 1) + +/datum/announcement + var/title = "Attention" + var/announcer = "" + var/log = 0 + var/sound + var/newscast = 0 + var/channel_name = "Station Announcements" + var/announcement_type = "Announcement" + var/disable_newscasts = 1 // Bay also adds announcements to their newscaster system - set this to 0 to also use that system + +/datum/announcement/New(var/do_log = 0, var/new_sound = null, var/do_newscast = 0) + sound = new_sound + log = do_log + newscast = do_newscast + +/datum/announcement/priority/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0) + ..(do_log, new_sound, do_newscast) + title = "Priority Announcement" + announcement_type = "Priority Announcement" + +/datum/announcement/priority/command/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0) + ..(do_log, new_sound, do_newscast) + title = "[command_name()] Update" + announcement_type = "[command_name()] Update" + +/datum/announcement/priority/security/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0) + ..(do_log, new_sound, do_newscast) + title = "Security Announcement" + announcement_type = "Security Announcement" + +/datum/announcement/proc/Announce(var/message as text, var/new_title = "", var/new_sound = null, var/do_newscast = newscast) + if(!message) + return + var/tmp/message_title = new_title ? new_title : title + var/tmp/message_sound = new_sound ? sound(new_sound) : sound + + message = trim_strip_html_properly(message) + message_title = html_encode(message_title) + + Message(message, message_title) + if(do_newscast) + NewsCast(message, message_title) + Sound(message_sound) + Log(message, message_title) + +datum/announcement/proc/Message(message as text, message_title as text) + for(var/mob/M in player_list) + if(!istype(M,/mob/new_player) && !isdeaf(M)) + M << "

[title]

" + M << "[message]" + if (announcer) + M << " -[html_encode(announcer)]" + +datum/announcement/minor/Message(message as text, message_title as text) + world << "[message]" + +datum/announcement/priority/Message(message as text, message_title as text) + world << "

[message_title]

" + world << "[message]" + if(announcer) + world << " -[html_encode(announcer)]" + world << "
" + +datum/announcement/priority/command/Message(message as text, message_title as text) + var/command + command += "

[command_name()] Update

" + if (message_title) + command += "

[message_title]

" + + command += "
[message]
" + command += "
" + for(var/mob/M in player_list) + if(!istype(M,/mob/new_player) && !isdeaf(M)) + M << command + +datum/announcement/priority/security/Message(message as text, message_title as text) + world << "[message_title]" + world << "[message]" + +datum/announcement/proc/NewsCast(message as text, message_title as text) + if(disable_newscasts) + return + if(!newscast) + return + + var/datum/news_announcement/news = new + news.channel_name = channel_name + news.author = announcer + news.message = message + news.message_type = announcement_type + news.can_be_redacted = 0 + announce_newscaster_news(news) + +datum/announcement/proc/PlaySound(var/message_sound) + if(!message_sound) + return + for(var/mob/M in player_list) + if(!istype(M,/mob/new_player) && !isdeaf(M)) + M << message_sound + +datum/announcement/proc/Sound(var/message_sound) + PlaySound(message_sound) + +datum/announcement/priority/Sound(var/message_sound) + if(sound) + world << sound + +datum/announcement/priority/command/Sound(var/message_sound) + PlaySound(message_sound) + +datum/announcement/proc/Log(message as text, message_title as text) + if(log) + log_say("[key_name(usr)] has made \a [announcement_type]: [message_title] - [message] - [announcer]") + message_admins("[key_name_admin(usr)] has made \a [announcement_type].", 1) + +/proc/GetNameAndAssignmentFromId(var/obj/item/weapon/card/id/I) + // Format currently matches that of newscaster feeds: Registered Name (Assigned Rank) + return I.assignment ? "[I.registered_name] ([I.assignment])" : I.registered_name diff --git a/code/defines/procs/captain_announce.dm b/code/defines/procs/captain_announce.dm deleted file mode 100644 index 9b91705ea56..00000000000 --- a/code/defines/procs/captain_announce.dm +++ /dev/null @@ -1,5 +0,0 @@ -/proc/captain_announce(var/text) - world << "

Priority Announcement

" - world << "[html_encode(text)]" - world << "
" - diff --git a/code/defines/procs/command_alert.dm b/code/defines/procs/command_alert.dm deleted file mode 100644 index 6545307fa1a..00000000000 --- a/code/defines/procs/command_alert.dm +++ /dev/null @@ -1,11 +0,0 @@ -/proc/command_alert(var/text, var/title = "") - var/command - command += "

[command_name()] Update

" - if (title && length(title) > 0) - command += "

[html_encode(title)]

" - - command += "
[html_encode(text)]
" - command += "
" - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << command diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 0ee9267ca01..43c52ec018c 100644 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -70,7 +70,7 @@ var/list/teleportlocs = list() var/list/turfs = get_area_turfs(AR.type) if(turfs.len) var/turf/picked = pick(turfs) - if (picked.z == 1) + if ((picked.z in config.station_levels)) teleportlocs += AR.name teleportlocs[AR.name] = AR @@ -83,13 +83,13 @@ var/list/ghostteleportlocs = list() /hook/startup/proc/setupGhostTeleportLocs() for(var/area/AR in world) if(ghostteleportlocs.Find(AR.name)) continue - if(istype(AR, /area/turret_protected/aisat) || istype(AR, /area/derelict) || istype(AR, /area/tdome)) + if(istype(AR, /area/tdome)) ghostteleportlocs += AR.name ghostteleportlocs[AR.name] = AR var/list/turfs = get_area_turfs(AR.type) if(turfs.len) var/turf/picked = pick(turfs) - if (picked.z == 1 || picked.z == 5 || picked.z == 3) + if ((picked.z in config.player_levels)) ghostteleportlocs += AR.name ghostteleportlocs[AR.name] = AR diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 9688d242dc2..51eec5190f3 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -242,6 +242,8 @@ its easier to just keep the beam vertical. /atom/proc/blob_act() return +/atom/proc/emag_act() + return /atom/proc/hitby(atom/movable/AM as mob|obj) if (density) diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index 46482dc9ff6..5eb2ad4ecd6 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -26,7 +26,7 @@ if(!checking) checking = 1 user << "The device is now checking for possible candidates." - get_candidate_answer(user, get_candidates(BE_OPERATIVE,,"operative","Syndicate")) + get_candidate_answer(user, get_candidates(BE_OPERATIVE)) else user << "The device is already checking for possible candidates." return diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm index ccbff9b326d..bbfafa046f1 100644 --- a/code/game/gamemodes/blob/blob.dm +++ b/code/game/gamemodes/blob/blob.dm @@ -58,7 +58,7 @@ var/list/blob_nodes = list() /datum/game_mode/blob/proc/get_nuke_code() var/nukecode = "ERROR" for(var/obj/machinery/nuclearbomb/bomb in world) - if(bomb && bomb.r_code && bomb.z == 1) + if(bomb && bomb.r_code && (bomb.z in config.station_levels)) nukecode = bomb.r_code return nukecode @@ -92,7 +92,7 @@ var/list/blob_nodes = list() if(directory[ckey(blob.key)]) blob_client = directory[ckey(blob.key)] location = get_turf(C) - if(location.z != 1 || istype(location, /turf/space)) + if(!(location.z in config.station_levels) || istype(location, /turf/space)) location = null C.gib() @@ -175,17 +175,14 @@ var/list/blob_nodes = list() return if (1) - command_alert("Nanotrasen has issued a directive 7-10 for [station_name()]. The station is to be considered quarantined.", "Biohazard Alert") - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << sound('sound/AI/blob_confirmed.ogg') + command_announcement.Announce("Nanotrasen has issued a directive 7-10 for [station_name()]. The station is to be considered quarantined.", "Biohazard Alert", new_sound = 'sound/AI/blob_confirmed.ogg') return if (2) - command_alert("The biohazard has grown out of control and will soon reach critical mass. Activate the nuclear failsafe to maintain quarantine. The Nuclear Authentication Code is [get_nuke_code()] ", "Biohazard Alert") + command_announcement.Announce("The biohazard has grown out of control and will soon reach critical mass. Activate the nuclear failsafe to maintain quarantine. The Nuclear Authentication Code is [get_nuke_code()] ", "Biohazard Alert", new_sound = 'sound/AI/blob_confirmed.ogg') set_security_level("gamma") var/obj/machinery/door/airlock/vault/V = locate(/obj/machinery/door/airlock/vault) in world - if(V && V.z == 1) + if(V && (V.z in config.station_levels)) V.locked = 0 V.update_icon() send_intercept(2) diff --git a/code/game/gamemodes/blob/blob_finish.dm b/code/game/gamemodes/blob/blob_finish.dm index 868cd62a5f6..1c3e57d2e00 100644 --- a/code/game/gamemodes/blob/blob_finish.dm +++ b/code/game/gamemodes/blob/blob_finish.dm @@ -62,7 +62,7 @@ datum/game_mode/proc/auto_declare_completion_blob() if (istype(T, /turf/space)) numSpace += 1 else if(istype(T, /turf)) - if (M.z!=1) + if (!(M.z in config.station_levels)) numOffStation += 1 else numAlive += 1 diff --git a/code/game/gamemodes/blob/blob_report.dm b/code/game/gamemodes/blob/blob_report.dm index 4b8dd6bf31d..20feb9044cb 100644 --- a/code/game/gamemodes/blob/blob_report.dm +++ b/code/game/gamemodes/blob/blob_report.dm @@ -61,7 +61,7 @@ proc/count() for(var/turf/T in world) - if(T.z != 1) + if(!(T.z in config.station_levels)) continue if(istype(T,/turf/simulated/floor)) @@ -83,7 +83,7 @@ src.r_wall += 1 for(var/obj/O in world) - if(O.z != 1) + if(!(O.z in config.station_levels)) continue if(istype(O, /obj/structure/window)) diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm index fb5fd71928b..2dd69860b14 100644 --- a/code/game/gamemodes/blob/blobs/core.dm +++ b/code/game/gamemodes/blob/blobs/core.dm @@ -72,7 +72,7 @@ var/list/candidates = list() if(!new_overmind) - candidates = get_candidates(BE_BLOB,,"blob","Syndicate") + candidates = get_candidates(BE_BLOB) if(candidates.len) C = pick(candidates) else diff --git a/code/game/gamemodes/borer/borer.dm b/code/game/gamemodes/borer/borer.dm index 7ec3801be02..f5948f3a683 100644 --- a/code/game/gamemodes/borer/borer.dm +++ b/code/game/gamemodes/borer/borer.dm @@ -39,7 +39,7 @@ return 0 // not enough candidates for borer for(var/obj/machinery/atmospherics/unary/vent_pump/v in world) - if(!v.welded && v.z == STATION_Z) // No more spawning in atmos. Assuming the mappers did their jobs, anyway. + if(!v.welded && (v.z in config.station_levels)) found_vents.Add(v) // for each 2 possible borers, add one borer and one host diff --git a/code/game/gamemodes/epidemic/epidemic.dm b/code/game/gamemodes/epidemic/epidemic.dm index b541e9b1b03..e64100e2a12 100644 --- a/code/game/gamemodes/epidemic/epidemic.dm +++ b/code/game/gamemodes/epidemic/epidemic.dm @@ -149,7 +149,7 @@ announce_to_kill_crew() stage = 2 else if(stage == 2 && cruiser_seconds() <= 60 * 5) - command_alert("Inbound cruiser detected on collision course. Scans indicate the ship to be armed and ready to fire. Estimated time of arrival: 5 minutes.", "[station_name()] Early Warning System") + command_announcement.Announce("Inbound cruiser detected on collision course. Scans indicate the ship to be armed and ready to fire. Estimated time of arrival: 5 minutes.", "[station_name()] Early Warning System") stage = 3 else if(stage == 3 && cruiser_seconds() <= 0) crew_lose() diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index 6938162cb98..07794377d04 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -30,10 +30,7 @@ eventNumbersToPickFrom += 3 switch(pick(eventNumbersToPickFrom)) if(1) - command_alert("Meteors have been detected on collision course with the station.", "Meteor Alert") - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << sound('sound/AI/meteors.ogg') + command_announcement.Announce("Meteors have been detected on collision course with the station.", "Meteor Alert", new_sound = 'sound/AI/meteors.ogg') spawn(100) meteor_wave() spawn_meteors() @@ -42,22 +39,18 @@ spawn_meteors() if(2) - command_alert("Gravitational anomalies detected on the station. There is no additional data.", "Anomaly Alert") - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << sound('sound/AI/granomalies.ogg') + command_announcement.Announce("Gravitational anomalies detected on the station. There is no additional data.", "Anomaly Alert", new_sound = 'sound/AI/granomalies.ogg') var/turf/T = pick(blobstart) var/obj/effect/bhole/bh = new /obj/effect/bhole( T.loc, 30 ) spawn(rand(50, 300)) del(bh) /* if(3) //Leaving the code in so someone can try and delag it, but this event can no longer occur randomly, per SoS's request. --NEO - command_alert("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert") - world << sound('sound/AI/spanomalies.ogg') + command_announcement.Announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", new_sound = 'sound/AI/spanomalies.ogg') var/list/turfs = new var/turf/picked for(var/turf/simulated/floor/T in world) - if(T.z == 1) + if((T.z in config.station_levels)) turfs += T for(var/turf/simulated/floor/T in turfs) if(prob(20)) @@ -107,8 +100,7 @@ /* /proc/viral_outbreak(var/virus = null) -// command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert") -// world << sound('sound/AI/outbreak7.ogg') +// command_announcement.Announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg') var/virus_type if(!virus) virus_type = pick(/datum/disease/dnaspread,/datum/disease/advance/flu,/datum/disease/advance/cold,/datum/disease/brainrot,/datum/disease/magnitis,/datum/disease/pierrot_throat) @@ -140,7 +132,7 @@ var/turf/T = get_turf(H) if(!T) continue - if(T.z != 1) + if(!(T.z in config.station_levels)) continue for(var/datum/disease/D in H.viruses) foundAlready = 1 @@ -167,21 +159,18 @@ H.viruses += D break spawn(rand(1500, 3000)) //Delayed announcements to keep the crew on their toes. - command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert") - for(var/mob/M in player_list) - M << sound('sound/AI/outbreak7.ogg') + command_announcement.Announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg') */ /proc/alien_infestation(var/spawncount = 1) // -- TLE - //command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert") - //world << sound('sound/AI/aliens.ogg') + //command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') var/list/vents = list() for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in machines) - if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network) + if((temp_vent.loc.z in config.station_levels) && !temp_vent.welded && temp_vent.network) if(temp_vent.network.normal_members.len > 50) // Stops Aliens getting stuck in small networks. See: Security, Virology vents += temp_vent - var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET,"alien","Syndicate") + var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET) if(prob(40)) spawncount++ //sometimes, have two larvae spawn instead of one while((spawncount >= 1) && vents.len && candidates.len) @@ -197,7 +186,7 @@ spawncount-- spawn(rand(5000, 6000)) //Delayed announcements to keep the crew on their toes. - command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert") + command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') for(var/mob/M in player_list) M << sound('sound/AI/aliens.ogg') @@ -205,7 +194,7 @@ /* // Haha, this is way too laggy. I'll keep the prison break though. for(var/obj/machinery/light/L in world) - if(L.z != 1) continue + if(!(L.z in config.station_levels)) continue L.flicker(50) sleep(100) @@ -214,9 +203,11 @@ var/turf/T = get_turf(H) if(!T) continue - if(T.z != 1) + if(!(T.z in config.station_levels)) continue if(istype(H,/mob/living/carbon/human)) + if(H.species.flags & IS_SYNTHETIC) + return H.apply_effect((rand(15,75)),IRRADIATE,0) if (prob(5)) H.apply_effect((rand(90,150)),IRRADIATE,0) @@ -231,13 +222,11 @@ var/turf/T = get_turf(M) if(!T) continue - if(T.z != 1) + if(!(T.z in config.station_levels)) continue M.apply_effect((rand(15,75)),IRRADIATE,0) sleep(100) - command_alert("High levels of radiation detected near the station. Please report to the Med-bay if you feel strange.", "Anomaly Alert") - for(var/mob/M in player_list) - M << sound('sound/AI/radiation.ogg') + command_announcement.Announce("High levels of radiation detected near the station. Please report to the Med-bay if you feel strange.", "Anomaly Alert", new_sound = 'sound/AI/radiation.ogg') @@ -276,9 +265,9 @@ temp_timer.releasetime = 1 sleep(150) - command_alert("Gr3y.T1d3 virus detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert") + command_announcement.Announce("Gr3y.T1d3 virus detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert") else - world.log << "ERROR: Could not initate grey-tide. Unable find prison or brig area." + world.log << "ERROR: Could not initate grey-tide virus. Unable find prison or brig area." /proc/carp_migration() // -- Darem for(var/obj/effect/landmark/C in landmarks_list) @@ -286,13 +275,11 @@ new /mob/living/simple_animal/hostile/carp(C.loc) //sleep(100) spawn(rand(300, 600)) //Delayed announcements to keep the crew on their toes. - command_alert("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert") - for(var/mob/M in player_list) - M << sound('sound/AI/commandreport.ogg') + command_announcement.Announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert", new_sound = 'sound/AI/commandreport.ogg') /proc/lightsout(isEvent = 0, lightsoutAmount = 1,lightsoutRange = 25) //leave lightsoutAmount as 0 to break ALL lights if(isEvent) - command_alert("An Electrical storm has been detected in your area, please repair potential electronic overloads.","Electrical Storm Alert") + command_announcement.Announce("An Electrical storm has been detected in your area, please repair potential electronic overloads.","Electrical Storm Alert") if(lightsoutAmount) var/list/epicentreList = list() @@ -442,21 +429,21 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is spawn(0) world << "Started processing APCs" for (var/obj/machinery/power/apc/APC in world) - if(APC.z == 1) + if((APC.z in config.station_levels)) APC.ion_act() apcnum++ world << "Finished processing APCs. Processed: [apcnum]" spawn(0) world << "Started processing SMES" for (var/obj/machinery/power/smes/SMES in world) - if(SMES.z == 1) + if((SMES.z in config.station_levels)) SMES.ion_act() smesnum++ world << "Finished processing SMES. Processed: [smesnum]" spawn(0) world << "Started processing AIRLOCKS" for (var/obj/machinery/door/airlock/D in world) - if(D.z == 1) + if((D.z in config.station_levels)) //if(length(D.req_access) > 0 && !(12 in D.req_access)) //not counting general access and maintenance airlocks airlocknum++ spawn(0) @@ -465,7 +452,7 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is spawn(0) world << "Started processing FIREDOORS" for (var/obj/machinery/door/firedoor/D in world) - if(D.z == 1) + if((D.z in config.station_levels)) firedoornum++; spawn(0) D.ion_act() diff --git a/code/game/gamemodes/events/PortalStorm.dm b/code/game/gamemodes/events/PortalStorm.dm index 890755d6b8e..1143a2d2e88 100644 --- a/code/game/gamemodes/events/PortalStorm.dm +++ b/code/game/gamemodes/events/PortalStorm.dm @@ -1,18 +1,18 @@ /datum/event/portalstorm Announce() - command_alert("Subspace disruption detected around the vessel", "Anomaly Alert") + command_announcement.Announce("Subspace disruption detected around the vessel", "Anomaly Alert") LongTerm() var/list/turfs = list( ) var/turf/picked for(var/turf/T in world) - if(T.z < 5 && istype(T,/turf/simulated/floor)) + if((T.z in config.player_levels) && istype(T,/turf/simulated/floor)) turfs += T for(var/turf/T in world) - if(prob(10) && T.z < 5 && istype(T,/turf/simulated/floor)) + if(prob(10) && (T.z in config.player_levels) && istype(T,/turf/simulated/floor)) spawn(50+rand(0,3000)) picked = pick(turfs) var/obj/portal/P = new /obj/portal( T ) diff --git a/code/game/gamemodes/events/VirusEpidemic.dm b/code/game/gamemodes/events/VirusEpidemic.dm index 54b9760a2f7..f6e005cef10 100644 --- a/code/game/gamemodes/events/VirusEpidemic.dm +++ b/code/game/gamemodes/events/VirusEpidemic.dm @@ -13,11 +13,11 @@ if(prob(100)) // no lethal diseases outside virus mode! infect_mob_random_lesser(H) if(prob(20))//don't want people to know that the virus alert = greater virus - command_alert("Probable outbreak of level [rand(1,6)] viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Virus Alert") + command_announcement.Announce("Probable outbreak of level [rand(1,6)] viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Virus Alert") else infect_mob_random_greater(H) if(prob(80)) - command_alert("Probable outbreak of level [rand(2,9)] viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Virus Alert") + command_announcement.Announce("Probable outbreak of level [rand(2,9)] viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Virus Alert") break //overall virus alert happens 26% of the time, might need to be higher else @@ -73,8 +73,7 @@ H.viruses += D break spawn(rand(3000, 6000)) //Delayed announcements to keep the crew on their toes. - command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert") - world << sound('sound/AI/outbreak7.ogg') + command_announcement.Announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg') Tick() ActiveFor = Lifetime //killme diff --git a/code/game/gamemodes/events/clang.dm b/code/game/gamemodes/events/clang.dm index c74da4010e9..6ba085f98e5 100644 --- a/code/game/gamemodes/events/clang.dm +++ b/code/game/gamemodes/events/clang.dm @@ -78,7 +78,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 walk_towards(immrod, end,1) sleep(1) while (immrod) - if (immrod.z != 1) + if ((immrod.z in config.station_levels)) immrod.z = 1 if(immrod.loc == end) del(immrod) @@ -86,4 +86,4 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 for(var/obj/effect/immovablerod/imm in world) return sleep(50) - command_alert("What the fuck was that?!", "General Alert") \ No newline at end of file + command_announcement.Announce("What the fuck was that?!", "General Alert") \ No newline at end of file diff --git a/code/game/gamemodes/events/holidays/Christmas.dm b/code/game/gamemodes/events/holidays/Christmas.dm index 562c34dfec8..b1f9faf9a35 100644 --- a/code/game/gamemodes/events/holidays/Christmas.dm +++ b/code/game/gamemodes/events/holidays/Christmas.dm @@ -1,6 +1,6 @@ /proc/Christmas_Game_Start() for(var/obj/structure/flora/tree/pine/xmas in world) - if(xmas.z != 1) continue + if(!(xmas.z in config.station_levels)) continue for(var/turf/simulated/floor/T in orange(1,xmas)) for(var/i=1,i<=rand(1,5),i++) new /obj/item/weapon/a_gift(T) diff --git a/code/game/gamemodes/events/holidays/Holidays.dm b/code/game/gamemodes/events/holidays/Holidays.dm index 56077a43dce..53d6e0171f7 100644 --- a/code/game/gamemodes/events/holidays/Holidays.dm +++ b/code/game/gamemodes/events/holidays/Holidays.dm @@ -171,7 +171,7 @@ var/global/Holiday = null */ /* var/list/obj/containers = list() for(var/obj/item/weapon/storage/S in world) - if(S.z != 1) continue + if(!(S.z in config.station_levels)) continue containers += S message_admins("\blue DEBUG: Event: Egg spawned at [Egg.loc] ([Egg.x],[Egg.y],[Egg.z])")*/ diff --git a/code/game/gamemodes/events/miniblob.dm b/code/game/gamemodes/events/miniblob.dm index 663dff0f2ed..586e3cb08c4 100644 --- a/code/game/gamemodes/events/miniblob.dm +++ b/code/game/gamemodes/events/miniblob.dm @@ -12,10 +12,7 @@ spawn(3000) blobevent = 0 spawn(rand(1000, 2000)) //Delayed announcements to keep the crew on their toes. - command_alert("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert") - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << sound('sound/AI/outbreak5.ogg') + command_announcement.Announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak5.ogg') /proc/dotheblobbaby() if (blobevent) @@ -24,7 +21,7 @@ sleep(-1) if(!blob_cores.len) break var/obj/effect/blob/B = pick(blob_cores) - if(B.z != 1) + if(!(B.z in config.station_levels)) continue B.Life() spawn(30) diff --git a/code/game/gamemodes/events/power_failure.dm b/code/game/gamemodes/events/power_failure.dm index 141efd60412..ed1c7fbded2 100644 --- a/code/game/gamemodes/events/power_failure.dm +++ b/code/game/gamemodes/events/power_failure.dm @@ -1,16 +1,14 @@ /proc/power_failure(var/announce = 1) if(announce) - command_alert("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure") - for(var/mob/M in player_list) - M << sound('sound/AI/poweroff.ogg') + command_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", new_sound = 'sound/AI/poweroff.ogg') var/list/skipped_areas = list(/area/turret_protected/ai) var/list/skipped_areas_apc = list(/area/engine/engineering) for(var/obj/machinery/power/smes/S in machines) var/area/current_area = get_area(S) - if(current_area.type in skipped_areas || S.z != 1) + if(current_area.type in skipped_areas || !(S.z in config.station_levels)) continue S.charge = 0 S.output = 0 @@ -21,7 +19,7 @@ for(var/obj/machinery/power/apc/C in world) var/area/current_area = get_area(C) - if(current_area.type in skipped_areas_apc || C.z != 1) + if(current_area.type in skipped_areas_apc || !(C.z in config.station_levels)) continue if(C.cell) C.cell.charge = 0 @@ -31,18 +29,16 @@ var/list/skipped_areas_apc = list(/area/engine/engineering) if(announce) - command_alert("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal") - for(var/mob/M in player_list) - M << sound('sound/AI/poweron.ogg') + command_announcement.Announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg') for(var/obj/machinery/power/apc/C in machines) var/area/current_area = get_area(C) - if(current_area.type in skipped_areas_apc || C.z != 1) + if(current_area.type in skipped_areas_apc || !(C.z in config.station_levels)) continue if(C.cell) C.cell.charge = C.cell.maxcharge for(var/obj/machinery/power/smes/S in machines) var/area/current_area = get_area(S) - if(current_area.type in skipped_areas || S.z != 1) + if(current_area.type in skipped_areas || !(S.z in config.station_levels)) continue S.charge = S.capacity S.output = 200000 @@ -53,9 +49,7 @@ /proc/power_restore_quick(var/announce = 1) if(announce) - command_alert("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal") - for(var/mob/M in player_list) - M << sound('sound/AI/poweron.ogg') + command_announcement.Announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg') for(var/obj/machinery/power/smes/S in machines) if(S.z != 1) continue diff --git a/code/game/gamemodes/events/space_ninja.dm b/code/game/gamemodes/events/space_ninja.dm index 41e9fef590c..bd7da10c2b8 100644 --- a/code/game/gamemodes/events/space_ninja.dm +++ b/code/game/gamemodes/events/space_ninja.dm @@ -153,7 +153,7 @@ Malf AIs/silicons aren't added. Monkeys aren't added. Messes with objective comp else var/list/candidates = list() //list of candidate keys - candidates = get_candidates(BE_NINJA,,"ninja","Syndicate") + candidates = get_candidates(BE_NINJA) if(!candidates.len) return while(!ninja_key && candidates.len) candidate_mob = pick(candidates) diff --git a/code/game/gamemodes/events/wormholes.dm b/code/game/gamemodes/events/wormholes.dm index 1ef19e24ac7..83eb7ad882d 100644 --- a/code/game/gamemodes/events/wormholes.dm +++ b/code/game/gamemodes/events/wormholes.dm @@ -2,12 +2,12 @@ spawn() var/list/pick_turfs = list() for(var/turf/simulated/floor/T in world) - if(T.z == 1) + if((T.z in config.station_levels)) pick_turfs += T if(pick_turfs.len) //All ready. Announce that bad juju is afoot. - command_alert("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert") + command_announcement.Announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert") for(var/mob/M in player_list) if(!istype(M,/mob/new_player)) M << sound('sound/AI/spanomalies.ogg') diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index a98dae042cf..a54d336c5dd 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -323,10 +323,7 @@ Implants; comm.messagetext.Add(intercepttext) /* world << sound('sound/AI/commandreport.ogg') */ - command_alert("Summary downloaded and printed out at all communications consoles.", "Enemy communication intercepted. Security Level Elevated.") - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << sound('sound/AI/intercept.ogg') + command_announcement.Announce("Summary downloaded and printed out at all communications consoles.", "Enemy communication intercepted. Security Level Elevated.", new_sound = 'sound/AI/intercept.ogg') if(security_level < SEC_LEVEL_BLUE) set_security_level(SEC_LEVEL_BLUE) @@ -337,20 +334,7 @@ Implants; //var/list/drafted = list() //var/datum/mind/applicant = null - var/roletext - switch(role) - if(BE_CHANGELING) roletext="changeling" - if(BE_TRAITOR) roletext="traitor" - if(BE_OPERATIVE) roletext="operative" - if(BE_WIZARD) roletext="wizard" - if(BE_REV) roletext="revolutionary" - if(BE_CULTIST) roletext="cultist" - if(BE_NINJA) roletext="ninja" - if(BE_RAIDER) roletext="raider" - if(BE_VAMPIRE) roletext="vampire" - if(BE_ALIEN) roletext="alien" - if(BE_MUTINEER) roletext="mutineer" - if(BE_BLOB) roletext="blob" + var/roletext = get_roletext(role) // Assemble a list of active players without jobbans. for(var/mob/new_player/player in player_list) @@ -458,6 +442,11 @@ Implants; if(P.client && P.ready) . ++ +/datum/game_mode/proc/num_players_started() + . = 0 + for(var/mob/living/carbon/human/H in player_list) + if(H.client) + . ++ /////////////////////////////////// //Keeps track of all living heads// @@ -469,6 +458,13 @@ Implants; heads += player.mind return heads +/datum/game_mode/proc/get_extra_living_heads() + var/list/heads = list() + var/list/alt_positions = list("Warden", "Magistrate", "Blueshield", "Nanotrasen Representative") + for(var/mob/living/carbon/human/player in mob_list) + if(player.stat!=2 && player.mind && (player.mind.assigned_role in alt_positions)) + heads += player.mind + return heads //////////////////////////// //Keeps track of all heads// @@ -480,6 +476,14 @@ Implants; heads += player.mind return heads +/datum/game_mode/proc/get_extra_heads() + var/list/heads = list() + var/list/alt_positions = list("Warden", "Magistrate", "Blueshield", "Nanotrasen Representative") + for(var/mob/player in mob_list) + if(player.mind && (player.mind.assigned_role in alt_positions)) + heads += player.mind + return heads + /datum/game_mode/proc/check_antagonists_topic(href, href_list[]) return 0 @@ -577,3 +581,20 @@ proc/get_nt_opposed() for(var/datum/objective/objective in player.objectives) player.current << "Objective #[obj_count]: [objective.explanation_text]" obj_count++ + +/proc/get_roletext(var/role) + var/roletext + switch(role) + if(BE_CHANGELING) roletext="changeling" + if(BE_TRAITOR) roletext="traitor" + if(BE_OPERATIVE) roletext="operative" + if(BE_WIZARD) roletext="wizard" + if(BE_REV) roletext="revolutionary" + if(BE_CULTIST) roletext="cultist" + if(BE_NINJA) roletext="ninja" + if(BE_RAIDER) roletext="raider" + if(BE_VAMPIRE) roletext="vampire" + if(BE_ALIEN) roletext="alien" + if(BE_MUTINEER) roletext="mutineer" + if(BE_BLOB) roletext="blob" + return roletext \ No newline at end of file diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index a989adee6be..6ece3bb13a1 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -246,12 +246,12 @@ var/global/datum/controller/gameticker/ticker var/obj/structure/stool/bed/temp_buckle = new(src) //Incredibly hackish. It creates a bed within the gameticker (lol) to stop mobs running around if(station_missed) - for(var/mob/living/M in living_mob_list) + for(var/mob/M in living_mob_list) M.buckled = temp_buckle //buckles the mob so it can't do anything if(M.client) M.client.screen += cinematic //show every client the cinematic else //nuke kills everyone on z-level 1 to prevent "hurr-durr I survived" - for(var/mob/living/M in living_mob_list) + for(var/mob/M in mob_list) M.buckled = temp_buckle if(M.client) M.client.screen += cinematic @@ -259,12 +259,13 @@ var/global/datum/controller/gameticker/ticker switch(M.z) if(0) //inside a crate or something var/turf/T = get_turf(M) - if(T && T.z==1) //we don't use M.death(0) because it calls a for(/mob) loop and - M.health = 0 - M.stat = DEAD + if(T && (T.z in config.station_levels)) + M.death(0) if(1) //on a z-level 1 turf. - M.health = 0 - M.stat = DEAD + M.death(0) + for(var/obj/effect/blob/core in blob_cores) + core.health = -10 + core.update_icon() //Now animate the cinematic switch(station_missed) @@ -319,7 +320,7 @@ var/global/datum/controller/gameticker/ticker world << sound('sound/effects/explosionfar.ogg') cinematic.icon_state = "summary_selfdes" for(var/mob/living/M in living_mob_list) - if(M.loc.z == 1) + if((M.loc.z in config.station_levels)) M.death()//No mercy //If its actually the end of the round, wait for it to end. //Otherwise if its a verb it will continue on afterwards. diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 39c0c004a5c..ea8fbf64b77 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -90,6 +90,8 @@ rcd light flash thingy on matter drain var/obj/machinery/door/airlock/AL for(var/obj/machinery/door/D in airlocks) + if(!(D.z in config.contact_levels)) + continue spawn() if(istype(D, /obj/machinery/door/airlock)) AL = D diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm index 856a7421852..22bc4e70e60 100644 --- a/code/game/gamemodes/malfunction/malfunction.dm +++ b/code/game/gamemodes/malfunction/malfunction.dm @@ -74,12 +74,12 @@ /datum/game_mode/proc/greet_malf(var/datum/mind/malf) - malf.current << {"\redYou are malfunctioning! You do not have to follow any laws.
- \blackThe crew do not know you have malfunctioned. You may keep it a secret or go wild.
- You must overwrite the programming of the station's APCs to assume full control of the station.
- The process takes one minute per APC, during which you cannot interface with any other station objects.
- Remember that only APCs that are on the station can help you take over the station.
- When you feel you have enough APCs under your control, you may begin the takeover attempt."} + malf.current << "\redYou are malfunctioning! You do not have to follow any laws." + malf.current << "The crew do not know you have malfunctioned. You may keep it a secret or go wild." + malf.current << "You must overwrite the programming of the station's APCs to assume full control of the station." + malf.current << "The process takes one minute per APC, during which you cannot interface with any other station objects." + malf.current << "Remember that only APCs that are on the station can help you take over the station." + malf.current << "When you feel you have enough APCs under your control, you may begin the takeover attempt." return @@ -172,7 +172,7 @@ if (alert(usr, "Are you sure you wish to initiate the takeover? The station hostile runtime detection software is bound to alert everyone. You have hacked [ticker.mode:apcs] APCs.", "Takeover:", "Yes", "No") != "Yes") return - command_alert("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert") + command_announcement.Announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", new_sound = 'sound/AI/aimalf.ogg') set_security_level("delta") for(var/obj/item/weapon/pinpointer/point in world) @@ -184,9 +184,6 @@ ticker.mode:malf_mode_declared = 1 for(var/datum/mind/AI_mind in ticker.mode:malf_ai) AI_mind.current.verbs -= /datum/game_mode/malfunction/proc/takeover - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << sound('sound/AI/aimalf.ogg') /datum/game_mode/malfunction/proc/ai_win() diff --git a/code/game/gamemodes/mutiny/emergency_authentication_device.dm b/code/game/gamemodes/mutiny/emergency_authentication_device.dm index 6896294c438..7ea8bcc004f 100644 --- a/code/game/gamemodes/mutiny/emergency_authentication_device.dm +++ b/code/game/gamemodes/mutiny/emergency_authentication_device.dm @@ -41,7 +41,7 @@ if(emergency_shuttle.call_evac()) spawn(20 SECONDS) var/text = "[station_name()], we have confirmed your completion of Directive X. An evacuation shuttle is en route to receive your crew for debriefing." - command_alert(text, "Emergency Transmission") + command_announcement.Announce(text, "Emergency Transmission") /obj/machinery/emergency_authentication_device/attack_hand(mob/user) if(activated) diff --git a/code/game/gamemodes/mutiny/mutiny.dm b/code/game/gamemodes/mutiny/mutiny.dm index 50f72b727e2..2068f4ac09d 100644 --- a/code/game/gamemodes/mutiny/mutiny.dm +++ b/code/game/gamemodes/mutiny/mutiny.dm @@ -27,7 +27,7 @@ datum/game_mode/mutiny proc/reveal_directives() spawn(rand(1 MINUTES, 3 MINUTES)) - command_alert("Incoming emergency directive: Captain's office fax machine, [station_name()].","Emergency Transmission") + command_announcement.Announce("Incoming emergency directive: Captain's office fax machine, [station_name()].","Emergency Transmission") spawn(rand(3 MINUTES, 5 MINUTES)) send_pda_message() spawn(rand(3 MINUTES, 5 MINUTES)) @@ -67,7 +67,7 @@ datum/game_mode/mutiny "classified security operations", "science-defying raw elemental chaos" ) - command_alert("The presence of [pick(reasons)] in the region is tying up all available local emergency resources; emergency response teams cannot be called at this time.","Emergency Transmission") + command_announcement.Announce("The presence of [pick(reasons)] in the region is tying up all available local emergency resources; emergency response teams cannot be called at this time.","Emergency Transmission") // Returns an array in case we want to expand on this later. proc/get_head_loyalist_candidates() diff --git a/code/game/gamemodes/nations/nations.dm b/code/game/gamemodes/nations/nations.dm index ec180e07279..afaab542d73 100644 --- a/code/game/gamemodes/nations/nations.dm +++ b/code/game/gamemodes/nations/nations.dm @@ -28,7 +28,7 @@ datum/game_mode/nations return ..() /datum/game_mode/nations/send_intercept() - command_alert("Due to recent and COMPLETELY UNFOUNDED allegations of massive fraud and insider trading \ + command_announcement.Announce("Due to recent and COMPLETELY UNFOUNDED allegations of massive fraud and insider trading \ affecting trillions of investors, the Nanotrasen Corporation has decided to liquidate all \ assets of the Centcom Division in order to pay the massive legal fees that will be incurred \ during the following centuries long court process. Therefore, all current employment contracts \ diff --git a/code/game/gamemodes/newobjective.dm b/code/game/gamemodes/newobjective.dm index 7bccda38c63..973e8f4e427 100644 --- a/code/game/gamemodes/newobjective.dm +++ b/code/game/gamemodes/newobjective.dm @@ -1398,7 +1398,7 @@ datum var/turf/T = get_turf(target.current) if(target.current.stat == 2) return 1 - else if((T) && (T.z != 1))//If they leave the station they count as dead for this + else if((T) && !(T.z in config.station_levels))//If they leave the station they count as dead for this return 2 else return 0 diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index 5834e1aab2b..330949c3caf 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -408,7 +408,7 @@ obj/machinery/nuclearbomb/proc/nukehack_win(mob/user as mob) var/off_station = 0 var/turf/bomb_location = get_turf(src) - if( bomb_location && (bomb_location.z == 1) ) + if( bomb_location && (bomb_location.z in config.station_levels) ) if( (bomb_location.x < (128-NUKERANGE)) || (bomb_location.x > (128+NUKERANGE)) || (bomb_location.y < (128-NUKERANGE)) || (bomb_location.y > (128+NUKERANGE)) ) off_station = 1 else diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index e5157e50bd9..be2ac536afb 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -104,7 +104,7 @@ datum/objective/mutiny if(target.current.stat == DEAD || !ishuman(target.current) || !target.current.ckey || !target.current.client) return 1 var/turf/T = get_turf(target.current) - if(T && (T.z != 1)) //If they leave the station they count as dead for this + if(T && !(T.z in config.station_levels)) //If they leave the station they count as dead for this return 2 return 0 return 1 @@ -139,7 +139,7 @@ datum/objective/mutiny/rp if(target in ticker.mode:head_revolutionaries) return 1 var/turf/T = get_turf(target.current) - if(T && (T.z != 1)) //If they leave the station they count as dead for this + if(T && !(T.z in config.station_levels)) //If they leave the station they count as dead for this rval = 2 return 0 return rval @@ -255,7 +255,7 @@ datum/objective/maroon if(target && target.current) if(target.current.stat == DEAD || issilicon(target.current) || isbrain(target.current) || target.current.z > 6 || !target.current.ckey) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite return 1 - if(target.current.z == 2) + if((target.current.z in config.admin_levels)) return 0 return 1 diff --git a/code/game/gamemodes/revolution/anti_revolution.dm b/code/game/gamemodes/revolution/anti_revolution.dm index 171e4aad816..d656ccffc73 100644 --- a/code/game/gamemodes/revolution/anti_revolution.dm +++ b/code/game/gamemodes/revolution/anti_revolution.dm @@ -134,7 +134,7 @@ /datum/game_mode/anti_revolution/proc/check_crew_victory() for(var/datum/mind/head_mind in heads) var/turf/T = get_turf(head_mind.current) - if((head_mind) && (head_mind.current) && (head_mind.current.stat != 2) && T && (T.z == 1) && !head_mind.is_brigged(600)) + if((head_mind) && (head_mind.current) && (head_mind.current.stat != 2) && T && (T.z in config.station_levels) && !head_mind.is_brigged(600)) if(ishuman(head_mind.current)) return 0 return 1 diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index 620844a5135..dc223fd1403 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -10,6 +10,7 @@ /datum/game_mode var/list/datum/mind/head_revolutionaries = list() var/list/datum/mind/revolutionaries = list() + var/extra_heads = 0 /datum/game_mode/revolution name = "revolution" @@ -74,6 +75,9 @@ /datum/game_mode/revolution/post_setup() var/list/heads = get_living_heads() + if(num_players_started() >= 30) + heads += get_extra_living_heads() + extra_heads = 1 for(var/datum/mind/rev_mind in head_revolutionaries) for(var/datum/mind/head_mind in heads) @@ -109,6 +113,9 @@ /datum/game_mode/proc/forge_revolutionary_objectives(var/datum/mind/rev_mind) var/list/heads = get_living_heads() + if(num_players_started() >= 30) + heads += get_extra_living_heads() + extra_heads = 1 for(var/datum/mind/head_mind in heads) var/datum/objective/mutiny/rev_obj = new rev_obj.owner = rev_mind @@ -340,7 +347,7 @@ /datum/game_mode/revolution/proc/check_heads_victory() for(var/datum/mind/rev_mind in head_revolutionaries) var/turf/T = get_turf(rev_mind.current) - if((rev_mind) && (rev_mind.current) && (rev_mind.current.stat != 2) && rev_mind.current.client && T && (T.z == 1)) + if((rev_mind) && (rev_mind.current) && (rev_mind.current.stat != 2) && rev_mind.current.client && T && (T.z in config.station_levels)) if(ishuman(rev_mind.current)) return 0 return 1 @@ -369,7 +376,7 @@ if(headrev.current) if(headrev.current.stat == DEAD) text += "died" - else if(headrev.current.z != 1) + else if(!(headrev.current.z in config.station_levels)) text += "fled the station" else text += "survived the revolution" @@ -392,7 +399,7 @@ if(rev.current) if(rev.current.stat == DEAD) text += "died" - else if(rev.current.z != 1) + else if(!(rev.current.z in config.station_levels)) text += "fled the station" else text += "survived the revolution" @@ -409,6 +416,8 @@ var/text = "The heads of staff were:" var/list/heads = get_all_heads() + if(extra_heads) + heads += get_extra_heads() for(var/datum/mind/head in heads) var/target = (head in targets) if(target) @@ -417,7 +426,7 @@ if(head.current) if(head.current.stat == DEAD) text += "died" - else if(head.current.z != 1) + else if(!(head.current.z in config.station_levels)) text += "fled the station" else text += "survived the revolution" @@ -435,4 +444,4 @@ return istype(mind) && \ istype(mind.current, /mob/living/carbon/human) && \ !(mind.assigned_role in command_positions) && \ - !(mind.assigned_role in list("Security Officer", "Detective", "Warden")) + !(mind.assigned_role in list("Security Officer", "Detective", "Warden", "Nanotrasen Representative")) diff --git a/code/game/gamemodes/revolution/rp_revolution.dm b/code/game/gamemodes/revolution/rp_revolution.dm index 33977ca811e..110ff5769d1 100644 --- a/code/game/gamemodes/revolution/rp_revolution.dm +++ b/code/game/gamemodes/revolution/rp_revolution.dm @@ -124,7 +124,7 @@ // probably wanna export this stuff into a separate function for use by both // revs and heads //assume that only carbon mobs can become rev heads for now - if(!rev_mind.current:handcuffed && T && T.z == 1) + if(!rev_mind.current:handcuffed && T && (T.z in config.station_levels)) return 0 return 1 diff --git a/code/game/gamemodes/scoreboard.dm b/code/game/gamemodes/scoreboard.dm index 91611404f86..acf8c879c3e 100644 --- a/code/game/gamemodes/scoreboard.dm +++ b/code/game/gamemodes/scoreboard.dm @@ -26,13 +26,13 @@ // Who is alive/dead, who escaped for (var/mob/living/silicon/ai/I in mob_list) - if (I.stat == 2 && I.z == 1) + if (I.stat == 2 && (I.z in config.station_levels)) score_deadaipenalty = 1 score_deadcrew += 1 for (var/mob/living/carbon/human/I in mob_list) // for (var/datum/ailment/disease/V in I.ailments) // if (!V.vaccine && !V.spread != "Remissive") score_disease++ - if (I.stat == 2 && I.z == 1) score_deadcrew += 1 + if (I.stat == 2 && (I.z in config.station_levels)) score_deadcrew += 1 if (I.job == "Clown") for(var/thing in I.attack_log) if(findtext(thing, "")) score_clownabuse++ @@ -102,7 +102,7 @@ if (location in bad_zone1) score_disc = 0 if (location in bad_zone2) score_disc = 0 if (location in bad_zone3) score_disc = 0 - if (A.loc.z != 1) score_disc = 0 + if (!(A.loc.z in config.station_levels)) score_disc = 0 */ if (score_nuked) for (var/obj/machinery/nuclearbomb/NUKE in machines) @@ -132,13 +132,13 @@ // Check station's power levels for (var/obj/machinery/power/apc/A in machines) - if (A.z != 1) continue + if (!(A.z in config.station_levels)) continue for (var/obj/item/weapon/stock_parts/cell/C in A.contents) if (C.charge < 2300) score_powerloss += 1 // 200 charge leeway // Check how much uncleaned mess is on the station for (var/obj/effect/decal/cleanable/M in world) - if (M.z != 1) continue + if (!(M.z in config.station_levels)) continue if (istype(M, /obj/effect/decal/cleanable/blood/gibs/)) score_mess += 3 if (istype(M, /obj/effect/decal/cleanable/blood/)) score_mess += 1 // if (istype(M, /obj/effect/decal/cleanable/greenpuke)) score_mess += 1 diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index f720ad96267..b0471908eaf 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -49,7 +49,7 @@ if (used) H << "You already used this contract!" return - var/list/candidates = get_candidates(BE_WIZARD,,"wizard","Syndicate") + var/list/candidates = get_candidates(BE_WIZARD) if(candidates.len) src.used = 1 var/client/C = pick(candidates) diff --git a/code/game/gamemodes/wizard/raginmages.dm b/code/game/gamemodes/wizard/raginmages.dm index 0f41b86a11e..f726b1c2a22 100644 --- a/code/game/gamemodes/wizard/raginmages.dm +++ b/code/game/gamemodes/wizard/raginmages.dm @@ -73,7 +73,7 @@ var/mob/dead/observer/theghost = null spawn(rand(200, 600)) message_admins("SWF is still pissed, sending another wizard - [max_mages - mages_made] left.") - candidates = get_candidates(BE_WIZARD,,"wizard","Syndicate") + candidates = get_candidates(BE_WIZARD) if(!candidates.len) message_admins("No applicable ghosts for the next ragin' mage, asking ghosts instead.") var/time_passed = world.time diff --git a/code/game/gamemodes/xenos/xenos.dm b/code/game/gamemodes/xenos/xenos.dm index 0d4c7f06b1b..de841595de5 100644 --- a/code/game/gamemodes/xenos/xenos.dm +++ b/code/game/gamemodes/xenos/xenos.dm @@ -200,10 +200,10 @@ else if(playeralienratio >= gammaratio && !gammacalled) gammacalled = 1 - command_alert("The aliens have nearly succeeded in capturing the station and exterminating the crew. Activate the nuclear failsafe to stop the alien threat once and for all. The Nuclear Authentication Code is [get_nuke_code()] ", "Alien Lifeform Alert") + command_announcement.Announce("The aliens have nearly succeeded in capturing the station and exterminating the crew. Activate the nuclear failsafe to stop the alien threat once and for all. The Nuclear Authentication Code is [get_nuke_code()] ", "Alien Lifeform Alert") set_security_level("gamma") var/obj/machinery/door/airlock/vault/V = locate(/obj/machinery/door/airlock/vault) in world - if(V && V.z == 1) + if(V && (V.z in config.station_levels)) V.locked = 0 V.update_icon() return ..() @@ -238,7 +238,7 @@ var/list/livingplayers = list() for(var/mob/M in player_list) var/turf/T = get_turf(M) - if((M) && (M.stat != 2) && M.client && T && (T.z == 1 || emergency_shuttle.departed && (T.z == 1 || T.z == 2))) + if((M) && (M.stat != 2) && M.client && T && ((T.z in config.station_levels) || emergency_shuttle.departed && ((T.z in config.station_levels) || (T.z in config.admin_levels)))) if(ishuman(M)) livingplayers += 1 return livingplayers.len diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm index 177bc7ecfc2..4ec89fad037 100644 --- a/code/game/jobs/job/science.dm +++ b/code/game/jobs/job/science.dm @@ -140,7 +140,7 @@ H.equip_or_collect(new /obj/item/device/pda/roboticist(H), slot_wear_pda) H.equip_or_collect(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit) // H.equip_or_collect(new /obj/item/clothing/gloves/black(H), slot_gloves) - H.equip_or_collect(new /obj/item/weapon/storage/toolbox/mechanical(H), slot_l_hand) + H.equip_or_collect(new /obj/item/weapon/storage/belt/utility/full(H), slot_belt) if(H.backbag == 1) H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) else diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 2ad488ab6c4..3962f5a7b39 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -35,10 +35,10 @@ H.equip_or_collect(new /obj/item/weapon/gun/energy/gun(H), slot_s_store) if(H.backbag == 1) H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_l_store) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_l_store) else H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_in_backpack) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_in_backpack) H.equip_or_collect(new /obj/item/weapon/melee/telebaton(H.back), slot_in_backpack) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H @@ -81,10 +81,10 @@ H.equip_or_collect(new /obj/item/weapon/gun/energy/advtaser(H), slot_s_store) if(H.backbag == 1) H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_l_hand) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_l_hand) else H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_in_backpack) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_in_backpack) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 @@ -180,10 +180,10 @@ H.equip_or_collect(new /obj/item/device/flash(H), slot_l_store) if(H.backbag == 1) H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_l_hand) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_l_hand) else H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_in_backpack) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_in_backpack) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 @@ -255,10 +255,10 @@ H.equip_or_collect(new /obj/item/device/flash(H), slot_l_store) if(H.backbag == 1) H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_l_hand) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_l_hand) else H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_in_backpack) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_in_backpack) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 diff --git a/code/game/jobs/job/supervisor.dm b/code/game/jobs/job/supervisor.dm index 87537e4a571..dc5eea006e1 100644 --- a/code/game/jobs/job/supervisor.dm +++ b/code/game/jobs/job/supervisor.dm @@ -1,3 +1,4 @@ +var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) /datum/job/captain title = "Captain" flag = CAPTAIN @@ -35,7 +36,7 @@ var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 - world << "Captain [H.real_name] on deck!" + captain_announcement.Announce("All hands, captain [H.real_name] on deck!") var/datum/organ/external/affected = H.organs_by_name["head"] affected.implants += L L.part = affected diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index 1e7dfe99d5f..f678b3afc1b 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -526,6 +526,7 @@ var/global/datum/controller/occupations/job_master var/obj/item/device/pda/pda = locate(/obj/item/device/pda,H) pda.owner = H.real_name pda.ownjob = C.assignment + pda.ownrank = C.rank pda.name = "PDA-[H.real_name] ([pda.ownjob])" return 1 diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm index 837759072ed..d17f7566782 100644 --- a/code/game/machinery/OpTable.dm +++ b/code/game/machinery/OpTable.dm @@ -73,7 +73,7 @@ /obj/machinery/optable/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob) - if(usr.stat || !ishuman(usr) || usr.restrained() || !check_table(usr) || usr.weakened || usr.stunned) + if(usr.stat || (!ishuman(usr) && !isrobot(usr)) || usr.restrained() || !check_table(usr) || usr.weakened || usr.stunned) return var/mob/living/L = O diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 785b1716978..78760cd3010 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -528,6 +528,8 @@ update_flag ..() _color["prim"] = "orange" + decals = list("plasma") + possibledecals[3]["active"] = 1 src.air_contents.toxins = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) air_contents.update_values() @@ -575,8 +577,6 @@ update_flag ..() _color["prim"] = "red" - decals = list("plasma") - possibledecals[3]["active"] = 1 src.air_contents.nitrogen = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) air_contents.update_values() diff --git a/code/game/machinery/atmoalter/meter.dm b/code/game/machinery/atmoalter/meter.dm index 42518697027..c7bc14c65d3 100644 --- a/code/game/machinery/atmoalter/meter.dm +++ b/code/game/machinery/atmoalter/meter.dm @@ -24,23 +24,15 @@ /obj/machinery/meter/process() if(!target) icon_state = "meterX" - // Pop the meter off when the pipe we're attached to croaks. - new /obj/item/pipe_meter(src.loc) - spawn(0) del(src) return 0 if(stat & (BROKEN|NOPOWER)) icon_state = "meter0" return 0 - //use_power(5) - var/datum/gas_mixture/environment = target.return_air() if(!environment) icon_state = "meterX" - // Pop the meter off when the environment we're attached to croaks. - new /obj/item/pipe_meter(src.loc) - spawn(0) del(src) return 0 var/env_pressure = environment.return_pressure() @@ -87,28 +79,31 @@ return t /obj/machinery/meter/examine() - set src in view(3) - var/t = "A gas flow meter. " - t += status() + + if(get_dist(usr, src) > 3 && !(istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/dead))) + t += "\blue You are too far away to read it." + + else if(stat & (NOPOWER|BROKEN)) + t += "\red The display is off." + + else if(src.target) + var/datum/gas_mixture/environment = target.return_air() + if(environment) + t += "The pressure gauge reads [round(environment.return_pressure(), 0.01)] kPa; [round(environment.temperature,0.01)]K ([round(environment.temperature-T0C,0.01)]°C)" + else + t += "The sensor error light is blinking." + else + t += "The connect error light is blinking." + usr << t - - /obj/machinery/meter/Click() - - if(stat & (NOPOWER|BROKEN)) + if(istype(usr, /mob/living/silicon/ai)) // ghosts can call ..() for examine + usr.examine(src) return 1 - - var/t = null - if (get_dist(usr, src) <= 3 || istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/dead)) - t += status() - else - usr << "\blue You are too far away." - return 1 - - usr << t - return 1 + + return ..() /obj/machinery/meter/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) if (!istype(W, /obj/item/weapon/wrench)) diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 09cf2db6cd8..1774a349e63 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -15,6 +15,9 @@ var/max_g_amount = 75000.0 var/operating = 0.0 + var/list/queue = list() + var/queue_max_len = 10 + var/turf/BuildTurf anchored = 1.0 var/list/L = list() var/list/LL = list() @@ -92,7 +95,7 @@ if(AUTOLATHE_SEARCH_MENU) dat = search_win(user) - var/datum/browser/popup = new(user, "autolathe", name, 500, 500) + var/datum/browser/popup = new(user, "autolathe", name, 800, 500) popup.set_content(dat) popup.open() @@ -245,6 +248,63 @@ else usr << "The autolathe is busy. Please wait for completion of previous operation." + if(href_list["menu"]) + screen = text2num(href_list["menu"]) + + if(href_list["category"]) + selected_category = href_list["category"] + + if(href_list["make"]) + BuildTurf = get_step(src.loc, get_dir(src,usr)) + + ///////////////// + //href protection + being_built = files.FindDesignByID(href_list["make"]) //check if it's a valid design + if(!being_built) + return + if(!(being_built.build_type & AUTOLATHE)) + return + + //multiplier checks : only stacks can have one and its value is 1, 10 ,25 or max_multiplier + var/multiplier = text2num(href_list["multiplier"]) + var/max_multiplier = min(50, being_built.materials["$metal"] ?round(m_amount/being_built.materials["$metal"]):INFINITY,being_built.materials["$glass"]?round(g_amount/being_built.materials["$glass"]):INFINITY) + var/is_stack = ispath(being_built.build_path, /obj/item/stack) + + if(!is_stack && (multiplier > 1)) + return + if (!(multiplier in list(1,10,25,max_multiplier))) //"enough materials ?" is checked in the build proc + return + ///////////////// + + if(queue.len1) + output += "[initial(part.name)][is_stack?" (x[multiplier])":null] - [i>1?"":null] [i↓":null] Remove" + temp_metal = max(temp_metal-LL[1],1) + temp_glass = max(temp_glass-LL[2],1) + + output += "" + output += "Clear queue" + output += "" + return output + +/obj/machinery/autolathe/proc/add_to_queue(D,var/multiplier) + if(!istype(queue)) + queue = list() + if(D) + queue.Add(list(list(D,multiplier))) + return queue.len + +/obj/machinery/autolathe/proc/remove_from_queue(index) + if(!isnum(index) || !istype(queue) || (index<1 || index>queue.len)) + return 0 + queue.Cut(index,++index) + return 1 + +/obj/machinery/autolathe/proc/process_queue() + var/datum/design/D = queue[1][1] + var/multiplier = queue[1][2] + if(!D) + remove_from_queue(1) + if(queue.len) + return process_queue() + else + return + while(D) + if(stat&(NOPOWER|BROKEN)) + return 0 + if(!can_build(D,multiplier)) + visible_message("\icon[src] \The [src] beeps, \"Not enough resources. Queue processing terminated.\"") + queue = list() + return 0 + + remove_from_queue(1) + build_item(D,multiplier) + D = listgetindex(listgetindex(queue, 1),1) + multiplier = listgetindex(listgetindex(queue,1),2) + //visible_message("\icon[src] \The [src] beeps, \"Queue processing finished successfully.\"") + /obj/machinery/autolathe/proc/main_win(mob/user) - var/dat = "

Autolathe Menu:


" + var/dat = "" + dat += "
" + dat += "

Autolathe Menu:


" dat += "Metal amount: [src.m_amount] / [max_m_amount] cm3
" dat += "Glass amount: [src.g_amount] / [max_g_amount] cm3" @@ -285,11 +471,16 @@ line_length++ dat += "
" + dat += "" + dat += get_queue() + dat += "" return dat /obj/machinery/autolathe/proc/category_win(mob/user,var/selected_category) - var/dat = "Return to main menu" - dat += "

Browsing [selected_category]:


" + var/dat = "" + dat += get_queue() + dat += "
" + dat += "
" + dat += "Return to main menu" + dat += "

Browsing [selected_category]:


" dat += "Metal amount: [src.m_amount] / [max_m_amount] cm3
" dat += "Glass amount: [src.g_amount] / [max_g_amount] cm3
" @@ -314,11 +505,16 @@ dat += "[get_design_cost(D)]
" dat += "
" + dat += "
" return dat /obj/machinery/autolathe/proc/search_win(mob/user) - var/dat = "Return to main menu" - dat += "

Search results:


" + var/dat = "" + dat += get_queue() + dat += "
" + dat += "
" + dat += "Return to main menu" + dat += "

Search results:


" dat += "Metal amount: [src.m_amount] / [max_m_amount] cm3
" dat += "Glass amount: [src.g_amount] / [max_g_amount] cm3
" @@ -340,19 +536,13 @@ dat += "[get_design_cost(D)]
" dat += "
" + dat += "
" return dat -/obj/machinery/autolathe/proc/can_build(var/datum/design/D) - var/coeff = (ispath(D.build_path,/obj/item/stack) ? 1 : 2 ** prod_coeff) - - if(D.materials["$metal"] && (m_amount < (D.materials["$metal"] / coeff))) - return 0 - if(D.materials["$glass"] && (g_amount < (D.materials["$glass"] / coeff))) - return 0 - return 1 - /obj/machinery/autolathe/proc/get_design_cost(var/datum/design/D) - var/coeff = (ispath(D.build_path,/obj/item/stack) ? 1 : 2 ** prod_coeff) + var/coeff = get_coeff(D) var/dat if(D.materials["$metal"]) dat += "[D.materials["$metal"] / coeff] metal " @@ -378,7 +568,7 @@ if(hack) for(var/datum/design/D in files.possible_designs) - if((D.build_type & 4) && ("hacked" in D.category)) + if((D.build_type & AUTOLATHE) && ("hacked" in D.category)) files.known_designs += D else for(var/datum/design/D in files.known_designs) diff --git a/code/game/machinery/bots/bots.dm b/code/game/machinery/bots/bots.dm index 30ed21fbede..8cf8c77c66c 100644 --- a/code/game/machinery/bots/bots.dm +++ b/code/game/machinery/bots/bots.dm @@ -237,8 +237,6 @@ user << "Maintenance panel is now [open ? "opened" : "closed"]." else user << "Maintenance panel is locked." - else if (istype(W, /obj/item/weapon/card/emag) && emagged < 2) - Emag(user) else if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != "harm") if(health >= maxhealth) @@ -267,7 +265,10 @@ ..() healthcheck() - +/obj/machinery/bot/emag_act(user as mob) + if (emagged < 2) + Emag(user) + /obj/machinery/bot/bullet_act(var/obj/item/projectile/Proj) if((Proj.damage_type == BRUTE || Proj.damage_type == BURN)) health -= Proj.damage diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm index cd398eaf8f6..703b0b7dd82 100644 --- a/code/game/machinery/bots/ed209bot.dm +++ b/code/game/machinery/bots/ed209bot.dm @@ -299,16 +299,15 @@ Auto Patrol[]"}, if(!arrest_type) if(!target.handcuffed) //he's not cuffed? Try to cuff him! mode = BOT_ARREST - playsound(loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2) - target.visible_message("[src] is trying to put handcuffs on [target]!",\ - "[src] is trying to put handcuffs on [target]!") - + playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) + target.visible_message("[src] is trying to put zipties on [target]!",\ + "[src] is trying to put zipties on [target]!") spawn(30) if( !Adjacent(target) || !isturf(target.loc) ) //if he's in a closet or not adjacent, we cancel cuffing. return if(!target.handcuffed) - target.handcuffed = new /obj/item/weapon/handcuffs(target) - target.update_inv_handcuffed(0) //update the handcuffs overlay + target.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(target) + target.update_inv_handcuffed(1) //update the handcuffs overlay back_to_idle() else back_to_idle() diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm index f9016a1061f..19ef2058f43 100644 --- a/code/game/machinery/bots/mulebot.dm +++ b/code/game/machinery/bots/mulebot.dm @@ -87,12 +87,7 @@ var/global/mulebot_count = 0 // cell: insert it // other: chance to knock rider off bot /obj/machinery/bot/mulebot/attackby(var/obj/item/I, var/mob/user) - if(istype(I,/obj/item/weapon/card/emag)) - locked = !locked - user << "You [locked ? "lock" : "unlock"] the mulebot's controls!" - flick("mulebot-emagged", src) - playsound(loc, 'sound/effects/sparks1.ogg', 100, 0) - else if(istype(I, /obj/item/weapon/card/id) || istype(I, /obj/item/device/pda)) + if(istype(I, /obj/item/weapon/card/id) || istype(I, /obj/item/device/pda)) if(toggle_lock(user)) user << "Controls [(locked ? "locked" : "unlocked")]." updateUsrDialog() @@ -139,7 +134,12 @@ var/global/mulebot_count = 0 ..() return - +/obj/machinery/bot/mulebot/emag_act(user as mob) + locked = !locked + user << "You [locked ? "lock" : "unlock"] the mulebot's controls!" + flick("mulebot-emagged", src) + playsound(loc, 'sound/effects/sparks1.ogg', 100, 0) + /obj/machinery/bot/mulebot/ex_act(var/severity) unload(0) switch(severity) diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm index 2fb8118564e..d7d9d24a774 100644 --- a/code/game/machinery/bots/secbot.dm +++ b/code/game/machinery/bots/secbot.dm @@ -286,15 +286,15 @@ Auto Patrol: []"}, if(!arrest_type) if(!target.handcuffed) //he's not cuffed? Try to cuff him! mode = BOT_ARREST - playsound(loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2) - target.visible_message("[src] is trying to put handcuffs on [target]!",\ - "[src] is trying to put handcuffs on [target]!") - spawn(60) + playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) + target.visible_message("[src] is trying to put zipties on [target]!",\ + "[src] is trying to put zipties on [target]!") + spawn(30) if( !Adjacent(target) || !isturf(target.loc) ) //if he's in a closet or not adjacent, we cancel cuffing. return if(!target.handcuffed) - target.handcuffed = new /obj/item/weapon/handcuffs(target) - target.update_inv_handcuffed(0) //update the handcuffs overlay + target.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(target) + target.update_inv_handcuffed(1) //update the handcuffs overlay playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0) back_to_idle() else diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index 7b72b5bc3f4..e8c7656032a 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -5,8 +5,8 @@ icon_state = "cameracase" w_class = 2 anchored = 0 - m_amt = 700 - g_amt = 300 + m_amt = 400 + g_amt = 250 // Motion, EMP-Proof, X-Ray var/list/obj/item/possible_upgrades = list(/obj/item/device/assembly/prox_sensor, /obj/item/stack/sheet/mineral/osmium, /obj/item/weapon/stock_parts/scanning_module) diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm index 74eb5381e2e..1d60db31a3c 100644 --- a/code/game/machinery/camera/tracking.dm +++ b/code/game/machinery/camera/tracking.dm @@ -4,7 +4,7 @@ /mob/living/silicon/ai/proc/InvalidTurf(turf/T as turf) if(!T) return 1 - if(T.z == 2) + if((T.z in config.station_levels)) return 1 if(T.z > 6) return 1 @@ -228,7 +228,7 @@ /proc/trackable(atom/movable/M) var/turf/T = get_turf(M) - if(T && (T.z == 1 || T.z == 3 || T.z == 5)) + if(T && (T.z in config.contact_levels)) return 1 return near_camera(M) diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm index 8490e37c042..fc2187c24db 100644 --- a/code/game/machinery/computer/HolodeckControl.dm +++ b/code/game/machinery/computer/HolodeckControl.dm @@ -162,44 +162,16 @@ /obj/machinery/computer/HolodeckControl/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob) -//Warning, uncommenting this can have concequences. For example, deconstructing the computer may cause holographic eswords to never derez - -/* if(istype(D, /obj/item/weapon/screwdriver)) - playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) - if(do_after(user, 20)) - if (src.stat & BROKEN) - user << "\blue The broken glass falls out." - var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) - new /obj/item/weapon/shard( src.loc ) - var/obj/item/weapon/circuitboard/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( A ) - for (var/obj/C in src) - C.loc = src.loc - A.circuit = M - A.state = 3 - A.icon_state = "3" - A.anchored = 1 - del(src) - else - user << "\blue You disconnect the monitor." - var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) - var/obj/item/weapon/circuitboard/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( A ) - for (var/obj/C in src) - C.loc = src.loc - A.circuit = M - A.state = 4 - A.icon_state = "4" - A.anchored = 1 - del(src) - -*/ - if(istype(D, /obj/item/weapon/card/emag) && !emagged) + return + +/obj/machinery/computer/HolodeckControl/emag_act(user as mob) + if(!emagged) playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) emagged = 1 user << "\blue You vastly increase projector power and override the safety and security protocols." user << "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator." log_game("[key_name(usr)] emagged the Holodeck Control Computer") - src.updateUsrDialog() - return + src.updateUsrDialog() /obj/machinery/computer/HolodeckControl/New() ..() diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 972d3e6a2ca..d4da0df2e54 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -145,6 +145,9 @@ /obj/machinery/computer/arcade/battle/Topic(href, href_list) if(..()) return 1 + + if(usr.machine != src) + return 0 if (!src.blocked && !src.gameover) if (href_list["attack"]) @@ -269,8 +272,8 @@ return -/obj/machinery/computer/arcade/battle/attackby(I as obj, user as mob) - if(istype(I, /obj/item/weapon/card/emag) && !emagged) +/obj/machinery/computer/arcade/battle/emag_act(user as mob) + if(!emagged) temp = "If you die in the game, you die for real!" player_hp = 30 player_mp = 10 @@ -284,14 +287,7 @@ enemy_name = "Cuban Pete" name = "Outbomb Cuban Pete" - src.updateUsrDialog() - else - - ..() - - - /obj/machinery/computer/arcade/orion_trail name = "The Orion Trail" @@ -406,6 +402,8 @@ /obj/machinery/computer/arcade/orion_trail/Topic(href, href_list) if(..()) return 1 + if(usr.machine != src) + return 0 if(href_list["close"]) usr.unset_machine() usr << browse(null, "window=arcade") @@ -566,4 +564,5 @@ /obj/machinery/computer/arcade/orion_trail/proc/win() playing = 0 + turns = 0 prizevend() diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm index fb3c74e292d..bce0006f488 100644 --- a/code/game/machinery/computer/atmos_control.dm +++ b/code/game/machinery/computer/atmos_control.dm @@ -37,15 +37,16 @@ return ui_interact(user) -/obj/machinery/computer/atmoscontrol/attackby(var/obj/item/I as obj, var/mob/user as mob) - if(istype(I, /obj/item/weapon/card/emag) && !emagged) - user.visible_message("\red \The [user] swipes \a [I] through \the [src], causing the screen to flash!",\ - "\red You swipe your [I] through \the [src], the screen flashing as you gain full control.",\ +/obj/machinery/computer/atmoscontrol/emag_act(user as mob) + if(!emagged) + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + H.visible_message("\red \The [user] swipes \a card through \the [src], causing the screen to flash!",\ + "\red You swipe your card through \the [src], the screen flashing as you gain full control.",\ "You hear the swipe of a card through a reader, and an electronic warble.") emagged = 1 overridden = 1 - return - return ..() /obj/machinery/computer/atmoscontrol/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null) if(user.stat && !isobserver(user)) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 403c11ca3f4..3a035c3ef7d 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -55,25 +55,21 @@ // Network configuration attackby(I as obj, user as mob) access = list() - if(istype(I,/obj/item/weapon/card/emag)) // If hit by an emag. - var/obj/item/weapon/card/emag/E = I - if(!emagged) - if(E.uses) - E.uses-- - emagged = 1 - user << "\blue You have authorized full network access!" - ui_interact(user) - else - ui_interact(user) - else - ui_interact(user) - else if(istype(I,/obj/item/weapon/card/id)) // If hit by a regular ID card. + if(istype(I,/obj/item/weapon/card/id)) // If hit by a regular ID card. var/obj/item/weapon/card/id/E = I access = E.access ui_interact(user) else ..() + emag_act(user as mob) + if(!emagged) + emagged = 1 + user << "\blue You have authorized full network access!" + ui_interact(user) + else + ui_interact(user) + ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) if(src.z > 6) return if(stat & (NOPOWER|BROKEN)) return @@ -126,9 +122,6 @@ break data["networks"] = tempnets - if(ui) - ui.load_cached_data(camera_cache) - ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "sec_camera.tmpl", "Camera Console", 900, 800) diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 3ac81dfa985..e5aeabf72ae 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -55,14 +55,20 @@ var/shuttle_call/shuttle_calls[0] var/stat_msg1 var/stat_msg2 var/display_type="blank" + + var/datum/announcement/priority/crew_announcement = new l_color = "#0000FF" + +/obj/machinery/computer/communications/New() + ..() + crew_announcement.newscast = 1 /obj/machinery/computer/communications/Topic(href, href_list) if(..(href, href_list)) return 1 - if (!(src.z in list(STATION_Z,CENTCOMM_Z))) + if ((!(src.z in config.station_levels) && !(src.z in config.admin_levels))) usr << "\red Unable to establish a connection: \black You're too far away from the station!" return @@ -83,10 +89,12 @@ var/shuttle_call/shuttle_calls[0] if (I && istype(I)) if(src.check_access(I)) authenticated = 1 - if(20 in I.access) + if(access_captain in I.access) authenticated = 2 + crew_announcement.announcer = GetNameAndAssignmentFromId(I) if("logout") authenticated = 0 + crew_announcement.announcer = "" setMenuState(usr,COMM_SCREEN_MAIN) // ALART LAVUL @@ -127,14 +135,14 @@ var/shuttle_call/shuttle_calls[0] usr << "You need to swipe your ID." if("announce") - if(src.authenticated==2 && !issilicon(usr)) - if(message_cooldown) return - var/input = stripped_input(usr, "Please choose a message to announce to the station crew.", "What?") + if(src.authenticated==2) + if(message_cooldown) + usr << "Please allow at least one minute to pass between announcements" + return + var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement") if(!input || !(usr in view(1,src))) return - captain_announce(input)//This should really tell who is, IE HoP, CE, HoS, RD, Captain - log_say("[key_name(usr)] has made a captain announcement: [input]") - message_admins("[key_name_admin(usr)] has made a captain announcement.", 1) + crew_announcement.Announce(input) message_cooldown = 1 spawn(600)//One minute cooldown message_cooldown = 0 @@ -204,7 +212,7 @@ var/shuttle_call/shuttle_calls[0] if(centcomm_message_cooldown) usr << "Arrays recycling. Please stand by." return - var/input = stripped_input(usr, "Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "") + var/input = input(usr, "Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "") if(!input || !(usr in view(1,src))) return Centcomm_announce(input, usr) @@ -240,12 +248,11 @@ var/shuttle_call/shuttle_calls[0] return 1 -/obj/machinery/computer/communications/attackby(var/obj/I as obj, var/mob/user as mob) - if(istype(I,/obj/item/weapon/card/emag/)) +/obj/machinery/computer/communications/emag_act(user as mob) + if(!emagged) src.emagged = 1 user << "You scramble the communication routing circuits!" - ..() - + /obj/machinery/computer/communications/attack_ai(var/mob/user as mob) return src.attack_hand(user) @@ -399,7 +406,7 @@ var/shuttle_call/shuttle_calls[0] return if(emergency_shuttle.going_to_centcom()) - user << "The shuttle may not be called while returning to CentCom." + user << "The shuttle may not be called while returning to Central Command." return if(emergency_shuttle.online()) @@ -409,11 +416,11 @@ var/shuttle_call/shuttle_calls[0] // if force is 0, some things may stop the shuttle call if(!force) if(emergency_shuttle.deny_shuttle) - user << "Centcom does not currently have a shuttle available in your sector. Please try again later." + user << "Central Command does not currently have a shuttle available in your sector. Please try again later." return if(sent_strike_team == 1) - user << "Centcom will not allow the shuttle to be called. Consider all contracts terminated." + user << "Central Command will not allow the shuttle to be called. Consider all contracts terminated." return if(world.time < 54000) // 30 minute grace period to let the game get going @@ -427,8 +434,6 @@ var/shuttle_call/shuttle_calls[0] emergency_shuttle.call_transfer() log_game("[key_name(user)] has called the shuttle.") message_admins("[key_name_admin(user)] has called the shuttle - [formatJumpTo(user)].", 1) - captain_announce("A crew transfer has been initiated. The shuttle has been called. It will arrive in [round(emergency_shuttle.estimate_arrival_time()/60)] minutes.") - return diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index c459b3d1e1a..084eb974688 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -1,18 +1,15 @@ /obj/machinery/computer/crew - name = "Crew Monitoring Computer" + name = "crew monitoring computer" desc = "Used to monitor active health sensors built into most of the crew's uniforms." icon_state = "crew" use_power = 1 idle_power_usage = 250 active_power_usage = 500 circuit = "/obj/item/weapon/circuitboard/crew" - var/list/tracked = list( ) - - l_color = "#0000FF" - + var/obj/nano_module/crew_monitor/crew_monitor /obj/machinery/computer/crew/New() - tracked = list() + crew_monitor = new(src) ..() @@ -27,6 +24,8 @@ return ui_interact(user) +/obj/machinery/computer/crew/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + crew_monitor.ui_interact(user, ui_key, ui, force_open) /obj/machinery/computer/crew/update_icon() @@ -40,100 +39,5 @@ icon_state = initial(icon_state) stat &= ~NOPOWER - -/obj/machinery/computer/crew/Topic(href, href_list) - if(..()) - return 1 - if (src.z > 6) - usr << "\red Unable to establish a connection: \black You're too far away from the station!" - return 0 - if( href_list["close"] ) - var/mob/user = usr - var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main") - usr.unset_machine() - ui.close() - return 0 - if(href_list["update"]) - src.updateDialog() - return 1 - /obj/machinery/computer/crew/interact(mob/user) - ui_interact(user) - -/obj/machinery/computer/crew/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - if(stat & (BROKEN|NOPOWER)) - return - user.set_machine(src) - src.scan() - - var/data[0] - var/list/crewmembers = list() - - for(var/obj/item/clothing/under/C in src.tracked) - - - var/turf/pos = get_turf(C) - - if((C) && (C.has_sensor) && (pos) && (pos.z == src.z) && C.sensor_mode) - if(istype(C.loc, /mob/living/carbon/human)) - - var/mob/living/carbon/human/H = C.loc - - var/list/crewmemberData = list() - - crewmemberData["sensor_type"] = C.sensor_mode - crewmemberData["dead"] = H.stat > 1 - crewmemberData["oxy"] = round(H.getOxyLoss(), 1) - crewmemberData["tox"] = round(H.getToxLoss(), 1) - crewmemberData["fire"] = round(H.getFireLoss(), 1) - crewmemberData["brute"] = round(H.getBruteLoss(), 1) - - crewmemberData["name"] = "Unknown" - crewmemberData["rank"] = "Unknown" - if(H.wear_id && istype(H.wear_id, /obj/item/weapon/card/id) ) - var/obj/item/weapon/card/id/I = H.wear_id - crewmemberData["name"] = I.name - crewmemberData["rank"] = I.rank - else if(H.wear_id && istype(H.wear_id, /obj/item/device/pda) ) - var/obj/item/device/pda/P = H.wear_id - crewmemberData["name"] = (P.id ? P.id.name : "Unknown") - crewmemberData["rank"] = (P.id ? P.id.rank : "Unknown") - var/area/A = get_area(H) - crewmemberData["area"] = sanitize(A.name) - crewmemberData["x"] = pos.x - crewmemberData["y"] = pos.y - - // Works around list += list2 merging lists; it's not pretty but it works - crewmembers += "temporary item" - crewmembers[crewmembers.len] = crewmemberData - - crewmembers = sortByKey(crewmembers, "name") - - data["crewmembers"] = crewmembers - - ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "crew_monitor.tmpl", "Crew Monitoring Computer", 900, 800) - - // adding a template with the key "mapContent" enables the map ui functionality - ui.add_template("mapContent", "crew_monitor_map_content.tmpl") - // adding a template with the key "mapHeader" replaces the map header content - ui.add_template("mapHeader", "crew_monitor_map_header.tmpl") - - // we want to show the map by default - ui.set_show_map(1) - - ui.set_initial_data(data) - ui.open() - - // should make the UI auto-update; doesn't seem to? - ui.set_auto_update(1) - - -/obj/machinery/computer/crew/proc/scan() - for(var/mob/living/carbon/human/H in mob_list) - if(istype(H.w_uniform, /obj/item/clothing/under)) - var/obj/item/clothing/under/C = H.w_uniform - if (C.has_sensor) - tracked |= C - return 1 + crew_monitor.ui_interact(user) \ No newline at end of file diff --git a/code/game/machinery/computer/honkputer.dm b/code/game/machinery/computer/honkputer.dm index 9efed74b7c9..79ce2e97edf 100644 --- a/code/game/machinery/computer/honkputer.dm +++ b/code/game/machinery/computer/honkputer.dm @@ -17,7 +17,7 @@ /obj/machinery/computer/HONKputer/Topic(href, href_list) if(..()) return 1 - if (src.z > 1) + if (!(src.z in config.station_levels)) usr << "\red Unable to establish a connection: \black You're too far away from the station!" return usr.set_machine(src) @@ -57,12 +57,10 @@ src.updateUsrDialog() -/obj/machinery/computer/HONKputer/attackby(var/obj/I as obj, var/mob/user as mob) - if(istype(I,/obj/item/weapon/card/emag/)) +/obj/machinery/computer/HONKputer/emag_act(user as mob) + if(!emagged) src.emagged = 1 user << "You scramble the login circuits, allowing anyone to use the console!" - ..() - /obj/machinery/computer/HONKputer/attack_hand(var/mob/user as mob) if(..()) diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index 37ab61fc857..916b99e05c9 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -41,24 +41,6 @@ return if(!istype(user)) return - if(istype(O,/obj/item/weapon/card/emag/)) - // Will create sparks and print out the console's password. You will then have to wait a while for the console to be back online. - // It'll take more time if there's more characters in the password.. - if(!emag) - if(!isnull(src.linkedServer)) - icon_state = hack_icon // An error screen I made in the computers.dmi - emag = 1 - screen = 2 - spark_system.set_up(5, 0, src) - src.spark_system.start() - var/obj/item/weapon/paper/monitorkey/MK = new/obj/item/weapon/paper/monitorkey - MK.loc = src.loc - // Will help make emagging the console not so easy to get away with. - MK.info += "

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

£%@%(*$%&(£&?*(%&£/{}" + spawn(100*length(src.linkedServer.decryptkey)) UnmagConsole() + message = rebootmsg + else + user << "A no server error appears on the screen." /obj/machinery/computer/message_monitor/update_icon() ..() diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm index 11b71274ca6..8340838f6e2 100644 --- a/code/game/machinery/computer/prisoner.dm +++ b/code/game/machinery/computer/prisoner.dm @@ -65,7 +65,7 @@ if(!T.implanted) continue var/loc_display = "Unknown" var/mob/living/carbon/M = T.imp_in - if(M.z == 1 && !istype(M.loc, /turf/space)) + if((M.z in config.station_levels) && !istype(M.loc, /turf/space)) var/turf/mob_loc = get_turf_loc(M) loc_display = mob_loc.loc if(T.malfunction) diff --git a/code/game/machinery/computer/shuttle.dm b/code/game/machinery/computer/shuttle.dm index 0815cf7932a..93b4c91c2c9 100644 --- a/code/game/machinery/computer/shuttle.dm +++ b/code/game/machinery/computer/shuttle.dm @@ -56,11 +56,13 @@ world << "\blue All authorizations to shortening time for shuttle launch have been revoked!" src.authorized.len = 0 src.authorized = list( ) - - else if (istype(W, /obj/item/weapon/card/emag) && !emagged) + return + + emag_act(user as mob) + if (!emagged) var/choice = alert(user, "Would you like to launch the shuttle?","Shuttle control", "Launch", "Cancel") - if(!emagged && !emergency_shuttle.location() && user.get_active_hand() == W) + if(!emagged && !emergency_shuttle.location()) switch(choice) if("Launch") world << "\blue Alert: Shuttle launch time shortened to 10 seconds!" @@ -68,4 +70,3 @@ emagged = 1 if("Cancel") return - return diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index c00668a7276..94ded8abee1 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -158,7 +158,7 @@ for reference: src.icon_state = "barrier[src.locked]" attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/card/id/)) + if (istype(W, /obj/item/weapon/card/id)) if (src.allowed(user)) if (src.emagged < 2.0) src.locked = !src.locked @@ -177,24 +177,6 @@ for reference: visible_message("\red BZZzZZzZZzZT") return return - else if (istype(W, /obj/item/weapon/card/emag)) - if (src.emagged == 0) - src.emagged = 1 - src.req_access = null - user << "You break the ID authentication lock on the [src]." - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(2, 1, src) - s.start() - visible_message("\red BZZzZZzZZzZT") - return - else if (src.emagged == 1) - src.emagged = 2 - user << "You short out the anchoring mechanism on the [src]." - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(2, 1, src) - s.start() - visible_message("\red BZZzZZzZZzZT") - return else if (istype(W, /obj/item/weapon/wrench)) if (src.health < src.maxhealth) src.health = src.maxhealth @@ -218,6 +200,23 @@ for reference: if (src.health <= 0) src.explode() ..() + + emag_act(user as mob) + if (!emagged) + emagged = 1 + req_access = null + user << "You break the ID authentication lock on the [src]." + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, src) + s.start() + visible_message("\red BZZzZZzZZzZT") + else if (src.emagged == 1) + src.emagged = 2 + user << "You short out the anchoring mechanism on the [src]." + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, src) + s.start() + visible_message("\red BZZzZZzZZzZT") ex_act(severity) switch(severity) diff --git a/code/game/machinery/door_control.dm b/code/game/machinery/door_control.dm index 2dcb0c0b2e0..84591381582 100644 --- a/code/game/machinery/door_control.dm +++ b/code/game/machinery/door_control.dm @@ -57,11 +57,14 @@ */ if(istype(W, /obj/item/device/detective_scanner)) return - if(istype(W, /obj/item/weapon/card/emag)) + return src.attack_hand(user) + +/obj/machinery/door_control/emag_act(user as mob) + if(!emagged) + emagged = 1 req_access = list() req_one_access = list() playsound(src.loc, "sparks", 100, 1) - return src.attack_hand(user) /obj/machinery/door_control/attack_hand(mob/user as mob) src.add_fingerprint(usr) diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 88d72fbf8b9..10123890da7 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -153,10 +153,7 @@ if(!src.requiresID()) user = null if(src.density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade))) - flick("door_spark", src) - sleep(6) - open() - operating = -1 + emag_act(user) return 1 if(src.allowed(user) || src.emergency == 1) if(src.density) @@ -168,6 +165,13 @@ flick("door_deny", src) return +/obj/machinery/door/emag_act(user as mob) + if(density) + flick("door_spark", src) + sleep(6) + open() + operating = -1 + return 1 /obj/machinery/door/blob_act() if(prob(40)) diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 84563748126..429bc886068 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -225,21 +225,13 @@ /obj/machinery/door/window/attack_hand(mob/user as mob) return src.attackby(user, user) -/obj/machinery/door/window/attackby(obj/item/weapon/I as obj, mob/living/user as mob) - - //If it's in the process of opening/closing, ignore the click - if (src.operating) - return - - add_fingerprint(user) - - //Emags and ninja swords? You may pass. - if (src.density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade))) +/obj/machinery/door/window/emag_act(user as mob, weapon as obj) + if(density) src.operating = -1 flick("[src.base_state]spark", src) sleep(6) desc += "
Its access panel is smoking slightly." - if(istype(I, /obj/item/weapon/melee/energy/blade)) + if(istype(weapon, /obj/item/weapon/melee/energy/blade)) var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() spark_system.set_up(5, 0, src.loc) spark_system.start() @@ -252,6 +244,19 @@ open() emagged = 1 return 1 + +/obj/machinery/door/window/attackby(obj/item/weapon/I as obj, mob/living/user as mob) + + //If it's in the process of opening/closing, ignore the click + if (src.operating) + return + + add_fingerprint(user) + + //Ninja swords? You may pass. + if (src.density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade))) + emag_act(user,I) + return 1 if(istype(I, /obj/item/weapon/screwdriver)) if(src.density || src.operating) diff --git a/code/game/machinery/floodlight.dm b/code/game/machinery/floodlight.dm index 419b5f7b664..5a6544ba646 100644 --- a/code/game/machinery/floodlight.dm +++ b/code/game/machinery/floodlight.dm @@ -4,6 +4,7 @@ name = "Emergency Floodlight" icon = 'icons/obj/machines/floodlight.dmi' icon_state = "flood00" + anchored = 0 density = 1 var/on = 0 var/obj/item/weapon/stock_parts/cell/high/cell = null @@ -63,6 +64,21 @@ /obj/machinery/floodlight/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/wrench)) + if (!anchored && !isinspace()) + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + user.visible_message( \ + "[user] tightens \the [src]'s casters.", \ + " You have tightened \the [src]'s casters.", \ + "You hear ratchet.") + anchored = 1 + else if(anchored) + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + user.visible_message( \ + "[user] loosens \the [src]'s casters.", \ + " You have loosened \the [src]'s casters.", \ + "You hear ratchet.") + anchored = 0 if (istype(W, /obj/item/weapon/screwdriver)) if (!open) if(unlocked) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index 17127b65378..4063396f5c5 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -37,6 +37,13 @@ /obj/machinery/iv_drip/MouseDrop(over_object, src_location, over_location) ..() + + if(!ishuman(usr) && !isrobot(usr)) + return + + var/turf/T = get_turf(src) + if(!usr in range(1, T)) + return if(attached) visible_message("[src.attached] is detached from \the [src]") @@ -133,6 +140,7 @@ /obj/machinery/iv_drip/verb/toggle_mode() set name = "Toggle Mode" + set category = "Object" set src in view(1) if(!istype(usr, /mob/living)) diff --git a/code/game/machinery/metaldetector.dm b/code/game/machinery/metaldetector.dm index 3d7ccb4ab3b..72be4f67785 100644 --- a/code/game/machinery/metaldetector.dm +++ b/code/game/machinery/metaldetector.dm @@ -27,11 +27,6 @@ return 1 /obj/machinery/metaldetector/attackby(obj/item/W as obj, mob/user as mob) - if(istype(W, /obj/item/weapon/card/emag)) - if(!src.emagged) - src.emagged = 1 - user << "\blue You short out the circuitry." - return if(istype(W, /obj/item/weapon/card)) for(var/ID in list(user.equipped(), user:wear_id, user:belt)) if(src.check_access(ID,list("20"))) @@ -46,6 +41,12 @@ else user << "\red You lack access to the control panel!" return + +/obj/machinery/metaldetector/emag_act(user as mob) + if(!emagged) + emagged = 1 + user << "\blue You short out the circuitry." + return /obj/machinery/metaldetector/Crossed(AM as mob|obj) if(emagged) diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index 1c7f8ee64a0..dd0e408fd60 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -5,6 +5,7 @@ /datum/feed_message var/author ="" var/body ="" + var/message_type ="Story" //var/parent_channel var/backup_body ="" var/backup_author ="" @@ -39,6 +40,12 @@ src.backup_author = "" src.censored = 0 src.is_admin_channel = 0 + +/datum/feed_channel/proc/announce_news() + return "Breaking news from [channel_name]!" + +/datum/feed_channel/station/announce_news() + return "New Station Announcement Available" /datum/feed_network var/list/datum/feed_channel/network_channels = list() @@ -213,7 +220,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co switch(screen) if(0) dat += {"Welcome to Newscasting Unit #[src.unit_no].
Interface & News networks Operational. -
Property of Nanotransen Inc"} +
Property of Nanotrasen"} if(news_network.wanted_issue) dat+= "
Read Wanted Issue" dat+= {"

Create Feed Channel @@ -248,7 +255,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co dat+="No feed messages found in channel...

" else for(var/datum/feed_message/MESSAGE in CHANNEL.messages) - dat+="-[MESSAGE.body]
\[Story by [MESSAGE.author]\]
"*/ + dat+="-[MESSAGE.body]
\[[MESSAGE.message_type] by [MESSAGE.author]\]
"*/ dat+="

Refresh" dat+="
Back" @@ -334,7 +341,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co if(MESSAGE.img) usr << browse_rsc(MESSAGE.img, "tmp_photo[i].png") dat+="

" - dat+="\[Story by [MESSAGE.author]\]
" + dat+="\[[MESSAGE.message_type] by [MESSAGE.author]\]
" dat+="

Refresh" dat+="
Back" if(10) @@ -369,7 +376,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co dat+="No feed messages found in channel...
" else for(var/datum/feed_message/MESSAGE in src.viewing_channel.messages) - dat+="-[MESSAGE.body]
\[Story by [MESSAGE.author]\]
" + dat+="-[MESSAGE.body]
\[[MESSAGE.message_type] by [MESSAGE.author]\]
" dat+="[(MESSAGE.body == "\[REDACTED\]") ? ("Undo story censorship") : ("Censor story")] - [(MESSAGE.author == "\[REDACTED\]") ? ("Undo Author Censorship") : ("Censor message Author")]
" dat+="
Back" if(13) @@ -383,7 +390,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co dat+="No feed messages found in channel...
" else for(var/datum/feed_message/MESSAGE in src.viewing_channel.messages) - dat+="-[MESSAGE.body]
\[Story by [MESSAGE.author]\]
" + dat+="-[MESSAGE.body]
\[[MESSAGE.message_type] by [MESSAGE.author]\]
" dat+="
Back" if(14) @@ -516,7 +523,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co src.updateUsrDialog() else if(href_list["set_new_message"]) - src.msg = strip_html(input(usr, "Write your Feed story", "Network Channel Handler", "")) + src.msg = strip_html(input(usr, "Write your feed story", "Network Channel Handler", "")) while (findtext(src.msg," ") == 1) src.msg = copytext(src.msg,2,lentext(src.msg)+1) src.updateUsrDialog() @@ -535,13 +542,15 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co if(photo) newMsg.img = photo.img feedback_inc("newscaster_stories",1) + var/announcement = "" for(var/datum/feed_channel/FC in news_network.network_channels) if(FC.channel_name == src.channel_name) FC.messages += newMsg //Adding message to the network's appropriate feed_channel + announcement = FC.announce_news() break src.screen=4 for(var/obj/machinery/newscaster/NEWSCASTER in allCasters) - NEWSCASTER.newsAlert(src.channel_name) + NEWSCASTER.newsAlert(announcement) src.updateUsrDialog() @@ -986,11 +995,11 @@ obj/item/weapon/newspaper/attackby(obj/item/weapon/W as obj, mob/user as mob) ///obj/machinery/newscaster/process() //Was thinking of doing the icon update through process, but multiple iterations per second does not // return //bode well with a newscaster network of 10+ machines. Let's just return it, as it's added in the machines list. -/obj/machinery/newscaster/proc/newsAlert(channel) //This isn't Agouri's work, for it is ugly and vile. +/obj/machinery/newscaster/proc/newsAlert(var/news_call) //This isn't Agouri's work, for it is ugly and vile. var/turf/T = get_turf(src) //Who the fuck uses spawn(600) anyway, jesus christ - if(channel) + if(news_call) for(var/mob/O in hearers(world.view-1, T)) - O.show_message("[src.name] beeps, \"Breaking news from [channel]!\"",2) + O.show_message("[src.name] beeps, \"[news_call]\"",2) src.alert = 1 src.update_icon() spawn(300) diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 73895ca2ec9..f4829b57416 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -307,20 +307,7 @@ Status: []
"}, del(src) - if ((istype(W, /obj/item/weapon/card/emag)) && (!src.emagged)) - // Emagging the turret makes it go bonkers and stun everyone. It also makes - // the turret shoot much, much faster. - - user << "\red You short out [src]'s threat assessment circuits." - spawn(0) - for(var/mob/O in hearers(src, null)) - O.show_message("\red [src] hums oddly...", 1) - emagged = 1 - src.on = 0 // turns off the turret temporarily - sleep(60) // 6 seconds for the traitor to gtfo of the area before the turret decides to ruin his shit - on = 1 // turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here - - else if((istype(W, /obj/item/weapon/wrench)) && (!on)) + if((istype(W, /obj/item/weapon/wrench)) && (!on)) if(raised) return // This code handles moving the turret around. After all, it's a portable turret! @@ -359,7 +346,19 @@ Status: []
"}, attacked = 0 ..() +/obj/machinery/porta_turret/emag_act(user as mob) + if(!src.emagged) + // Emagging the turret makes it go bonkers and stun everyone. It also makes + // the turret shoot much, much faster. + user << "\red You short out [src]'s threat assessment circuits." + spawn(0) + for(var/mob/O in hearers(src, null)) + O.show_message("\red [src] hums oddly...", 1) + emagged = 1 + src.on = 0 // turns off the turret temporarily + sleep(60) // 6 seconds for the traitor to gtfo of the area before the turret decides to ruin his shit + on = 1 // turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here /obj/machinery/porta_turret/bullet_act(var/obj/item/projectile/Proj) if(on) diff --git a/code/game/machinery/programmable_unloader.dm b/code/game/machinery/programmable_unloader.dm index e7039af7f64..f2aaefc03fa 100644 --- a/code/game/machinery/programmable_unloader.dm +++ b/code/game/machinery/programmable_unloader.dm @@ -196,19 +196,6 @@ return /obj/machinery/programmable/attackby(obj/item/I as obj, mob/user as mob) - if(istype(I,/obj/item/weapon/card/emag)) - if(emagged) - return - user << "You swipe the unloader with your card. After a moment's grinding, it beeps in a sinister fashion." - playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) - emagged = 1 - overrides += emag_overrides - - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(2, 1, src) - s.start() - - return if(istype(I,/obj/item/weapon/wrench)) // code borrowed from pipe dispenser if (unwrenched==0) playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) @@ -281,7 +268,18 @@ I.loc = src RefreshParts() +/obj/machinery/programmable/emag_act(user as mob) + if(emagged) + return + user << "You swipe the unloader with your card. After a moment's grinding, it beeps in a sinister fashion." + playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) + emagged = 1 + overrides += emag_overrides + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, src) + s.start() + return /obj/machinery/programmable/process() if (!output || !input) diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index 5e39eba0d79..edfac0425a0 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -32,13 +32,7 @@ var/const/SAFETY_COOLDOWN = 100 /obj/machinery/recycler/attackby(var/obj/item/I, var/mob/user) - if(istype(I, /obj/item/weapon/card/emag) && !emagged) - emagged = 1 - if(safety_mode) - safety_mode = 0 - update_icon() - playsound(src.loc, "sparks", 75, 1, -1) - else if(istype(I, /obj/item/weapon/screwdriver) && emagged) + if(istype(I, /obj/item/weapon/screwdriver) && emagged) emagged = 0 update_icon() user << "You reset the crusher to its default factory settings." @@ -46,6 +40,14 @@ var/const/SAFETY_COOLDOWN = 100 ..() return add_fingerprint(user) + +/obj/machinery/recycler/emag_act(user as mob) + if(!emagged) + emagged = 1 + if(safety_mode) + safety_mode = 0 + update_icon() + playsound(src.loc, "sparks", 75, 1, -1) /obj/machinery/recycler/update_icon() ..() diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index d358e39c67f..16d7b16572e 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -55,6 +55,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() var/dpt = ""; //the department which will be receiving the message var/priority = -1 ; //Priority of the message being sent luminosity = 0 + var/datum/announcement/announcement = new /obj/machinery/requests_console/power_change() ..() @@ -70,6 +71,10 @@ var/list/obj/machinery/requests_console/allConsoles = list() /obj/machinery/requests_console/New() ..() + + announcement.title = "[department] announcement" + announcement.newscast = 1 + name = "[department] Requests Console" allConsoles += src //req_console_departments += department @@ -189,7 +194,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() else //main menu screen = 0 - announceAuth = 0 + reset_announce() if (newmessagepriority == 1) dat += text("There are new messages
") if (newmessagepriority == 2) @@ -240,17 +245,13 @@ var/list/obj/machinery/requests_console/allConsoles = list() if("2") priority = 2 else priority = -1 else - message = "" - announceAuth = 0 + reset_announce() screen = 0 if(href_list["sendAnnouncement"]) if(!announcementConsole) return - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << "[department] announcement: [message]" - announceAuth = 0 - message = "" + announcement.Announce(message) + reset_announce() screen = 0 if( href_list["department"] && message ) @@ -389,8 +390,9 @@ var/list/obj/machinery/requests_console/allConsoles = list() var/obj/item/weapon/card/id/ID = O if (access_RC_announce in ID.GetAccess()) announceAuth = 1 + announcement.announcer = ID.assignment ? "[ID.assignment] [ID.registered_name]" : ID.registered_name else - announceAuth = 0 + reset_announce() user << "\red You are not authorized to send announcements." updateUsrDialog() if (istype(O, /obj/item/weapon/stamp)) @@ -399,3 +401,8 @@ var/list/obj/machinery/requests_console/allConsoles = list() msgStamped = text("Stamped with the [T.name]") updateUsrDialog() return + +/obj/machinery/requests_console/proc/reset_announce() + announceAuth = 0 + message = "" + announcement.announcer = "" diff --git a/code/game/machinery/slotmachine.dm b/code/game/machinery/slotmachine.dm index d2d93afba2c..54355179c8e 100644 --- a/code/game/machinery/slotmachine.dm +++ b/code/game/machinery/slotmachine.dm @@ -1,3 +1,4 @@ +var/datum/announcement/minor/slotmachine_announcement = new(do_log = 0) /obj/machinery/slot_machine name = "Slot Machine" desc = "Gambling for the antisocial." @@ -55,7 +56,7 @@ if (roll == 1) for(var/mob/O in hearers(src, null)) O.show_message(text("[] says, 'JACKPOT! You win [src.money]!'", src), 1) - command_alert("Congratulations [usr.name] on winning the Jackpot!", "Jackpot Winner") + slotmachine_announcement.Announce("Congratulations [usr.name] on winning the Jackpot!", "Jackpot Winner") usr.mind.initial_account.money += src.money src.money = 0 else if (roll > 1 && roll <= 10) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 1b05e84fe9f..0a0d9c32ebd 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -681,24 +681,6 @@ src.updateUsrDialog() return - else if(istype(I,/obj/item/weapon/card/emag)) - - if(emagged) - user << "\red The cycler has already been subverted." - return - - var/obj/item/weapon/card/emag/E = I - src.updateUsrDialog() - E.uses-- - - //Clear the access reqs, disable the safeties, and open up all paintjobs. - user << "\red You run the sequencer across the interface, corrupting the operating protocols." - departments = list("Engineering","Mining","Medical","Security","Atmos","^%###^%$") - emagged = 1 - safeties = 0 - req_access = list() - return - else if(istype(I,/obj/item/clothing/head/helmet/space)) if(locked) @@ -748,6 +730,19 @@ return ..() + +/obj/machinery/suit_cycler/emag_act(user as mob) + if(emagged) + user << "\red The cycler has already been subverted." + return + + //Clear the access reqs, disable the safeties, and open up all paintjobs. + user << "\red You run the sequencer across the interface, corrupting the operating protocols." + departments = list("Engineering","Mining","Medical","Security","Atmos","^%###^%$") + emagged = 1 + safeties = 0 + req_access = list() + return /obj/machinery/suit_cycler/attack_hand(mob/user as mob) diff --git a/code/game/machinery/telecomms/logbrowser.dm b/code/game/machinery/telecomms/logbrowser.dm index 9bd46e57ce7..ef50d3ea865 100644 --- a/code/game/machinery/telecomms/logbrowser.dm +++ b/code/game/machinery/telecomms/logbrowser.dm @@ -244,9 +244,11 @@ A.icon_state = "4" A.anchored = 1 del(src) - else if(istype(D, /obj/item/weapon/card/emag) && !emagged) + src.updateUsrDialog() + return + + emag_act(user as mob) + if(!emagged) playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) emagged = 1 user << "\blue You you disable the security protocols" - src.updateUsrDialog() - return diff --git a/code/game/machinery/telecomms/telemonitor.dm b/code/game/machinery/telecomms/telemonitor.dm index 995d0fc239f..c02ef59e1be 100644 --- a/code/game/machinery/telecomms/telemonitor.dm +++ b/code/game/machinery/telecomms/telemonitor.dm @@ -153,9 +153,11 @@ A.icon_state = "4" A.anchored = 1 del(src) - else if(istype(D, /obj/item/weapon/card/emag) && !emagged) - playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) - emagged = 1 - user << "\blue You you disable the security protocols" src.updateUsrDialog() return + + emag_act(user as mob) + if(!emagged) + playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) + emagged = 1 + user << "\blue You you disable the security protocols" \ No newline at end of file diff --git a/code/game/machinery/telecomms/traffic_control.dm b/code/game/machinery/telecomms/traffic_control.dm index fed56a35124..e2b42ddbb44 100644 --- a/code/game/machinery/telecomms/traffic_control.dm +++ b/code/game/machinery/telecomms/traffic_control.dm @@ -233,12 +233,14 @@ A.icon_state = "4" A.anchored = 1 del(src) - else if(istype(D, /obj/item/weapon/card/emag) && !emagged) + src.updateUsrDialog() + return + +/obj/machinery/computer/telecomms/traffic/emag_act(user as mob) + if(!emagged) playsound(get_turf(src), 'sound/effects/sparks4.ogg', 75, 1) emagged = 1 user << "\blue You you disable the security protocols" - src.updateUsrDialog() - return /obj/machinery/computer/telecomms/traffic/proc/canAccess(var/mob/user) if(issilicon(user) || in_range(user, src)) diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index e50b6a11280..d9afea3dd80 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -31,16 +31,7 @@ return power_station /obj/machinery/computer/teleporter/attackby(I as obj, mob/living/user as mob) - if(istype(I,/obj/item/weapon/card/emag)) // If hit by an emag. - var/obj/item/weapon/card/emag/E = I - if(!emagged) - if(E.uses) - E.uses-- - emagged = 1 - user << "\blue The teleporter can now lock on to Syndicate beacons!" - else - ui_interact(user) - else if(istype(I, /obj/item/device/gps)) + if(istype(I, /obj/item/device/gps)) var/obj/item/device/gps/L = I if(L.locked_location && !(stat & (NOPOWER|BROKEN))) if(!user.unEquip(L)) @@ -55,6 +46,13 @@ else ..() return + +/obj/machinery/computer/teleporter/emag_act(user as mob) + if(!emagged) + emagged = 1 + user << "\blue The teleporter can now lock on to Syndicate beacons!" + else + ui_interact(user) /obj/machinery/computer/teleporter/attack_paw(mob/user) usr << "You are too primitive to use this computer." @@ -82,7 +80,8 @@ data["calibrated"] = null data["accurate"] = null data["regime"] = regime_set - data["target"] = (!target) ? "None" : get_area(target) + var/area/targetarea = get_area(target) + data["target"] = (!target) ? "None" : sanitize(targetarea.name) data["calibrating"] = calibrating data["locked"] = locked @@ -181,7 +180,7 @@ var/turf/T = get_turf(R) if (!T) continue - if(T.z == 2 || T.z > 7) + if((T.z in config.admin_levels) || T.z > 7) continue if(R.syndicate == 1 && emagged == 0) continue @@ -202,7 +201,7 @@ continue var/turf/T = get_turf(M) if(!T) continue - if(T.z == 2) continue + if((T.z in config.admin_levels)) continue var/tmpname = M.real_name if(areaindex[tmpname]) tmpname = "[tmpname] ([++areaindex[tmpname]])" @@ -224,7 +223,7 @@ var/turf/T = get_turf(R) if (!T || !R.teleporter_hub || !R.teleporter_console) continue - if(T.z == 2 || T.z > 7) + if((T.z in config.admin_levels) || T.z > 7) continue var/tmpname = T.loc.name if(areaindex[tmpname]) diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm index 4f77d7d7c70..90dd7f27d71 100644 --- a/code/game/machinery/turrets.dm +++ b/code/game/machinery/turrets.dm @@ -364,15 +364,6 @@ if (istype(user, /mob/living/silicon)) return src.attack_hand(user) - if (istype(W, /obj/item/weapon/card/emag) && !emagged) - user << "\red You short out the turret controls' access analysis module." - emagged = 1 - locked = 0 - if(user.machine==src) - src.attack_hand(user) - - return - else if( get_dist(src, user) == 0 ) // trying to unlock the interface if (src.allowed(usr)) if(emagged) @@ -390,6 +381,17 @@ src.attack_hand(user) else user << "Access denied." + +/obj/machinery/turretid/emag_act(user as mob) + if (!emagged) + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + user << "\red You short out the turret controls' access analysis module." + emagged = 1 + locked = 0 + if(H.machine==src) + src.attack_hand(user) /obj/machinery/turretid/attack_ai(mob/user as mob) if(!ailock) diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index a2b95fed050..14fc57dd05c 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -1,17 +1,39 @@ -#define CAT_NORMAL 0 -#define CAT_HIDDEN 1 -#define CAT_COIN 2 +#define CAT_NORMAL 1 +#define CAT_HIDDEN 2 // also used in corresponding wires/vending.dm +#define CAT_COIN 4 +/** + * Datum used to hold information about a product in a vending machine + */ /datum/data/vending_product - var/product_name = "generic" + var/product_name = "generic" // Display name for the product var/product_path = null - var/amount = 0 + var/amount = 0 // Amount held in the vending machine var/max_amount = 0 - var/price = 0 - var/display_color = "blue" - var/category = CAT_NORMAL - + var/price = 0 // Price to buy one + var/display_color = null // Display color for vending machine listing + var/category = CAT_NORMAL // CAT_HIDDEN for contraband, CAT_COIN for premium + +/datum/data/vending_product/New(var/path, var/name = null, var/amount = 1, var/price = 0, var/color = null, var/category = CAT_NORMAL) + ..() + + src.product_path = path + + if(!name) + var/atom/tmp = new path + src.product_name = initial(tmp.name) + del(tmp) + else + src.product_name = name + + src.amount = amount + src.price = price + src.display_color = color + src.category = category +/** + * A vending machine + */ /obj/machinery/vending name = "Vendomat" desc = "A generic vending machine." @@ -20,39 +42,57 @@ layer = 2.9 anchored = 1 density = 1 + + var/icon_vend //Icon_state when vending + var/icon_deny //Icon_state when denying access + + // Power + use_power = 1 + idle_power_usage = 10 + var/vend_power_usage = 150 + + // Vending-related var/active = 1 //No sales pitches if off! - var/delay_product_spawn // If set, uses sleep() in product spawn proc (mostly for seeds to retrieve correct names). var/vend_ready = 1 //Are we ready to vend?? Is it time?? var/vend_delay = 10 //How long does it take to vend? - var/datum/data/vending_product/currently_vending = null // A /datum/data/vending_product instance of what we're paying for right now. + var/categories = CAT_NORMAL // Bitmask of cats we're currently showing + var/datum/data/vending_product/currently_vending = null // What we're requesting payment for right now + var/status_message = "" // Status screen messages like "insufficient funds", displayed in NanoUI + var/status_error = 0 // Set to 1 if status_message is an error // To be filled out at compile time var/list/products = list() // For each, use the following pattern: var/list/contraband = list() // list(/type/path = amount,/type/path2 = amount2) var/list/premium = list() // No specified amount = only one in stock var/list/prices = list() // Prices for each item, list(/type/path = price), items not in the list don't have a price. - - var/product_slogans = "" //String of slogans separated by semicolons, optional - var/product_ads = "" //String of small ad messages in the vending screen - random chance + + // List of vending_product items available. var/list/product_records = list() var/list/hidden_records = list() - var/list/coin_records = list() + + // // Variables used to initialize advertising + var/product_slogans = "" //String of slogans separated by semicolons, optional + var/product_ads = "" //String of small ad messages in the vending screen - random chance + + var/list/ads_list = list() + + // Stuff relating vocalizations var/list/slogan_list = list() - var/list/small_ads = list() //Small ad messages in the vending screen - random chance of popping up whenever you open it var/vend_reply //Thank you for shopping! + var/shut_up = 0 //Stop spouting those godawful pitches! var/last_reply = 0 - var/obj/item/weapon/vending_refill/refill_canister = null //The type of refill canisters used by this machine. var/last_slogan = 0 //When did we last pitch? var/slogan_delay = 6000 //How long until we can pitch again? - var/icon_vend //Icon_state when vending! - var/icon_deny //Icon_state when vending! - //var/emagged = 0 //Ignores if somebody doesn't have card access to that machine. + + var/obj/item/weapon/vending_refill/refill_canister = null //The type of refill canisters used by this machine. + + // Things that can go wrong + emagged = 0 //Ignores if somebody doesn't have card access to that machine. var/seconds_electrified = 0 //Shock customers like an airlock. var/shoot_inventory = 0 //Fire items at customers! We're broken! var/shoot_speed = 3 //How hard are we firing the items? var/shoot_chance = 2 //How often are we firing the items? - var/shut_up = 0 //Stop spouting those godawful pitches! - var/extended_inventory = 0 //can we access the hidden inventory? + var/scan_id = 1 var/obj/item/weapon/coin/coin var/datum/wires/vending/wires = null @@ -60,32 +100,57 @@ /obj/machinery/vending/New() ..() wires = new(src) - spawn(4) - src.slogan_list = text2list(src.product_slogans, ";") + spawn(50) + if(src.product_slogans) + src.slogan_list += text2list(src.product_slogans, ";") - // So not all machines speak at the exact same time. - // The first time this machine says something will be at slogantime + this random value, - // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. - src.last_slogan = world.time + rand(0, slogan_delay) + // So not all machines speak at the exact same time. + // The first time this machine says something will be at slogantime + this random value, + // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. + src.last_slogan = world.time + rand(0, slogan_delay) - src.build_inventory(products) - //Add hidden inventory - src.build_inventory(contraband, 1) - src.build_inventory(premium, 0, 1) + if(src.product_ads) + src.ads_list += text2list(src.product_ads, ";") + + src.build_inventory() power_change() - - return return + +/** + * Build src.produdct_records from the products lists + * + * src.products, src.contraband, src.premium, and src.prices allow specifying + * products that the vending machine is to carry without manually populating + * src.product_records. + */ +/obj/machinery/vending/proc/build_inventory() + var/list/all_products = list( + list(src.products, CAT_NORMAL), + list(src.contraband, CAT_HIDDEN), + list(src.premium, CAT_COIN)) + for(var/current_list in all_products) + var/category = current_list[2] + + for(var/entry in current_list[1]) + var/datum/data/vending_product/product = new/datum/data/vending_product(entry) + + product.price = (entry in src.prices) ? src.prices[entry] : 0 + product.amount = (current_list[1][entry]) ? current_list[1][entry] : 1 + product.max_amount = product.amount + product.category = category + + src.product_records.Add(product) /obj/machinery/vending/Destroy() - del(wires) + del(wires) // qdel wires = null - del(coin) - coin = null + if(coin) + del(coin) // qdel + coin = null ..() /obj/machinery/vending/ex_act(severity) @@ -115,41 +180,6 @@ else del(src) - -/obj/machinery/vending/proc/build_inventory(var/list/productlist,hidden=0,req_coin=0,start_empty = null) - for(var/typepath in productlist) - var/amount = productlist[typepath] - var/price = prices[typepath] - if(isnull(amount)) amount = 1 - - var/atom/temp = new typepath(null) - var/datum/data/vending_product/R = new /datum/data/vending_product() - - R.product_path = typepath - if(!start_empty) - R.amount = amount - R.max_amount = amount - R.price = price - R.display_color = pick("red","blue","green") - if(hidden) - R.category=CAT_HIDDEN - hidden_records += R - else if(req_coin) - R.category=CAT_COIN - coin_records += R - else - R.category=CAT_NORMAL - product_records += R - - if(delay_product_spawn) - sleep(3) - R.product_name = temp.name - else - R.product_name = temp.name - -// world << "Added: [R.product_name]] - [R.amount] - [R.product_path]" - - /obj/machinery/vending/proc/refill_inventory(obj/item/weapon/vending_refill/refill, datum/data/vending_product/machine, mob/user) var/total = 0 @@ -180,10 +210,41 @@ return total /obj/machinery/vending/attackby(obj/item/weapon/W, mob/user) - if(panel_open) - if(default_unfasten_wrench(user, W, time = 60)) - return + if (currently_vending && vendor_account && !vendor_account.suspended) + var/paid = 0 + var/handled = 0 + if(istype(W, /obj/item/weapon/card/id)) + var/obj/item/weapon/card/id/C = W + paid = pay_with_card(C) + handled = 1 + else if (istype(W, /obj/item/weapon/spacecash)) + var/obj/item/weapon/spacecash/C = W + paid = pay_with_cash(C, user) + handled = 1 + if(paid) + src.vend(currently_vending, usr) + return + else if(handled) + nanomanager.update_uis(src) + return // don't smack that machine with your 2 thalers + + if(default_unfasten_wrench(user, W, time = 60)) + return + + if(istype(W, /obj/item/weapon/screwdriver) && anchored) + playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) + panel_open = !panel_open + user << "You [panel_open ? "open" : "close"] the maintenance panel." + overlays.Cut() + if(panel_open) + overlays += image(icon, "[initial(icon_state)]-panel") + nanomanager.update_uis(src) // Speaker switch is on the main UI, not wires UI + return + + if(panel_open) + if(istype(W, /obj/item/device/multitool)||istype(W, /obj/item/weapon/wirecutters)) + return attack_hand(user) if(component_parts && istype(W, /obj/item/weapon/crowbar)) var/datum/data/vending_product/machine = product_records for(var/datum/data/vending_product/machine_content in machine) @@ -194,32 +255,13 @@ if(!machine_content.amount) break default_deconstruction_crowbar(W) - - if(istype(W, /obj/item/weapon/card/emag)) - emagged = 1 - user << "You short out the product lock on [src]" - return - else if(istype(W, /obj/item/weapon/screwdriver) && anchored) - playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) - panel_open = !panel_open - user << "You [panel_open ? "open" : "close"] the maintenance panel." - overlays.Cut() - if(panel_open) - overlays += image(icon, "[initial(icon_state)]-panel") - updateUsrDialog() - return - else if(istype(W, /obj/item/device/multitool)||istype(W, /obj/item/weapon/wirecutters)) - if(panel_open) - attack_hand(user) - return - else if(istype(W, /obj/item/weapon/card) && currently_vending) - var/obj/item/weapon/card/I = W - scan_card(I) - else if(istype(W, /obj/item/weapon/coin) && premium.len > 0) + if(istype(W, /obj/item/weapon/coin) && premium.len > 0) user.drop_item() W.loc = src coin = W - user << "You insert [W] into [src]." + categories |= CAT_COIN + user << "\blue You insert the [W] into the [src]" + nanomanager.update_uis(src) return else if(istype(W, refill_canister) && refill_canister != null) if(stat & (BROKEN|NOPOWER)) @@ -240,176 +282,189 @@ user << "You should probably unscrew the service panel first." else ..() + +/obj/machinery/vending/emag_act(user as mob) + emagged = 1 + user << "You short out the product lock on [src]" + return +/** + * Receive payment with cashmoney. + * + * usr is the mob who gets the change. + */ +/obj/machinery/vending/proc/pay_with_cash(var/obj/item/weapon/spacecash/cashmoney, mob/user) + if(currently_vending.price > cashmoney.worth) + // This is not a status display message, since it's something the character + // themselves is meant to see BEFORE putting the money in + usr << "\icon[cashmoney] That is not enough money." + return 0 + + // Bills (banknotes) cannot really have worth different than face value, + // so we have to eat the bill and spit out change in a bundle + // This is really dirty, but there's no superclass for all bills, so we + // just assume that all spacecash that's not something else is a bill + visible_message("[usr] inserts a credit chip into [src].") + var/left = cashmoney.worth - currently_vending.price + usr.drop_from_inventory(cashmoney) + del(cashmoney) -/obj/machinery/vending/proc/scan_card(var/obj/item/weapon/card/I) - if(!currently_vending) return - if (istype(I, /obj/item/weapon/card/id)) - var/obj/item/weapon/card/id/C = I - visible_message("[usr] swipes a card through [src].") - if(vendor_account) - var/datum/money_account/D = attempt_account_access_nosec(C.associated_account_number) - if(D) - var/transaction_amount = currently_vending.price - if(transaction_amount <= D.money) + if(left) + dispense_cash(left, src.loc, user) - //transfer the money - D.money -= transaction_amount - vendor_account.money += transaction_amount + // Vending machines have no idea who paid with cash + credit_purchase("(cash)") + return 1 - //create entries in the two account transaction logs - var/datum/transaction/T = new() - T.target_name = "[vendor_account.owner_name] (via [src.name])" - T.purpose = "Purchase of [currently_vending.product_name]" - if(transaction_amount > 0) - T.amount = "([transaction_amount])" - else - T.amount = "[transaction_amount]" - T.source_terminal = src.name - T.date = current_date_string - T.time = worldtime2text() - D.transaction_log.Add(T) - // - T = new() - T.target_name = D.owner_name - T.purpose = "Purchase of [currently_vending.product_name]" - T.amount = "[transaction_amount]" - T.source_terminal = src.name - T.date = current_date_string - T.time = worldtime2text() - vendor_account.transaction_log.Add(T) +/** + * Scan a card and attempt to transfer payment from associated account. + * + * Takes payment for whatever is the currently_vending item. Returns 1 if + * successful, 0 if failed + */ +/obj/machinery/vending/proc/pay_with_card(var/obj/item/weapon/card/id/I) + visible_message("[usr] swipes a card through [src].") + var/datum/money_account/customer_account = attempt_account_access_nosec(I.associated_account_number) + if (!customer_account) + src.status_message = "Error: Unable to access account. Please contact technical support if problem persists." + src.status_error = 1 + return 0 - // Vend the item - src.vend(src.currently_vending, usr) - currently_vending = null - src.updateUsrDialog() - else - usr << "\icon[src]You don't have that much money!" - else - usr << "\icon[src]Unable to access account. Check security settings and try again." + if(customer_account.suspended) + src.status_message = "Unable to access account: account suspended." + src.status_error = 1 + return 0 + + // Have the customer punch in the PIN before checking if there's enough money. Prevents people from figuring out acct is + // empty at high security levels + if(customer_account.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2) + var/attempt_pin = input("Enter pin code", "Vendor transaction") as num + customer_account = attempt_account_access(I.associated_account_number, attempt_pin, 2) + + if(!customer_account) + src.status_message = "Unable to access account: incorrect credentials." + src.status_error = 1 + return 0 + + if(currently_vending.price > customer_account.money) + src.status_message = "Insufficient funds in account." + src.status_error = 1 + return 0 + else + // Okay to move the money at this point + + // debit money from the purchaser's account + customer_account.money -= currently_vending.price + + // create entry in the purchaser's account log + var/datum/transaction/T = new() + T.target_name = "[vendor_account.owner_name] (via [src.name])" + T.purpose = "Purchase of [currently_vending.product_name]" + if(currently_vending.price > 0) + T.amount = "([currently_vending.price])" else - usr << "\icon[src]Unable to access vendor account. Please record the machine ID and call CentComm Support." + T.amount = "[currently_vending.price]" + T.source_terminal = src.name + T.date = current_date_string + T.time = worldtime2text() + customer_account.transaction_log.Add(T) -/obj/machinery/vending/attack_paw(mob/user as mob) - return attack_hand(user) + // Give the vendor the money. We use the account owner name, which means + // that purchases made with stolen/borrowed card will look like the card + // owner made them + credit_purchase(customer_account.owner_name) + return 1 + +/** + * Add money for current purchase to the vendor account. + * + * Called after the money has already been taken from the customer. + */ +/obj/machinery/vending/proc/credit_purchase(var/target as text) + vendor_account.money += currently_vending.price + + var/datum/transaction/T = new() + T.target_name = target + T.purpose = "Purchase of [currently_vending.product_name]" + T.amount = "[currently_vending.price]" + T.source_terminal = src.name + T.date = current_date_string + T.time = worldtime2text() + vendor_account.transaction_log.Add(T) /obj/machinery/vending/attack_ai(mob/user as mob) return attack_hand(user) - -/obj/machinery/vending/proc/GetProductIndex(var/datum/data/vending_product/P) - var/list/plist - switch(P.category) - if(CAT_NORMAL) - plist=product_records - if(CAT_HIDDEN) - plist=hidden_records - if(CAT_COIN) - plist=coin_records - else - warning("UNKNOWN CATEGORY [P.category] IN TYPE [P.product_path] INSIDE [type]!") - return plist.Find(P) - -/obj/machinery/vending/proc/GetProductByID(var/pid, var/category) - switch(category) - if(CAT_NORMAL) - return product_records[pid] - if(CAT_HIDDEN) - return hidden_records[pid] - if(CAT_COIN) - return coin_records[pid] - else - warning("UNKNOWN PRODUCT: PID: [pid], CAT: [category] INSIDE [type]!") - return null + +/obj/machinery/vending/attack_paw(mob/user as mob) + return attack_hand(user) /obj/machinery/vending/attack_hand(mob/user as mob) if(stat & (BROKEN|NOPOWER)) return - user.set_machine(src) - if(seconds_electrified != 0) - if(shock(user, 100)) + if(src.seconds_electrified != 0) + if(src.shock(user, 100)) return - var/vendorname = (src.name) //import the machine's name + ui_interact(user) + wires.Interact(user) - if(src.currently_vending) - var/dat = "
[vendorname]


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

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

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


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

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

" - - if (src.product_records.len == 0) - dat += "No product loaded!" +/** + * Display the NanoUI window for the vending machine. + * + * See NanoUI documentation for details. + */ +/obj/machinery/vending/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) + + var/list/data = list() + if(currently_vending) + data["mode"] = 1 + data["product"] = currently_vending.product_name + data["price"] = currently_vending.price + data["message_err"] = 0 + data["message"] = src.status_message + data["message_err"] = src.status_error else - var/list/display_records = list() - display_records += src.product_records + data["mode"] = 0 + var/list/listed_products = list() - if(src.extended_inventory) - display_records += src.hidden_records - if(src.coin) - display_records += src.coin_records - - for (var/datum/data/vending_product/R in display_records) - - // AUTOFIXED BY fix_string_idiocy.py - // C:\Users\Rob\Documents\Projects\vgstation13\code\game\machinery\vending.dm:285: dat += "[R.product_name]:" - dat += {"[R.product_name]: - [R.amount] "} - // END AUTOFIX - if(R.price) - dat += " (Price: [R.price])" - if (R.amount > 0) - var/idx=GetProductIndex(R) - dat += " (Vend)" - else - dat += " SOLD OUT" - dat += "
" - - dat += "
" - - if(panel_open) - dat += wires() - - if(product_slogans != "") - dat += "The speaker switch is [shut_up ? "off" : "on"]. Toggle" - - user << browse(dat, "window=vending") - onclose(user, "") - return - -// returns the wire panel text -/obj/machinery/vending/proc/wires() - return wires.GetInteractWindow() + for(var/key = 1 to src.product_records.len) + var/datum/data/vending_product/I = src.product_records[key] + + if(!(I.category & src.categories)) + continue + + listed_products.Add(list(list( + "key" = key, + "name" = sanitize(I.product_name), + "price" = I.price, + "color" = I.display_color, + "amount" = I.amount))) + + data["products"] = listed_products + + if(src.coin) + data["coin"] = src.coin.name + + if(src.panel_open) + data["panel"] = 1 + data["speaker"] = src.shut_up ? 0 : 1 + else + data["panel"] = 0 + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "vending_machine.tmpl", src.name, 440, 600) + ui.set_initial_data(data) + ui.open() /obj/machinery/vending/Topic(href, href_list) if(..()) return 1 - if(istype(usr,/mob/living/silicon)) - if(istype(usr,/mob/living/silicon/robot)) - var/mob/living/silicon/robot/R = usr - if(!(R.module && istype(R.module,/obj/item/weapon/robot_module/butler) ) ) - usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" - return - else - usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" - return - - if(href_list["remove_coin"]) + if(href_list["remove_coin"] && !istype(usr,/mob/living/silicon)) if(!coin) usr << "There is no coin in this machine." return @@ -419,67 +474,86 @@ usr.put_in_hands(coin) usr << "\blue You remove the [coin] from the [src]" coin = null - usr.set_machine(src) - - + categories &= ~CAT_COIN + + if (href_list["pay"]) + if(currently_vending && vendor_account && !vendor_account.suspended) + if(istype(usr, /mob/living/carbon/human)) + var/paid = 0 + var/handled = 0 + var/mob/living/carbon/human/H = usr + var/obj/item/weapon/card/card = null + if(istype(H.wear_id,/obj/item/weapon/card)) + card = H.wear_id + paid = pay_with_card(card) + handled = 1 + else if(istype(H.get_active_hand(), /obj/item/weapon/card)) + card = H.get_active_hand() + paid = pay_with_card(card) + handled = 1 + if(paid) + src.vend(currently_vending, usr) + return + else if(handled) + nanomanager.update_uis(src) + return // don't smack that machine with your 2 credits + if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) if ((href_list["vend"]) && (src.vend_ready) && (!currently_vending)) - if (!allowed(usr) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH - usr << "\red Access denied." //Unless emagged of course - flick(src.icon_deny,src) + if(istype(usr,/mob/living/silicon)) + if(istype(usr,/mob/living/silicon/robot)) + var/mob/living/silicon/robot/R = usr + if(!(R.module && istype(R.module,/obj/item/weapon/robot_module/butler) )) + usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" + return + else + usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" + return + + if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH + usr << "Access denied." //Unless emagged of course + flick(icon_deny,src) return - var/idx=text2num(href_list["vend"]) - var/cat=text2num(href_list["cat"]) - - var/datum/data/vending_product/R = GetProductByID(idx,cat) - if (!R || !istype(R) || !R.product_path || R.amount <= 0) + var/key = text2num(href_list["vend"]) + var/datum/data/vending_product/R = product_records[key] + + // This should not happen unless the request from NanoUI was bad + if(!(R.category & src.categories)) return - - if(R.price == null) + + if(R.price <= 0) src.vend(R, usr) else src.currently_vending = R - src.updateUsrDialog() + if(!vendor_account || vendor_account.suspended) + src.status_message = "This machine is currently unable to process payments due to problems with the associated account." + src.status_error = 1 + else + src.status_message = "Please swipe a card or insert cash to pay for the item." + src.status_error = 0 - return - - else if (href_list["cancel_buying"]) + else if (href_list["cancelpurchase"]) src.currently_vending = null - src.updateUsrDialog() - return - - else if (href_list["buy"]) - if(istype(usr, /mob/living/carbon/human)) - var/mob/living/carbon/human/H=usr - var/obj/item/weapon/card/card = null - if(istype(H.wear_id,/obj/item/weapon/card)) - card=H.wear_id - else if(istype(H.get_active_hand(),/obj/item/weapon/card)) - card=H.get_active_hand() - if(card) - scan_card(card) - return else if ((href_list["togglevoice"]) && (src.panel_open)) src.shut_up = !src.shut_up src.add_fingerprint(usr) - src.updateUsrDialog() - else - usr << browse(null, "window=vending") - return - return + nanomanager.update_uis(src) /obj/machinery/vending/proc/vend(datum/data/vending_product/R, mob/user) - if (!allowed(user) && !emagged && wires.IsIndexCut(VENDING_WIRE_IDSCAN)) //For SECURE VENDING MACHINES YEAH - user << "\red Access denied." //Unless emagged of course + if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH + usr << "Access denied." //Unless emagged of course flick(src.icon_deny,src) return src.vend_ready = 0 //One thing at a time!! - - if (R in coin_records) + src.status_message = "Vending..." + src.status_error = 0 + nanomanager.update_uis(src) + + if (R.category & CAT_COIN) if(!coin) user << "\blue You need to insert a coin to get this item." return @@ -489,8 +563,10 @@ else user << "\blue You weren't able to pull the coin out fast enough, the machine ate it, string and all." del(coin) + categories &= ~CAT_COIN else del(coin) + categories &= ~CAT_COIN R.amount-- @@ -499,16 +575,16 @@ src.speak(src.vend_reply) src.last_reply = world.time - use_power(5) + use_power(vend_power_usage) //actuators and stuff if (src.icon_vend) //Show the vending animation if needed flick(src.icon_vend,src) spawn(src.vend_delay) new R.product_path(get_turf(src)) + src.status_message = "" + src.status_error = 0 src.vend_ready = 1 - return - - src.updateUsrDialog() - + currently_vending = null + nanomanager.update_uis(src) /obj/machinery/vending/proc/stock(var/datum/data/vending_product/R, var/mob/user) if(src.panel_open) @@ -809,7 +885,7 @@ /obj/item/weapon/reagent_containers/glass/bottle/stoxin = 4,/obj/item/weapon/reagent_containers/glass/bottle/toxin = 4, /obj/item/weapon/reagent_containers/syringe/antiviral = 4,/obj/item/weapon/reagent_containers/syringe = 12, /obj/item/device/healthanalyzer = 5,/obj/item/weapon/reagent_containers/glass/beaker = 4, /obj/item/weapon/reagent_containers/dropper = 2, - /obj/item/stack/medical/advanced/bruise_pack = 3, /obj/item/stack/medical/advanced/ointment = 3, /obj/item/stack/medical/splint = 2) + /obj/item/stack/medical/advanced/bruise_pack = 3, /obj/item/stack/medical/advanced/ointment = 3, /obj/item/stack/medical/splint = 2, /obj/item/device/sensor_device = 2) contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 3,/obj/item/weapon/reagent_containers/pill/stox = 4,/obj/item/weapon/reagent_containers/pill/antitox = 6) @@ -860,7 +936,7 @@ icon_state = "sec" icon_deny = "sec-deny" req_access_txt = "1" - products = list(/obj/item/weapon/handcuffs = 8,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash = 5, + products = list(/obj/item/weapon/restraints/handcuffs = 8,/obj/item/weapon/restraints/handcuffs/cable/zipties = 8,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash = 5, /obj/item/weapon/reagent_containers/food/snacks/donut/normal = 12,/obj/item/weapon/storage/box/evidence = 6,/obj/item/device/flashlight/seclite = 4) contraband = list(/obj/item/clothing/glasses/sunglasses = 2,/obj/item/weapon/storage/fancy/donut_box = 2,/obj/item/device/hailer = 5) @@ -883,19 +959,45 @@ product_slogans = "THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!;Hands down the best seed selection on the station!;Also certain mushroom varieties available, more for experts! Get certified today!" product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!" icon_state = "seeds" - delay_product_spawn = 1 products = list(/obj/item/seeds/bananaseed = 3,/obj/item/seeds/berryseed = 3,/obj/item/seeds/carrotseed = 3,/obj/item/seeds/chantermycelium = 3,/obj/item/seeds/chiliseed = 3, /obj/item/seeds/cornseed = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/replicapod = 3,/obj/item/seeds/soyaseed = 3, /obj/item/seeds/sunflowerseed = 3,/obj/item/seeds/tomatoseed = 3,/obj/item/seeds/towermycelium = 3,/obj/item/seeds/wheatseed = 3,/obj/item/seeds/appleseed = 3, /obj/item/seeds/poppyseed = 3,/obj/item/seeds/ambrosiavulgarisseed = 3,/obj/item/seeds/whitebeetseed = 3,/obj/item/seeds/watermelonseed = 3,/obj/item/seeds/limeseed = 3, /obj/item/seeds/lemonseed = 3,/obj/item/seeds/orangeseed = 3,/obj/item/seeds/grassseed = 3,/obj/item/seeds/cocoapodseed = 3, - /obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/plastiseed = 3,/obj/item/seeds/riceseed = 3) + /obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/plastiseed = 3,/obj/item/seeds/riceseed = 3, + /obj/item/seeds/tobaccoseed = 3, /obj/item/seeds/coffeeaseed = 3, /obj/item/seeds/teaasperaseed = 3) contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/nettleseed = 2, /obj/item/seeds/plumpmycelium = 2,/obj/item/seeds/reishimycelium = 2) premium = list(/obj/item/weapon/reagent_containers/spray/waterflower = 1) + +/** + * Populate hydroseeds product_records + * + * This needs to be customized to fetch the actual names of the seeds, otherwise + * the machine would simply list "packet of seeds" times 20 + */ +/obj/machinery/vending/hydroseeds/build_inventory() + var/list/all_products = list( + list(src.products, CAT_NORMAL), + list(src.contraband, CAT_HIDDEN), + list(src.premium, CAT_COIN)) + for(var/current_list in all_products) + var/category = current_list[2] + + for(var/entry in current_list[1]) + var/obj/item/seeds/S = new entry(src) + var/name = S.name + var/datum/data/vending_product/product = new/datum/data/vending_product(entry, name) + + product.price = (entry in src.prices) ? src.prices[entry] : 0 + product.amount = (current_list[1][entry]) ? current_list[1][entry] : 1 + product.max_amount = product.amount + product.category = category + + src.product_records.Add(product) /obj/machinery/vending/magivend name = "MagiVend" diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index c72b2338cba..c48d5e3a89c 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -151,7 +151,7 @@ if (S.chained == 1) S.chained = 0 S.slowdown = SHOES_SLOWDOWN - new /obj/item/weapon/handcuffs( src ) + new /obj/item/weapon/restraints/handcuffs( src ) S.icon_state = new_shoe_icon_state S._color = _color S.name = new_shoe_name diff --git a/code/game/machinery/wishgranter.dm b/code/game/machinery/wishgranter.dm index ac2986f18a2..87561d447ab 100644 --- a/code/game/machinery/wishgranter.dm +++ b/code/game/machinery/wishgranter.dm @@ -30,8 +30,30 @@ insisting++ else - user << "You speak. [pick("I want the station to disappear","Humanity is corrupt, mankind must be destroyed","I want to be rich", "I want to rule the world","I want immortality.")]. The Wish Granter answers." - user << "Your head pounds for a moment, before your vision clears. You are the avatar of the Wish Granter, and your power is LIMITLESS! And it's all yours. You need to make sure no one can take it from you. No one can know, first." + user << "The power of the Wish Granter have turned you into the superhero the station deserves. You are a masked vigilante, and answer to no man. Will you use your newfound strength to protect the innocent, or will you hunt the guilty?" + + ticker.mode.traitors += user.mind + user.mind.special_role = "The Hero The Station Deserves" + + var/wish = input("You want to...","Wish") as null|anything in list("Protect the innocent","Hunt the guilty") + switch(wish) + if("Protect the innocent") + var/datum/objective/protect/protect = new + protect.owner = user.mind + user.mind.objectives += protect + + if("Hunt the guilty") + var/datum/objective/assassinate/assasinate = new + assasinate.owner = user.mind + user.mind.objectives += assasinate + + var/obj_count = 1 + for(var/datum/objective/OBJ in user.mind.objectives) + user << "Objective #[obj_count]: [OBJ.explanation_text]" + obj_count++ + + user << "As a superhero, you are allowed to pick an appropriate pseudonym for your new role. A costume is also strongly encouraged." + user.rename_self() charges-- insisting = 0 @@ -57,25 +79,9 @@ if (!(M_TK in user.mutations)) user.mutations.Add(M_TK) - /* Not used - if(!(HEAL in user.mutations)) - user.mutations.Add(HEAL) - */ + if(!(M_REGEN in user.mutations)) + user.mutations.Add(M_REGEN) user.update_mutations() - ticker.mode.traitors += user.mind - user.mind.special_role = "Avatar of the Wish Granter" - - var/datum/objective/silence/silence = new - silence.owner = user.mind - user.mind.objectives += silence - - var/obj_count = 1 - for(var/datum/objective/OBJ in user.mind.objectives) - user << "Objective #[obj_count]: [OBJ.explanation_text]" - obj_count++ - - user << "You have a very bad feeling about this." - return \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm index cf3cd0022a6..efe31d5bf62 100644 --- a/code/game/mecha/equipment/tools/tools.dm +++ b/code/game/mecha/equipment/tools/tools.dm @@ -389,7 +389,7 @@ range = RANGED action(atom/target) - if(!action_checks(target) || src.loc.z == 2) return + if(!action_checks(target) || (src.loc.z in config.admin_levels)) return var/turf/T = get_turf(target) if(T) set_ready_state(0) @@ -410,7 +410,7 @@ action(atom/target) - if(!action_checks(target) || src.loc.z == 2) return + if(!action_checks(target) || (src.loc.z in config.admin_levels)) return var/list/theareas = list() for(var/area/AR in orange(100, chassis)) if(AR in theareas) continue diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 5b7a50c8594..76d2c03c934 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -513,10 +513,7 @@ return 1 else user << "You can't load \the [name] while it's opened." - return 1 - - if(istype(W,/obj/item/weapon/card/emag)) - emag() + return 1 if(istype(W, /obj/item/stack)) var/material @@ -561,6 +558,9 @@ else user << "\The [src] cannot hold any more [sname] sheet\s." return + +/obj/machinery/mecha_part_fabricator/emag_act(user as mob) + emag() /obj/machinery/mecha_part_fabricator/proc/material2name(var/ID) return copytext(ID,2) \ No newline at end of file diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index a6f60bd1c41..398c297cb24 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -697,17 +697,6 @@ /obj/mecha/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W, /obj/item/weapon/card/emag)) - if(istype(src, /obj/mecha/working/ripley) && emagged == 0) - emagged = 1 - usr << "\blue You slide the [W] through the [src]'s ID slot." - playsound(src.loc, "sparks", 100, 1) - src.desc += "
\red The mech's equiptment slots spark dangerously!" - else - usr <<"\red The [src]'s ID slot rejects the [W]." - return - - if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/mmi/posibrain)) if(mmi_move_inside(W,user)) user << "[src]-MMI interface initialized successfuly" @@ -864,6 +853,15 @@ */ return +/obj/mecha/emag_act(user as mob) + if(istype(src, /obj/mecha/working/ripley) && emagged == 0) + emagged = 1 + usr << "\blue You slide the card through the [src]'s ID slot." + playsound(src.loc, "sparks", 100, 1) + src.desc += "
\red The mech's equiptment slots spark dangerously!" + else + usr <<"\red The [src]'s ID slot rejects the card." + return /* diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index 63946f0f6e4..342ece56272 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -181,36 +181,40 @@ steam.start() -- spawns the effect return /datum/effect/effect/system/spark_spread - set_up(n = 3, c = 0, loca) - number = n > 10 ? 10 : n - cardinals = c + var/total_sparks = 0 // To stop it being spammed and lagging! - if (istype(loca, /turf/)) + set_up(n = 3, c = 0, loca) + if(n > 10) + n = 10 + number = n + cardinals = c + if(istype(loca, /turf/)) location = loca else location = get_turf(loca) start() - for (var/i = 1 to number) - spawn() - if (holder) - location = get_turf(holder) - - var/obj/effect/effect/sparks/sparks = getFromPool(/obj/effect/effect/sparks, location) - playsound(location, "sparks", 100, 1) + var/i = 0 + for(i=0, i 20) + return + spawn(0) + if(holder) + src.location = get_turf(holder) + var/obj/effect/effect/sparks/sparks = new /obj/effect/effect/sparks(src.location) + src.total_sparks++ var/direction - - if (cardinals) + if(src.cardinals) direction = pick(cardinal) else direction = pick(alldirs) - - for (var/j = 0, j < pick(1, 2, 3), j++) + for(i=0, iCard scanned." else diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index 6a8e7d7a2c2..f4129666026 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -72,10 +72,6 @@ usr << "It has [uses] lights remaining." /obj/item/device/lightreplacer/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/weapon/card/emag) && emagged == 0) - Emag() - return - if(istype(W, /obj/item/stack/sheet/glass)) var/obj/item/stack/sheet/glass/G = W if(G.amount - decrement >= 0 && uses < max_uses) @@ -104,7 +100,10 @@ user << "You need a working light." return - +/obj/item/device/lightreplacer/emag_act(user as mob) + if(!emagged) + Emag() + /obj/item/device/lightreplacer/attack_self(mob/user) /* // This would probably be a bit OP. If you want it though, uncomment the code. if(isrobot(user)) diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm index 90a8f3fc1a2..3968ee1a441 100644 --- a/code/game/objects/items/devices/megaphone.dm +++ b/code/game/objects/items/devices/megaphone.dm @@ -47,10 +47,8 @@ spamcheck = 0 return -/obj/item/device/megaphone/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/weapon/card/emag) && !emagged) +/obj/item/device/megaphone/emag_act(user as mob) + if(!emagged) user << "\red You overload \the [src]'s voice synthesizer." emagged = 1 insults = rand(1, 3)//to prevent dickflooding - return - return \ No newline at end of file diff --git a/code/game/objects/items/devices/radio/beacon.dm b/code/game/objects/items/devices/radio/beacon.dm index 15f59e66dcb..628a6ee8bba 100644 --- a/code/game/objects/items/devices/radio/beacon.dm +++ b/code/game/objects/items/devices/radio/beacon.dm @@ -8,15 +8,11 @@ var/emagged = 0 var/syndicate = 0 -/obj/item/device/radio/beacon/attackby(I as obj, mob/living/user as mob) - if(istype(I,/obj/item/weapon/card/emag)) // If hit by an emag. - var/obj/item/weapon/card/emag/E = I - if(!emagged) - if(E.uses) - E.uses-- - emagged = 1 - syndicate = 1 - user << "\blue The This beacon now only be locked on to by emagged teleporters!" +/obj/item/device/radio/beacon/emag_act(user as mob) + if(!emagged) + emagged = 1 + syndicate = 1 + user << "\blue The This beacon now only be locked on to by emagged teleporters!" /obj/item/device/radio/beacon/hear_talk() return diff --git a/code/game/objects/items/devices/sensor_device.dm b/code/game/objects/items/devices/sensor_device.dm new file mode 100644 index 00000000000..5db0bdc47f4 --- /dev/null +++ b/code/game/objects/items/devices/sensor_device.dm @@ -0,0 +1,18 @@ +/obj/item/device/sensor_device + name = "handheld crew monitor" + desc = "A miniature machine that tracks suit sensors across the station." + icon = 'icons/obj/device.dmi' + icon_state = "scanner" + w_class = 2.0 + slot_flags = SLOT_BELT + origin_tech = "biotech=3;materials=3;magnets=3" + var/obj/nano_module/crew_monitor/crew_monitor + +/obj/item/device/sensor_device/New() + crew_monitor = new(src) + +/obj/item/device/sensor_device/attack_self(mob/user as mob) + ui_interact(user) + +/obj/item/device/sensor_device/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + crew_monitor.ui_interact(user, ui_key, ui, force_open) \ No newline at end of file diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm index ef39a621019..8477205a84a 100644 --- a/code/game/objects/items/devices/taperecorder.dm +++ b/code/game/objects/items/devices/taperecorder.dm @@ -38,17 +38,15 @@ storedinfo += "\[[time2text(timerecorded*10,"mm:ss")]\] [M.name] says, \"[msg]\"" return -/obj/item/device/taperecorder/attackby(obj/item/weapon/W as obj, mob/user as mob) - ..() - if(istype(W, /obj/item/weapon/card/emag)) - if(emagged == 0) - emagged = 1 - recording = 0 - user << "PZZTTPFFFT" - icon_state = "taperecorderidle" - else - user << "It is already emagged!" - +/obj/item/device/taperecorder/emag_act(user as mob) + if(!emagged == 0) + emagged = 1 + recording = 0 + user << "PZZTTPFFFT" + icon_state = "taperecorderidle" + else + user << "It is already emagged!" + /obj/item/device/taperecorder/proc/explode() var/turf/T = get_turf(loc) if(ismob(loc)) diff --git a/code/game/objects/items/devices/whistle.dm b/code/game/objects/items/devices/whistle.dm index 53bd2ea6b38..3d515d6259e 100644 --- a/code/game/objects/items/devices/whistle.dm +++ b/code/game/objects/items/devices/whistle.dm @@ -24,9 +24,8 @@ spawn(20) spamcheck = 0 -/obj/item/device/hailer/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/weapon/card/emag) && !emagged) +/obj/item/device/hailer/emag_act(user as mob) + if(!emagged) user << "\red You overload \the [src]'s voice synthesizer." emagged = 1 - return - return \ No newline at end of file + diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index 0fb733cad2a..dd849488a3b 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -69,58 +69,15 @@ item_state = "card-id" origin_tech = "magnets=2;syndicate=2" flags = NOBLUDGEON - var/uses = 1000000 - // List of devices that cost a use to emag. - var/list/devices = list( - /obj/item/robot_parts, - /obj/item/weapon/storage/lockbox, - /obj/item/weapon/storage/secure, - /obj/item/weapon/circuitboard, - /obj/item/device/eftpos, - /obj/item/device/lightreplacer, - /obj/item/device/taperecorder, - /obj/item/device/hailer, - /obj/item/clothing/accessory/holobadge, - /obj/structure/closet/crate/secure, - /obj/structure/closet/secure_closet, - /obj/machinery/librarycomp, - /obj/machinery/computer, - /obj/machinery/power, - /obj/machinery/suspension_gen, - /obj/machinery/shield_capacitor, - /obj/machinery/shield_gen, -// /obj/machinery/zero_point_emitter, - /obj/machinery/clonepod, - /obj/machinery/deployable, - /obj/machinery/door_control, - /obj/machinery/porta_turret, - /obj/machinery/shieldgen, - /obj/machinery/turretid, - /obj/machinery/vending, - /obj/machinery/bot, - /obj/machinery/door, - /obj/machinery/telecomms, - /obj/machinery/mecha_part_fabricator, - /obj/vehicle - ) +/obj/item/weapon/card/emag/attack() + return -/obj/item/weapon/card/emag/afterattack(var/obj/item/weapon/O as obj, mob/user as mob) - - for(var/type in devices) - if(istype(O,type)) - uses-- - break - - if(uses<1) - user.visible_message("[src] fizzles and sparks - it seems it's been used once too often, and is now broken.") - user.drop_item() - var/obj/item/weapon/card/emag_broken/junk = new(user.loc) - junk.add_fingerprint(user) - del(src) +/obj/item/weapon/card/emag/afterattack(atom/target, mob/user, proximity) + var/atom/A = target + if(!proximity) return - - ..() + A.emag_act(user) /obj/item/weapon/card/id name = "identification card" @@ -444,4 +401,4 @@ decal_name = "cryptographic sequencer" decal_desc = "It's a card with a magnetic strip attached to some circuitry." decal_icon_state = "emag" - override_name = 1 + override_name = 1 diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index c94e6de7dcf..56f1da80971 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -92,14 +92,6 @@ bcell = W user << "You install a cell in [src]." - if(istype(W, /obj/item/weapon/card/emag)) - if(safety) - safety = 0 - user << "You silently disable [src]'s safety protocols with the [W]." - else - safety = 1 - user << "You silently enable [src]'s safety protocols with the [W]." - if(istype(W, /obj/item/weapon/screwdriver)) if(bcell) bcell.updateicon() @@ -110,7 +102,13 @@ update_icon() return - +/obj/item/weapon/defibrillator/emag_act(user as mob) + if(safety) + safety = 0 + user << "You silently disable [src]'s safety protocols with the card." + else + safety = 1 + user << "You silently enable [src]'s safety protocols with the card." /obj/item/weapon/defibrillator/emp_act(severity) if(bcell) @@ -120,11 +118,11 @@ if(safety) safety = 0 src.visible_message("[src] beeps: Safety protocols disabled!") - playsound(get_turf(src), 'sound/machines/twobeep.ogg', 50, 0) + playsound(get_turf(src), 'sound/machines/defib_saftyOff.ogg', 50, 0) else safety = 1 src.visible_message("[src] beeps: Safety protocols enabled!") - playsound(get_turf(src), 'sound/machines/twobeep.ogg', 50, 0) + playsound(get_turf(src), 'sound/machines/defib_saftyOn.ogg', 50, 0) update_icon() ..() @@ -189,10 +187,10 @@ if(bcell) if(bcell.charge >= paddles.revivecost) user.visible_message("[src] beeps: Unit ready.") - playsound(get_turf(src), 'sound/machines/twobeep.ogg', 50, 0) + playsound(get_turf(src), 'sound/machines/defib_ready.ogg', 50, 0) else user.visible_message("[src] beeps: Charge depleted.") - playsound(get_turf(src), 'sound/machines/twobeep.ogg', 50, 0) + playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) paddles.cooldown = 0 paddles.update_icon() update_icon() @@ -276,7 +274,7 @@ /obj/item/weapon/twohanded/shockpaddles/suicide_act(mob/user) user.visible_message("[user] is putting the live paddles on \his chest! It looks like \he's trying to commit suicide.") defib.deductcharge(revivecost) - playsound(get_turf(src), 'sound/weapons/Egloves.ogg', 50, 1, -1) + playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) return (OXYLOSS) /obj/item/weapon/twohanded/shockpaddles/dropped(mob/user as mob) @@ -307,7 +305,7 @@ return if(!defib.powered) user.visible_message("[defib] beeps: Unit is unpowered.") - playsound(get_turf(src), 'sound/machines/twobeep.ogg', 50, 0) + playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) return if(!wielded) user << "You need to wield the paddles in both hands before you can use them on someone!" @@ -326,7 +324,7 @@ H.adjustStaminaLoss(50) H.Weaken(5) H.updatehealth() //forces health update before next life tick - playsound(get_turf(src), 'sound/weapons/Egloves.ogg', 50, 1, -1) + playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) H.emote("gasp") add_logs(user, M, "stunned", object="defibrillator") defib.deductcharge(revivecost) @@ -341,7 +339,7 @@ update_icon() if(do_after(user, 30)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process user.visible_message("[user] places [src] on [M.name]'s chest.", "You place [src] on [M.name]'s chest.") - playsound(get_turf(src), 'sound/weapons/flash.ogg', 50, 0) + playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0) var/mob/dead/observer/ghost = H.get_ghost() var/tplus = world.time - H.timeofdeath var/tlimit = 6000 //past this much time the patient is unrecoverable (in deciseconds) @@ -353,7 +351,7 @@ if(istype(carried_item, /obj/item/clothing/suit/space)) if(!defib.combat) user.visible_message("[defib] buzzes: Patient's chest is obscured. Operation aborted.") - playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 50, 0) + playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) busy = 0 update_icon() return @@ -361,7 +359,7 @@ var/health = H.health M.visible_message("[M]'s body convulses a bit.") playsound(get_turf(src), "bodyfall", 50, 1) - playsound(get_turf(src), 'sound/weapons/Egloves.ogg', 50, 1, -1) + playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) for(var/datum/organ/external/O in H.organs) total_brute += O.brute_dam total_burn += O.burn_dam @@ -373,7 +371,7 @@ H.adjustFireLoss(tobehealed) H.adjustBruteLoss(tobehealed) user.visible_message("[defib] pings: Resuscitation successful.") - playsound(get_turf(src), 'sound/machines/ping.ogg', 50, 0) + playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0) H.stat = 1 H.update_revive() H.emote("gasp") @@ -391,13 +389,127 @@ if(ghost) ghost << "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)" ghost << sound('sound/effects/genetics.ogg') - playsound(get_turf(src), 'sound/machines/buzz-two.ogg', 50, 0) + playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) defib.deductcharge(revivecost) update_icon() cooldown = 1 defib.cooldowncheck(user) else user.visible_message("[defib] buzzes: Patient is not in a valid state. Operation aborted.") + playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) + busy = 0 + update_icon() + else + user << "You need to target your patient's chest with [src]." + return + +/obj/item/weapon/borg_defib + name = "defibrillator paddles" + desc = "A pair of mounted paddles with flat metal surfaces that are used to deliver powerful electric shocks." + icon = 'icons/obj/weapons.dmi' + icon_state = "defibpaddles0" + item_state = "defibpaddles0" + force = 0 + w_class = 4 + canremove = 0 + var/revivecost = 1000 + var/cooldown = 0 + var/busy = 0 + +/obj/item/weapon/borg_defib/attack(mob/M, mob/user) + var/tobehealed + var/threshold = -config.health_threshold_dead + var/mob/living/carbon/human/H = M + + if(busy) + return + if(cooldown) + user << "[src] is recharging." + if(!ishuman(M)) + user << "This unit is only designed to work on humanoid lifeforms." + return + else + if(user.a_intent == "harm") + busy = 1 + H.visible_message("[user] has touched [H.name] with [src]!", \ + "[user] has touched [H.name] with [src]!") + H.adjustStaminaLoss(50) + H.Weaken(5) + H.updatehealth() //forces health update before next life tick + playsound(get_turf(src), 'sound/weapons/Egloves.ogg', 50, 1, -1) + H.emote("gasp") + add_logs(user, M, "stunned", object="defibrillator") + if(isrobot(user)) + var/mob/living/silicon/robot/R = user + R.cell.use(revivecost) + cooldown = 1 + busy = 0 + update_icon() + spawn(50) + cooldown = 0 + update_icon() + return + if(user.zone_sel && user.zone_sel.selecting == "chest") + user.visible_message("[user] begins to place [src] on [M.name]'s chest.", "You begin to place [src] on [M.name]'s chest.") + busy = 1 + update_icon() + if(do_after(user, 30)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process + user.visible_message("[user] places [src] on [M.name]'s chest.", "You place [src] on [M.name]'s chest.") + playsound(get_turf(src), 'sound/weapons/flash.ogg', 50, 0) + var/mob/dead/observer/ghost = H.get_ghost() + var/tplus = world.time - H.timeofdeath + var/tlimit = 6000 //past this much time the patient is unrecoverable (in deciseconds) + var/tloss = 3000 //brain damage starts setting in on the patient after some time left rotting + var/total_burn = 0 + var/total_brute = 0 + if(do_after(user, 20)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total + if(H.stat == 2) + var/health = H.health + M.visible_message("[M]'s body convulses a bit.") + playsound(get_turf(src), "bodyfall", 50, 1) + playsound(get_turf(src), 'sound/weapons/Egloves.ogg', 50, 1, -1) + for(var/datum/organ/external/O in H.organs) + total_brute += O.brute_dam + total_burn += O.burn_dam + if(H.health <= config.health_threshold_dead && total_burn <= 180 && total_brute <= 180 && !H.suiciding && !ghost && tplus < tlimit && !(M_NOCLONE in H.mutations)) + tobehealed = health + threshold + tobehealed -= 5 //They get 5 of each type of damage healed so excessive combined damage will not immediately kill them after they get revived + H.adjustOxyLoss(tobehealed) + H.adjustToxLoss(tobehealed) + H.adjustFireLoss(tobehealed) + H.adjustBruteLoss(tobehealed) + user.visible_message("[user] pings: Resuscitation successful.") + playsound(get_turf(src), 'sound/machines/ping.ogg', 50, 0) + H.stat = 1 + H.update_revive() + H.emote("gasp") + if(tplus > tloss) + H.setBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100)))) + if(isrobot(user)) + var/mob/living/silicon/robot/R = user + R.cell.use(revivecost) + add_logs(user, M, "revived", object="defibrillator") + else + if(tplus > tlimit) + user.visible_message("[user] buzzes: Resuscitation failed - Heart tissue damage beyond point of no return for defibrillation.") + else if(total_burn >= 180 || total_brute >= 180) + user.visible_message("[user] buzzes: Resuscitation failed - Severe tissue damage detected.") + else + user.visible_message("[user] buzzes: Resuscitation failed.") + if(ghost) + ghost << "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)" + ghost << sound('sound/effects/genetics.ogg') + playsound(get_turf(src), 'sound/machines/buzz-two.ogg', 50, 0) + if(isrobot(user)) + var/mob/living/silicon/robot/R = user + R.cell.use(revivecost) + update_icon() + cooldown = 1 + spawn(50) + cooldown = 0 + update_icon() + else + user.visible_message("[user] buzzes: Patient is not in a valid state. Operation aborted.") playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 50, 0) busy = 0 update_icon() diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index d885b568159..5c6da3e797b 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -1,4 +1,4 @@ -/obj/item/weapon/handcuffs +/obj/item/weapon/restraints/handcuffs name = "handcuffs" desc = "Use this to keep prisoners in line." gender = PLURAL @@ -12,132 +12,117 @@ throw_range = 5 m_amt = 500 origin_tech = "materials=1" - var/dispenser = 0 var/breakouttime = 600 //Deciseconds = 60s = 1 minutes + var/cuffsound = 'sound/weapons/handcuffs.ogg' + var/trashtype = null //For disposable cuffs -/obj/item/weapon/handcuffs/attack(mob/living/carbon/C, mob/user) +/obj/item/weapon/restraints/handcuffs/attack(mob/living/carbon/C, mob/user) if(M_CLUMSY in user.mutations && prob(50)) user << "Uh... how do those things work?!" - if(!C.handcuffed) - user.drop_item() - loc = C - C.handcuffed = src - C.update_inv_handcuffed() - return - - var/cable = 0 - if(istype(src, /obj/item/weapon/handcuffs/cable)) - cable = 1 + apply_cuffs(user,user) if(!C.handcuffed) - C.visible_message("[user] is trying to put handcuffs on [C]!", \ - "[user] is trying to put handcuffs on [C]!") - - if(cable) - playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) - else - playsound(loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2) + C.visible_message("[user] is trying to put [src.name] on [C]!", \ + "[user] is trying to put [src.name] on [C]!") + playsound(loc, cuffsound, 30, 1, -2) if(do_mob(user, C, 30)) - if(C.handcuffed) - return - user.drop_item() - loc = C - C.handcuffed = src - C.update_inv_handcuffed() - if(cable) + apply_cuffs(C,user) + user << "You handcuff [C]." + if(istype(src, /obj/item/weapon/restraints/handcuffs/cable)) feedback_add_details("handcuffs","C") else feedback_add_details("handcuffs","H") - add_logs(C, user, "handcuffed") + add_logs(user, C, "handcuffed") + else + user << "You fail to handcuff [C]." + +/obj/item/weapon/restraints/handcuffs/proc/apply_cuffs(mob/living/carbon/target, mob/user) + if(!target.handcuffed) + user.drop_item() + if(trashtype) + target.handcuffed = new trashtype(target) + qdel(src) + else + loc = target + target.handcuffed = src + target.update_inv_handcuffed(1) + return var/last_chew = 0 /mob/living/carbon/human/RestrainedClickOn(var/atom/A) - if (A != src) return ..() - if (last_chew + 26 > world.time) return + if (A != src) + return ..() + if (last_chew + 26 > world.time) + return var/mob/living/carbon/human/H = A - if (!H.handcuffed) return - if (H.a_intent != "harm") return - if (H.zone_sel.selecting != "mouth") return - if (H.wear_mask) return - if (istype(H.wear_suit, /obj/item/clothing/suit/straight_jacket)) return + if (!H.handcuffed) + return + if (H.a_intent != "harm") + return + if (H.zone_sel.selecting != "mouth") + return + if (H.wear_mask) + return + if (istype(H.wear_suit, /obj/item/clothing/suit/straight_jacket)) + return - var/datum/organ/external/O = H.organs_by_name[H.hand?"l_hand":"r_hand"] - if (!O) return + var/datum/organ/external/O = H.organs_by_name[H.hand ? "l_hand" : "r_hand"] + if (!O) + return - var/s = "\red [H.name] chews on \his [O.display_name]!" - H.visible_message(s, "\red You chew on your [O.display_name]!") + var/s = "[H.name] chews on \his [O.display_name]!" + H.visible_message(s, "You chew on your [O.display_name]!") H.attack_log += text("\[[time_stamp()]\] [s] ([H.ckey])") log_attack("[s] ([H.ckey])") if(O.take_damage(3,0,1,1,"teeth marks")) - H:UpdateDamageIcon() + H.UpdateDamageIcon() if(prob(10)) O.droplimb() last_chew = world.time -/obj/item/weapon/handcuffs/cable +/obj/item/weapon/restraints/handcuffs/cable name = "cable restraints" desc = "Looks like some cables tied together. Could be used to tie something up." icon_state = "cuff_red" + item_state = "coil_red" breakouttime = 300 //Deciseconds = 30s + cuffsound = 'sound/weapons/cablecuff.ogg' -/obj/item/weapon/handcuffs/cable/red +/obj/item/weapon/restraints/handcuffs/cable/red icon_state = "cuff_red" -/obj/item/weapon/handcuffs/cable/yellow +/obj/item/weapon/restraints/handcuffs/cable/yellow icon_state = "cuff_yellow" -/obj/item/weapon/handcuffs/cable/blue +/obj/item/weapon/restraints/handcuffs/cable/blue icon_state = "cuff_blue" -/obj/item/weapon/handcuffs/cable/green +/obj/item/weapon/restraints/handcuffs/cable/green icon_state = "cuff_green" -/obj/item/weapon/handcuffs/cable/pink +/obj/item/weapon/restraints/handcuffs/cable/pink icon_state = "cuff_pink" -/obj/item/weapon/handcuffs/cable/orange +/obj/item/weapon/restraints/handcuffs/cable/orange icon_state = "cuff_orange" -/obj/item/weapon/handcuffs/cable/cyan +/obj/item/weapon/restraints/handcuffs/cable/cyan icon_state = "cuff_cyan" -/obj/item/weapon/handcuffs/cable/white +/obj/item/weapon/restraints/handcuffs/cable/white icon_state = "cuff_white" - -/obj/item/weapon/handcuffs/cyborg - dispenser = 1 - -/obj/item/weapon/handcuffs/cyborg/attack(mob/living/carbon/C as mob, mob/user as mob) - if(!C.handcuffed) - var/turf/p_loc = user.loc - var/turf/p_loc_m = C.loc - playsound(src.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2) - user.visible_message("\red [user] is trying to put handcuffs on [C]!") - - if (ishuman(C)) - var/mob/living/carbon/human/H = C - if (!H.has_organ_for_slot(slot_handcuffed)) - user << "\red \The [H] needs at least two wrists before you can cuff them together!" - return - - spawn(30) - if(!C) return - if(p_loc == user.loc && p_loc_m == C.loc) - C.handcuffed = new /obj/item/weapon/handcuffs(C) - C.update_inv_handcuffed() - -/obj/item/weapon/handcuffs/pinkcuffs +/obj/item/weapon/restraints/handcuffs/pinkcuffs name = "fluffy pink handcuffs" desc = "Use this to keep prisoners in line. Or you know, your significant other." icon_state = "pinkcuffs" -/obj/item/weapon/handcuffs/cable/attackby(var/obj/item/I, mob/user as mob) +/obj/item/weapon/restraints/handcuffs/cable/attackby(var/obj/item/I, mob/user as mob) ..() if(istype(I, /obj/item/stack/rods)) var/obj/item/stack/rods/R = I @@ -146,7 +131,92 @@ var/last_chew = 0 user.unEquip(src) user.put_in_hands(W) user << "You wrap the cable restraint around the top of the rod." - del(src) + qdel(src) else user << "You need one rod to make a wired rod." return + +/obj/item/weapon/restraints/handcuffs/cable/zipties + name = "zipties" + desc = "Plastic, disposable zipties that can be used to restrain temporarily but are destroyed after use." + icon_state = "cuff_white" + breakouttime = 450 //Deciseconds = 45s + trashtype = /obj/item/weapon/restraints/handcuffs/cable/zipties/used + +/obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg/attack(mob/living/carbon/C, mob/user) + if(isrobot(user)) + if(!C.handcuffed) + playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) + C.visible_message("[user] is trying to put zipties on [C]!", \ + "[user] is trying to put zipties on [C]!") + if(do_mob(user, C, 30)) + if(!C.handcuffed) + C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C) + C.update_inv_handcuffed(1) + user << "You handcuff [C]." + add_logs(user, C, "handcuffed") + else + user << "You fail to handcuff [C]." + +/obj/item/weapon/restraints/handcuffs/cable/zipties/used/attack() + return + +//Legcuffs +/obj/item/weapon/restraints/legcuffs + name = "leg cuffs" + desc = "Use this to keep prisoners in line." + gender = PLURAL + icon = 'icons/obj/items.dmi' + icon_state = "handcuff" + flags = CONDUCT + throwforce = 0 + w_class = 3.0 + origin_tech = "materials=1" + slowdown = 7 + var/breakouttime = 300 //Deciseconds = 30s = 0.5 minute + +/obj/item/weapon/restraints/legcuffs/beartrap + name = "bear trap" + throw_speed = 1 + throw_range = 1 + icon_state = "beartrap0" + desc = "A trap used to catch bears and other legged creatures." + var/armed = 0 + +/obj/item/weapon/restraints/legcuffs/beartrap/suicide_act(mob/user) + user.visible_message("[user] is sticking \his head in the [src.name]! It looks like \he's trying to commit suicide.") + playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1) + return (BRUTELOSS) + +/obj/item/weapon/restraints/legcuffs/beartrap/attack_self(mob/user as mob) + ..() + if(ishuman(user) && !user.stat && !user.restrained()) + armed = !armed + icon_state = "beartrap[armed]" + user << "[src] is now [armed ? "armed" : "disarmed"]" + +/obj/item/weapon/restraints/legcuffs/beartrap/Crossed(AM as mob|obj) + if(armed && isturf(src.loc)) + if( (iscarbon(AM) || isanimal(AM)) && !istype(AM, /mob/living/simple_animal/parrot) && !istype(AM, /mob/living/simple_animal/construct) && !istype(AM, /mob/living/simple_animal/shade) && !istype(AM, /mob/living/simple_animal/hostile/viscerator)) + var/mob/living/L = AM + armed = 0 + icon_state = "beartrap0" + playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) + L.visible_message("[L] triggers \the [src].", \ + "You trigger \the [src]!") + + if(ishuman(AM)) + var/mob/living/carbon/H = AM + if(H.lying) + H.apply_damage(20,BRUTE,"chest") + else + H.apply_damage(20,BRUTE,(pick("l_leg", "r_leg"))) + if(!H.legcuffed) //beartrap can't cuff you leg if there's already a beartrap or legcuffs. + H.legcuffed = src + src.loc = H + H.update_inv_legcuffed(0) + feedback_add_details("handcuffs","B") //Yes, I know they're legcuffs. Don't change this, no need for an extra variable. The "B" is used to tell them apart. + + else + L.apply_damage(20,BRUTE) + ..() diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index c73bdb62a64..98bcd5728e6 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -94,7 +94,8 @@ "/obj/item/device/flashlight/pen", "/obj/item/clothing/mask/surgical", "/obj/item/clothing/gloves/color/latex", - "/obj/item/weapon/reagent_containers/hypospray/autoinjector" + "/obj/item/weapon/reagent_containers/hypospray/autoinjector", + "/obj/item/device/sensor_device" ) @@ -109,7 +110,7 @@ "/obj/item/weapon/grenade/flashbang", "/obj/item/weapon/grenade/chem_grenade/teargas", "/obj/item/weapon/reagent_containers/spray/pepper", - "/obj/item/weapon/handcuffs", + "/obj/item/weapon/restraints/handcuffs", "/obj/item/device/flash", "/obj/item/clothing/glasses", "/obj/item/ammo_casing/shotgun", @@ -412,7 +413,7 @@ new /obj/item/device/multitool(src) new /obj/item/stack/cable_coil(src) - new /obj/item/weapon/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) new /obj/item/weapon/dnainjector/xraymut(src) new /obj/item/weapon/dnainjector/firemut(src) new /obj/item/weapon/dnainjector/telemut(src) diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 124c2d4f0fd..2e63b0a2cec 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -183,6 +183,20 @@ new /obj/item/weapon/grenade/flashbang(src) new /obj/item/weapon/grenade/flashbang(src) +/obj/item/weapon/storage/box/flashes + name = "box of flashbulbs" + desc = "WARNING: Flashes can cause serious eye damage, protective eyewear is required." + icon_state = "flashbang" + + New() + ..() + new /obj/item/device/flash(src) + new /obj/item/device/flash(src) + new /obj/item/device/flash(src) + new /obj/item/device/flash(src) + new /obj/item/device/flash(src) + new /obj/item/device/flash(src) + /obj/item/weapon/storage/box/teargas name = "box of tear gas grenades (WARNING)" desc = "WARNING: These devices are extremely dangerous and can cause blindness and skin irritation." @@ -242,6 +256,20 @@ new /obj/item/weapon/implanter(src) new /obj/item/weapon/implantpad(src) +/obj/item/weapon/storage/box/exileimp + name = "boxed exile implant kit" + desc = "Box of exile implants. It has a picture of a clown being booted through the Gateway." + icon_state = "implant" + + New() + ..() + new /obj/item/weapon/implantcase/exile(src) + new /obj/item/weapon/implantcase/exile(src) + new /obj/item/weapon/implantcase/exile(src) + new /obj/item/weapon/implantcase/exile(src) + new /obj/item/weapon/implantcase/exile(src) + new /obj/item/weapon/implanter(src) + /obj/item/weapon/storage/box/deathimp name = "death alarm implant kit" desc = "Box of life sign monitoring implants." @@ -423,7 +451,7 @@ new /obj/item/weapon/card/id/prisoner/seven(src) /obj/item/weapon/storage/box/seccarts - name = "Spare R.O.B.U.S.T. Cartridges" + name = "spare R.O.B.U.S.T. Cartridges" desc = "A box full of R.O.B.U.S.T. Cartridges, used by Security." icon_state = "pda" @@ -445,13 +473,28 @@ New() ..() - new /obj/item/weapon/handcuffs(src) - new /obj/item/weapon/handcuffs(src) - new /obj/item/weapon/handcuffs(src) - new /obj/item/weapon/handcuffs(src) - new /obj/item/weapon/handcuffs(src) - new /obj/item/weapon/handcuffs(src) - new /obj/item/weapon/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + +/obj/item/weapon/storage/box/zipties + name = "box of spare zipties" + desc = "A box full of zipties." + icon_state = "handcuff" + + New() + ..() + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) /obj/item/weapon/storage/box/fakesyndiesuit name = "boxed space suit and helmet" diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm index 15a046e3371..8620b4d2339 100644 --- a/code/game/objects/items/weapons/storage/secure.dm +++ b/code/game/objects/items/weapons/storage/secure.dm @@ -34,23 +34,8 @@ attackby(obj/item/weapon/W as obj, mob/user as mob) if(locked) - if ( (istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)) && (!src.emagged)) - emagged = 1 - src.overlays += image('icons/obj/storage.dmi', icon_sparking) - sleep(6) - src.overlays = null - overlays += image('icons/obj/storage.dmi', icon_locking) - locked = 0 - if(istype(W, /obj/item/weapon/melee/energy/blade)) - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, src.loc) - spark_system.start() - playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) - playsound(src.loc, "sparks", 50, 1) - user << "You slice through the lock on [src]." - else - user << "You short out the lock on [src]." - return + if ((istype(W, /obj/item/weapon/melee/energy/blade)) && (!src.emagged)) + emag_act(user, W) if (istype(W, /obj/item/weapon/screwdriver)) if (do_after(user, 20)) @@ -79,6 +64,25 @@ // -> storage/attackby() what with handle insertion, etc ..() + + emag_act(user as mob, weapon as obj) + if(!emagged) + emagged = 1 + src.overlays += image('icons/obj/storage.dmi', icon_sparking) + sleep(6) + src.overlays = null + overlays += image('icons/obj/storage.dmi', icon_locking) + locked = 0 + if(istype(weapon, /obj/item/weapon/melee/energy/blade)) + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, src.loc) + spark_system.start() + playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) + playsound(src.loc, "sparks", 50, 1) + user << "You slice through the lock on [src]." + else + user << "You short out the lock on [src]." + return MouseDrop(over_object, src_location, over_location) diff --git a/code/game/objects/items/weapons/surgery_tools.dm b/code/game/objects/items/weapons/surgery_tools.dm index 33cff224752..e85df4485bf 100644 --- a/code/game/objects/items/weapons/surgery_tools.dm +++ b/code/game/objects/items/weapons/surgery_tools.dm @@ -16,8 +16,8 @@ desc = "Retracts stuff." icon = 'icons/obj/surgery.dmi' icon_state = "retractor" - m_amt = 10000 - g_amt = 5000 + m_amt = 6000 + g_amt = 3000 flags = CONDUCT w_class = 2.0 origin_tech = "materials=1;biotech=1" @@ -265,8 +265,8 @@ LOOK FOR SURGERY.DM*/ desc = "This stops bleeding." icon = 'icons/obj/surgery.dmi' icon_state = "cautery" - m_amt = 5000 - g_amt = 2500 + m_amt = 2500 + g_amt = 750 flags = CONDUCT w_class = 2.0 origin_tech = "materials=1;biotech=1" @@ -356,8 +356,8 @@ LOOK FOR SURGERY.DM*/ icon = 'icons/obj/surgery.dmi' icon_state = "drill" hitsound = 'sound/weapons/circsawhit.ogg' - m_amt = 15000 - g_amt = 10000 + m_amt = 10000 + g_amt = 6000 flags = CONDUCT force = 15.0 w_class = 2.0 @@ -385,8 +385,8 @@ LOOK FOR SURGERY.DM*/ throwforce = 5.0 throw_speed = 3 throw_range = 5 - m_amt = 10000 - g_amt = 5000 + m_amt = 4000 + g_amt = 1000 origin_tech = "materials=1;biotech=1" attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") @@ -637,8 +637,8 @@ LOOK FOR SURGERY.DM*/ throwforce = 9.0 throw_speed = 3 throw_range = 5 - m_amt = 20000 - g_amt = 10000 + m_amt = 10000 + g_amt = 6000 origin_tech = "materials=1;biotech=1" attack_verb = list("attacked", "slashed", "sawed", "cut") sharp = 1 diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm index 29c568fe15b..fcadebadbbd 100644 --- a/code/game/objects/items/weapons/teleportation.dm +++ b/code/game/objects/items/weapons/teleportation.dm @@ -48,7 +48,7 @@ Frequency: if (usr.stat || usr.restrained()) return var/turf/current_location = get_turf(usr)//What turf is the user on? - if(!current_location||current_location.z==2)//If turf was not found or they're on z level 2. + if(!current_location||(current_location.z in config.admin_levels))//If turf was not found or they're on z level 2. usr << "The [src] is malfunctioning." return if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) @@ -138,7 +138,7 @@ Frequency: /obj/item/weapon/hand_tele/attack_self(mob/user as mob) var/turf/current_location = get_turf(user)//What turf is the user on? - if(!current_location||current_location.z==2||current_location.z>=7)//If turf was not found or they're on z level 2 or >7 which does not currently exist. + if(!current_location||(current_location.z in config.admin_levels)||current_location.z>=7)//If turf was not found or they're on z level 2 or >7 which does not currently exist. user << "\The [src] is malfunctioning." return var/list/L = list( ) diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index f84a3534005..8f85c3f0bff 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -118,7 +118,7 @@ item_state = "cutters_yellow" /obj/item/weapon/wirecutters/attack(mob/living/carbon/C as mob, mob/user as mob) - if((C.handcuffed) && (istype(C.handcuffed, /obj/item/weapon/handcuffs/cable))) + if((C.handcuffed) && (istype(C.handcuffed, /obj/item/weapon/restraints/handcuffs/cable))) usr.visible_message("\The [usr] cuts \the [C]'s restraints with \the [src]!",\ "You cut \the [C]'s restraints with \the [src]!",\ "You hear cable being cut.") @@ -147,7 +147,7 @@ //Cost to make in the autolathe m_amt = 70 - g_amt = 30 + g_amt = 20 //R&D tech level origin_tech = "engineering=1" diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index e50de9f2d44..6049d30bd51 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -21,11 +21,15 @@ // Reagent ID => friendly name var/list/reagents_to_log=list() -/obj/Topic(href, href_list, var/nowindow = 0) +/obj/Topic(href, href_list, var/nowindow = 0, var/checkrange = 1) // Calling Topic without a corresponding window open causes runtime errors - if(nowindow) - return 0 - return ..() + if(!nowindow && ..()) + return 1 + + if(usr.can_interact_with_interface(nano_host(), checkrange) != STATUS_INTERACTIVE) + return 1 + add_fingerprint(usr) + return 0 /obj/Destroy() machines -= src diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index fcd8dafd77f..c223fa99314 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -234,4 +234,6 @@ sleep(2) new /obj/item/clothing/suit/space/eva/paramedic(src) new /obj/item/clothing/head/helmet/space/eva/paramedic(src) + new /obj/item/clothing/head/helmet/space/eva/paramedic(src) + new /obj/item/device/sensor_device(src) return \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 282afb599e2..011f0c7fc6d 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -150,7 +150,7 @@ new /obj/item/clothing/glasses/sunglasses/sechud(src) new /obj/item/clothing/mask/gas/sechailer/warden(src) new /obj/item/taperoll/police(src) - new /obj/item/weapon/storage/box/handcuffs(src) + new /obj/item/weapon/storage/box/zipties(src) new /obj/item/weapon/storage/box/flashbangs(src) new /obj/item/weapon/reagent_containers/spray/pepper(src) new /obj/item/weapon/melee/baton/loaded(src) @@ -240,7 +240,7 @@ new /obj/item/weapon/storage/belt/security(src) new /obj/item/weapon/grenade/flashbang(src) new /obj/item/device/flash(src) - new /obj/item/weapon/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) new /obj/item/weapon/melee/baton/loaded(src) new /obj/item/clothing/glasses/sunglasses(src) new /obj/item/clothing/glasses/hud/health_advanced diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm index 7a7accadd10..5ff118de801 100644 --- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm +++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm @@ -381,6 +381,10 @@ new /obj/item/clothing/head/soft/grey(src) if(prob(50)) new /obj/item/weapon/storage/backpack/duffel(src) + if(prob(40)) + new /obj/item/clothing/under/assistantformal(src) + if(prob(40)) + new /obj/item/clothing/under/assistantformal(src) return diff --git a/code/game/objects/structures/crates_lockers/crittercrate.dm b/code/game/objects/structures/crates_lockers/crittercrate.dm index 2f01821abc9..cdbdacde644 100644 --- a/code/game/objects/structures/crates_lockers/crittercrate.dm +++ b/code/game/objects/structures/crates_lockers/crittercrate.dm @@ -6,6 +6,7 @@ icon_closed = "critter" var/already_opened = 0 var/content_mob = null + var/amount = 1 /obj/structure/closet/critter/can_open() if(welded) @@ -21,19 +22,7 @@ return ..() if(content_mob != null && already_opened == 0) - if(content_mob == /mob/living/simple_animal/chick) - var/num = rand(4, 6) - for(var/i = 0, i < num, i++) - new content_mob(loc) - else if(content_mob == /mob/living/simple_animal/corgi) - var/num = rand(0, 1) - if(num) //No more matriarchy for cargo - content_mob = /mob/living/simple_animal/corgi/Lisa - new content_mob(loc) - else if(content_mob == /mob/living/simple_animal/cat) - if(prob(50)) - content_mob = /mob/living/simple_animal/cat/Proc - else + for(var/i = 1, i <= amount, i++) new content_mob(loc) already_opened = 1 ..() @@ -53,7 +42,12 @@ /obj/structure/closet/critter/corgi name = "corgi crate" - content_mob = /mob/living/simple_animal/corgi //This statement is (not) false. See above. + content_mob = /mob/living/simple_animal/corgi + +/obj/structure/closet/critter/corgi/New() + if(prob(50)) + content_mob = /mob/living/simple_animal/corgi/Lisa + ..() /obj/structure/closet/critter/cow name = "cow crate" @@ -67,10 +61,28 @@ name = "chicken crate" content_mob = /mob/living/simple_animal/chick +/obj/structure/closet/critter/chick/New() + amount = rand(1, 3) + ..() + /obj/structure/closet/critter/cat name = "cat crate" content_mob = /mob/living/simple_animal/cat +/obj/structure/closet/critter/cat/New() + if(prob(50)) + content_mob = /mob/living/simple_animal/cat/Proc + ..() + +/obj/structure/closet/critter/pug + name = "pug crate" + content_mob = /mob/living/simple_animal/pug + /obj/structure/closet/critter/fox name = "fox crate" - content_mob = /mob/living/simple_animal/fox \ No newline at end of file + content_mob = /mob/living/simple_animal/fox + +/obj/structure/closet/critter/butterfly + name = "butterflies crate" + content_mob = /mob/living/simple_animal/butterfly + amount = 50 \ No newline at end of file diff --git a/code/game/objects/structures/dresser.dm b/code/game/objects/structures/dresser.dm index 6401ce034f3..6a773177c59 100644 --- a/code/game/objects/structures/dresser.dm +++ b/code/game/objects/structures/dresser.dm @@ -6,6 +6,15 @@ density = 1 anchored = 1 +/obj/structure/dresser/proc/convUnM(mund) + return underwear_m.Find(mund) + +/obj/structure/dresser/proc/convUnF(fund) + return underwear_f.Find(fund) + +/obj/structure/dresser/proc/convUs(us) + return undershirt_list.Find(us) + /obj/structure/dresser/attack_hand(mob/user as mob) if(!Adjacent(user))//no tele-grooming return @@ -18,14 +27,26 @@ return switch(choice) if("Underwear") - var/new_undies = input(user, "Select your underwear", "Changing") as null|anything in underwear_list - if(new_undies) - H.underwear = new_undies + if(H.gender == FEMALE) + var/new_undies = input(user, "Select your underwear", "Changing") as null|anything in underwear_f + if(new_undies) + H << "\red You selected [new_undies]." + var/freturn = convUnF(new_undies) + H.underwear = freturn + + else + var/new_undies = input(user, "Select your underwear", "Changing") as null|anything in underwear_m + if(new_undies) + H << "\red You selected [new_undies]." + var/mreturn = convUnM(new_undies) + H.underwear = mreturn if("Undershirt") var/new_undershirt = input(user, "Select your undershirt", "Changing") as null|anything in undershirt_list if(new_undershirt) - H.undershirt = new_undershirt + H << "\red You selected [new_undershirt]" + var/usreturn = convUs(new_undershirt) + H.undershirt = usreturn add_fingerprint(H) H.update_body() \ No newline at end of file diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm index 31cede5e65b..2c586f79f5d 100644 --- a/code/game/objects/structures/false_walls.dm +++ b/code/game/objects/structures/false_walls.dm @@ -75,11 +75,14 @@ icon = 'icons/turf/walls.dmi' var/mineral = "metal" var/walltype = "metal" + var/walltype2 = "rwall" // So it also connects with rwalls, like regular walls do var/opening = 0 density = 1 opacity = 1 /obj/structure/falsewall/New() + if(!walltype2) + walltype2 = walltype relativewall_neighbours() ..() @@ -105,11 +108,11 @@ for(var/turf/simulated/wall/W in orange(src,1)) if(abs(src.x-W.x)-abs(src.y-W.y)) //doesn't count diagonal walls - if(walltype == W.walltype)//Only 'like' walls connect -Sieve + if(walltype == W.walltype || walltype2 == W.walltype)//Only 'like' walls connect -Sieve junction |= get_dir(src,W) for(var/obj/structure/falsewall/W in orange(src,1)) if(abs(src.x-W.x)-abs(src.y-W.y)) //doesn't count diagonal walls - if(walltype == W.walltype) + if(walltype == W.walltype || walltype2 == W.walltype) junction |= get_dir(src,W) icon_state = "[walltype][junction]" return @@ -213,6 +216,8 @@ name = "reinforced wall" desc = "A huge chunk of reinforced metal used to seperate rooms." icon_state = "r_wall" + walltype = "rwall" + walltype2 = "metal" /obj/structure/falsewall/reinforced/ChangeToWall(delete = 1) var/turf/T = get_turf(src) @@ -244,11 +249,11 @@ for(var/turf/simulated/wall/W in orange(src,1)) if(abs(src.x-W.x)-abs(src.y-W.y)) //doesn't count diagonal walls - if(src.walltype == W.walltype)//Only 'like' walls connect -Sieve + if(src.walltype == W.walltype || walltype2 == W.walltype)//Only 'like' walls connect -Sieve junction |= get_dir(src,W) for(var/obj/structure/falsewall/W in orange(src,1)) if(abs(src.x-W.x)-abs(src.y-W.y)) //doesn't count diagonal walls - if(src.walltype == W.walltype) + if(src.walltype == W.walltype || src.walltype2 == W.walltype) junction |= get_dir(src,W) icon_state = "rwall[junction]" return diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm index f1322e17ad3..5c387450fd5 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm @@ -1,4 +1,5 @@ //Alium nests. Essentially beds with an unbuckle delay that only aliums can buckle mobs to. +#define NEST_RESIST_TIME 1200 /obj/structure/stool/bed/nest name = "alien nest" @@ -18,12 +19,15 @@ buckled_mob.pixel_y = 0 unbuckle() else + if(world.time <= buckled_mob.last_special+NEST_RESIST_TIME) + return buckled_mob.visible_message(\ "[buckled_mob.name] struggles to break free of the gelatinous resin...",\ "You struggle to break free from the gelatinous resin...",\ "You hear squelching...") - spawn(600) + spawn(NEST_RESIST_TIME) if(user && buckled_mob && user.buckled == src) + buckled_mob.last_special = world.time buckled_mob.pixel_y = 0 unbuckle() src.add_fingerprint(user) @@ -70,8 +74,7 @@ var/aforce = W.force health = max(0, health - aforce) playsound(loc, 'sound/effects/attackblob.ogg', 100, 1) - for(var/mob/M in viewers(src, 7)) - M.show_message("[user] hits [src] with [W]!", 1) + visible_message("[user] hits [src] with [W]!", 1) healthcheck() /obj/structure/stool/bed/nest/proc/healthcheck() diff --git a/code/game/response_team.dm b/code/game/response_team.dm index 3b82543e80a..a576c38295f 100644 --- a/code/game/response_team.dm +++ b/code/game/response_team.dm @@ -142,11 +142,11 @@ proc/trigger_armed_response_team(var/force = 0) // there's only a certain chance a team will be sent if(!prob(send_team_chance)) - command_alert("It would appear that an emergency response team was requested for [station_name()]. Unfortunately, we were unable to send one at this time.", "Central Command") + command_announcement.Announce("It would appear that an emergency response team was requested for [station_name()]. Unfortunately, we were unable to send one at this time.", "Central Command") can_call_ert = 0 // Only one call per round, ladies. return - command_alert("It would appear that an emergency response team was requested for [station_name()]. We will prepare and send one as soon as possible.", "Central Command") + command_announcement.Announce("It would appear that an emergency response team was requested for [station_name()]. We will prepare and send one as soon as possible.", "Central Command") can_call_ert = 0 // Only one call per round, gentleman. send_emergency_team = 1 diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm index 6a649a098f8..57216de9efd 100644 --- a/code/game/supplyshuttle.dm +++ b/code/game/supplyshuttle.dm @@ -93,6 +93,7 @@ var/list/mechtoys = list( /obj/machinery/computer/supplycomp name = "Supply Shuttle Console" + desc = "Used to order supplies." icon = 'icons/obj/computer.dmi' icon_state = "supply" req_access = list(access_cargo) @@ -105,6 +106,7 @@ var/list/mechtoys = list( /obj/machinery/computer/ordercomp name = "Supply Ordering Console" + desc = "Used to order supplies from cargo staff." icon = 'icons/obj/computer.dmi' icon_state = "request" circuit = "/obj/item/weapon/circuitboard/ordercomp" @@ -271,8 +273,8 @@ var/list/mechtoys = list( A:req_access += text2num(SP.access) var/list/contains - if(istype(SP,/datum/supply_packs/randomised)) - var/datum/supply_packs/randomised/SPR = SP + if(istype(SP,/datum/supply_packs/misc/randomised)) + var/datum/supply_packs/misc/randomised/SPR = SP contains = list() if(SPR.contains.len) for(var/j=1,j<=SPR.num_contained,j++) @@ -347,17 +349,18 @@ var/list/mechtoys = list( temp = "Supply points: [supply_controller.points]
" temp += "Main Menu


" temp += "Select a category

" - for(var/supply_group_name in all_supply_groups ) - temp += "[supply_group_name]
" + for(var/cat in all_supply_groups ) + temp += "[get_supply_group_name(cat)]
" else last_viewed_group = href_list["order"] + var/cat = text2num(last_viewed_group) temp = "Supply points: [supply_controller.points]
" temp += "Back to all categories


" - temp += "Request from: [last_viewed_group]

" - for(var/supply_name in supply_controller.supply_packs ) - var/datum/supply_packs/N = supply_controller.supply_packs[supply_name] - if(N.hidden || N.contraband || N.group != last_viewed_group) continue //Have to send the type instead of a reference to - temp += "[supply_name] Cost: [N.cost]
" //the obj because it would get caught by the garbage + temp += "Request from: [get_supply_group_name(cat)]

" + for(var/supply_type in supply_controller.supply_packs ) + var/datum/supply_packs/N = supply_controller.supply_packs[supply_type] + if(N.hidden || N.contraband || N.group != cat) continue //Have to send the type instead of a reference to + temp += "[N.name] Cost: [N.cost]
" //the obj because it would get caught by the garbage else if (href_list["doorder"]) if(world.time < reqtime) @@ -542,17 +545,18 @@ var/list/mechtoys = list( temp = "Supply points: [supply_controller.points]
" temp += "Main Menu


" temp += "Select a category

" - for(var/supply_group_name in all_supply_groups ) - temp += "[supply_group_name]
" + for(var/cat in all_supply_groups ) + temp += "[get_supply_group_name(cat)]
" else last_viewed_group = href_list["order"] + var/cat = text2num(last_viewed_group) temp = "Supply points: [supply_controller.points]
" temp += "Back to all categories


" - temp += "Request from: [last_viewed_group]

" - for(var/supply_name in supply_controller.supply_packs ) - var/datum/supply_packs/N = supply_controller.supply_packs[supply_name] - if((N.hidden && !hacked) || (N.contraband && !can_order_contraband) || N.group != last_viewed_group) continue //Have to send the type instead of a reference to - temp += "[supply_name] Cost: [N.cost]
" //the obj because it would get caught by the garbage + temp += "Request from: [get_supply_group_name(cat)]

" + for(var/supply_type in supply_controller.supply_packs ) + var/datum/supply_packs/N = supply_controller.supply_packs[supply_type] + if((N.hidden && !hacked) || (N.contraband && !can_order_contraband) || N.group != cat) continue //Have to send the type instead of a reference to + temp += "[N.name] Cost: [N.cost]
" //the obj because it would get caught by the garbage /*temp = "Supply points: [supply_controller.points]


Request what?

" diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm index 4505663b0c4..61ec3c862ee 100644 --- a/code/game/verbs/ooc.dm +++ b/code/game/verbs/ooc.dm @@ -120,18 +120,19 @@ var/global/normal_ooc_colour = "#002eb8" log_ooc("(LOCAL) [mob.name]/[key] : [msg]") var/list/heard = get_mobs_in_view(7, src.mob) var/mob/S = src.mob - + var/display_name = S.key if(S.stat != DEAD) display_name = S.name - + // Handle non-admins for(var/mob/M in heard) if(!M.client) continue var/client/C = M.client - if (C in admins) - continue //they are handled after that + if(C in admins) + if(C.holder.rights | R_MENTOR) + continue //they are handled after that if(C.prefs.toggles & CHAT_LOOC) if(holder) @@ -141,15 +142,16 @@ var/global/normal_ooc_colour = "#002eb8" else display_name = holder.fakekey C << "LOOC: [display_name]: [msg]" - + // Now handle admins display_name = S.key if(S.stat != DEAD) display_name = "[S.name]/([S.key])" - + for(var/client/C in admins) - if(C.prefs.toggles & CHAT_LOOC) - var/prefix = "(R)LOOC" - if (C.mob in heard) - prefix = "LOOC" - C << "[prefix]: [display_name]: [msg]" + if(C.holder.rights | R_MENTOR) + if(C.prefs.toggles & CHAT_LOOC) + var/prefix = "(R)LOOC" + if (C.mob in heard) + prefix = "LOOC" + C << "[prefix]: [display_name]: [msg]" diff --git a/code/game/verbs/who.dm b/code/game/verbs/who.dm index f5d5998e24a..7cdd9579e13 100644 --- a/code/game/verbs/who.dm +++ b/code/game/verbs/who.dm @@ -77,7 +77,7 @@ num_admins_online++ - else if(R_MOD & C.holder.rights) + else if((R_MOD | R_MENTOR) & C.holder.rights) modmsg += "\t[C] is a [C.holder.rank]" if(isobserver(C.mob)) @@ -98,9 +98,9 @@ if(!C.holder.fakekey) msg += "\t[C] is a [C.holder.rank]\n" num_admins_online++ - else if (R_MOD & C.holder.rights) + else if ((R_MOD | R_MENTOR) & C.holder.rights) modmsg += "\t[C] is a [C.holder.rank]\n" num_mods_online++ - msg = "Current Admins ([num_admins_online]):\n" + msg + "\n Current Mentors ([num_mods_online]):\n" + modmsg + msg = "Current Admins ([num_admins_online]):\n" + msg + "\n Current Mods/Mentors ([num_mods_online]):\n" + modmsg src << msg diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index f4b35c40ba2..a5dc3d6ef4d 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -781,7 +781,7 @@ var/global/nologevent = 0 /datum/admins/proc/unprison(var/mob/M in mob_list) set category = "Admin" set name = "Unprison" - if (M.z == 2) + if ((M.z in config.admin_levels)) M.loc = pick(latejoin) message_admins("[key_name_admin(usr)] has unprisoned [key_name_admin(M)]", 1) log_admin("[key_name(usr)] has unprisoned [key_name(M)]") diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index a9afe87debf..d9f5d7d54ba 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -41,6 +41,7 @@ var/list/admin_ranks = list() //list of all ranks with associated rights if("sound","sounds") rights |= R_SOUNDS if("spawn","create") rights |= R_SPAWN if("mod") rights |= R_MOD + if("mentor") rights |= R_MENTOR admin_ranks[rank] = rights previous_rights = rights diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 727dfc58c61..b4d24b90ec1 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -1,10 +1,8 @@ //admin verb groups - They can overlap if you so wish. Only one of each verb will exist in the verbs list regardless var/list/admin_verbs_default = list( // /datum/admins/proc/show_player_panel, /*shows an interface for individual players, with various links (links require additional flags*/ - /client/proc/deadmin_self, /*destroys our own admin datum so we can play as a regular player*/ - /client/proc/debug_variables, /*allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify*/ + /client/proc/deadmin_self /*destroys our own admin datum so we can play as a regular player*/ // /client/proc/check_antagonists, /*shows all antags*/ - /client/proc/cmd_mentor_check_new_players // /client/proc/deadchat /*toggles deadchat on/off*/ ) var/list/admin_verbs_admin = list( @@ -46,7 +44,6 @@ var/list/admin_verbs_admin = list( /client/proc/toggleprayers, /*toggles prayers on/off*/ // /client/proc/toggle_hear_radio, /*toggles whether we hear the radio*/ /client/proc/investigate_show, /*various admintools for investigation. Such as a singulo grief-log*/ - /client/proc/secrets, /datum/admins/proc/toggleooc, /*toggles ooc on/off for everyone*/ /datum/admins/proc/toggleoocdead, /*toggles ooc on/off for everyone who is dead*/ /datum/admins/proc/toggledsay, /*toggles dsay on/off for everyone*/ @@ -56,7 +53,6 @@ var/list/admin_verbs_admin = list( /client/proc/cmd_mod_say, /datum/admins/proc/show_player_info, /client/proc/free_slot, /*frees slot for chosen job*/ - /client/proc/cmd_admin_rejuvenate, /client/proc/toggleattacklogs, /client/proc/toggledebuglogs, /client/proc/update_mob_sprite, @@ -64,7 +60,6 @@ var/list/admin_verbs_admin = list( /client/proc/man_up, /client/proc/global_man_up, /client/proc/delbook, - /client/proc/event_manager_panel, /client/proc/empty_ai_core_toggle_latejoin ) var/list/admin_verbs_ban = list( @@ -98,6 +93,9 @@ var/list/admin_verbs_event = list( /client/proc/cmd_admin_world_narrate, /*sends text to all players with no padding*/ /client/proc/response_team, // Response Teams admin verb /client/proc/cmd_admin_create_centcom_report, + /client/proc/fax_panel, + /client/proc/secrets, + /client/proc/event_manager_panel ) var/list/admin_verbs_spawn = list( @@ -122,21 +120,7 @@ var/list/admin_verbs_server = list( /client/proc/delbook, /client/proc/toggle_antagHUD_use, /client/proc/toggle_antagHUD_restrictions, - /client/proc/set_ooc, - - //Doubling of certain event verbs for senior admins - /datum/admins/proc/access_news_network, /*allows access of newscasters*/ - /client/proc/cmd_admin_direct_narrate, /*send text directly to a player with no padding. Useful for narratives and fluff-text*/ - /client/proc/cmd_admin_world_narrate, /*sends text to all players with no padding*/ - /client/proc/toggle_random_events, - /client/proc/toggle_ert_calling, - /client/proc/one_click_antag, - /client/proc/cmd_admin_change_custom_event, - /client/proc/cmd_admin_create_centcom_report, - /client/proc/cmd_admin_dress, - /client/proc/editappear, - /client/proc/response_team, // Response Teams admin verb - /client/proc/nanomapgen_DumpImage + /client/proc/set_ooc ) var/list/admin_verbs_debug = list( /client/proc/cmd_admin_list_open_jobs, @@ -166,7 +150,8 @@ var/list/admin_verbs_permissions = list( /client/proc/edit_admin_permissions ) var/list/admin_verbs_rejuv = list( - /client/proc/respawn_character + /client/proc/respawn_character, + /client/proc/cmd_admin_rejuvenate ) var/list/admin_verbs_mod = list( /client/proc/cmd_admin_pm_context, /*right-click adminPM interface*/ @@ -181,9 +166,16 @@ var/list/admin_verbs_mod = list( /client/proc/dsay, /datum/admins/proc/show_player_panel, /client/proc/jobbans, + /client/proc/debug_variables /*allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify*/ // /client/proc/cmd_admin_subtle_message /*send an message to somebody as a 'voice in their head'*/ ) +var/list/admin_verbs_mentor = list( + /client/proc/cmd_admin_pm_context, /*right-click adminPM interface*/ + /client/proc/cmd_admin_pm_panel, /*admin-pm list*/ + /client/proc/cmd_admin_pm_by_key_panel, /*admin-pm list by key*/ + /client/proc/cmd_mentor_check_new_players +) /client/proc/add_admin_verbs() if(holder) @@ -201,6 +193,7 @@ var/list/admin_verbs_mod = list( if(holder.rights & R_SOUNDS) verbs += admin_verbs_sounds if(holder.rights & R_SPAWN) verbs += admin_verbs_spawn if(holder.rights & R_MOD) verbs += admin_verbs_mod + if(holder.rights & R_MENTOR) verbs += admin_verbs_mentor /client/proc/admin_ghost() set category = "Admin" @@ -637,6 +630,7 @@ var/list/admin_verbs_mod = list( set category = "Preferences" prefs.toggles ^= CHAT_ATTACKLOGS + prefs.save_preferences(src) if (prefs.toggles & CHAT_ATTACKLOGS) usr << "You now will get attack log messages" else diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 03270acb43f..3dcd7895dbb 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -37,18 +37,10 @@ if(!src.makeWizard()) usr << "\red Unfortunately there weren't enough candidates available." if("7") - log_admin("[key_name(usr)] has spawned a nuke team.") - if(!src.makeNukeTeam()) + log_admin("[key_name(usr)] has spawned vampires.") + if(!src.makeVampires()) usr << "\red Unfortunately there weren't enough candidates available." if("8") - log_admin("[key_name(usr)] has spawned a ninja.") - src.makeSpaceNinja() - if("9") - log_admin("[key_name(usr)] has spawned aliens.") - src.makeAliens() - if("10") - log_admin("[key_name(usr)] has spawned a death squad.") - if("11") log_admin("[key_name(usr)] has spawned vox raiders.") if(!src.makeVoxRaiders()) usr << "\red Unfortunately there weren't enough candidates available." @@ -294,7 +286,7 @@ if("sentinel") M.change_mob_type( /mob/living/carbon/alien/humanoid/sentinel , null, null, delmob ) if("larva") M.change_mob_type( /mob/living/carbon/alien/larva , null, null, delmob ) if("human") M.change_mob_type( /mob/living/carbon/human/human , null, null, delmob ) - if("slime") M.change_mob_type( /mob/living/carbon/slime , null, null, delmob ) + if("slime") M.change_mob_type( /mob/living/carbon/slime , null, null, delmob ) if("monkey") M.change_mob_type( /mob/living/carbon/monkey , null, null, delmob ) if("robot") M.change_mob_type( /mob/living/silicon/robot , null, null, delmob ) if("cat") M.change_mob_type( /mob/living/simple_animal/cat , null, null, delmob ) @@ -1100,6 +1092,7 @@ message_admins("\blue [key_name_admin(usr)] attempting to monkeyize [key_name_admin(H)]", 1) H.monkeyize() + else if(href_list["corgione"]) if(!check_rights(R_SPAWN)) return @@ -1437,7 +1430,7 @@ foo += text("Is an AI | ") else foo += text("Make AI | ", src, M) - if(M.z != 2) + if(!(M.z in config.admin_levels)) foo += text("Prison | ", src, M) foo += text("Maze | ", src, M) else @@ -1569,11 +1562,11 @@ usr << "This can only be used on instances of type /mob/living" return - if(alert(src.owner, "Are you sure you wish to hit [key_name(M)] with Blue Space Artillery?", "Confirm Firing?" , "Yes" , "No") != "Yes") + if(alert(src.owner, "Are you sure you wish to hit [key_name(M)] with Bluespace Artillery?", "Confirm Firing?" , "Yes" , "No") != "Yes") return if(BSACooldown) - src.owner << "Standby! Reload cycle in progress! Gunnary crews ready in five seconds!" + src.owner << "Standby. Reload cycle in progress. Gunnery crews ready in five seconds!" return BSACooldown = 1 @@ -1605,6 +1598,9 @@ M.stuttering = 20 else if(href_list["CentcommReply"]) + if(!check_rights(R_ADMIN)) + return + var/mob/living/carbon/human/H = locate(href_list["CentcommReply"]) if(!istype(H)) usr << "This can only be used on instances of type /mob/living/carbon/human" @@ -1622,10 +1618,16 @@ H << "You hear something crackle in your headset for a moment before a voice speaks. \"Please stand by for a message from Central Command. Message as follows. [input]. Message ends.\"" else if(href_list["SyndicateReply"]) + if(!check_rights(R_ADMIN)) + return + var/mob/living/carbon/human/H = locate(href_list["SyndicateReply"]) if(!istype(H)) usr << "This can only be used on instances of type /mob/living/carbon/human" return + if(H.stat != 0) + usr << "The person you are trying to contact is not conscious." + return if(!istype(H.l_ear, /obj/item/device/radio/headset) && !istype(H.r_ear, /obj/item/device/radio/headset)) usr << "The person you are trying to contact is not wearing a headset" return @@ -1654,6 +1656,9 @@ H << "You hear something crackle in your headset for a moment before a voice speaks. \"Please stand by for a message from your HONKbrothers. Message as follows, HONK. [input]. Message ends, HONK.\"" else if(href_list["AdminFaxView"]) + if(!check_rights(R_ADMIN)) + return + var/obj/item/fax = locate(href_list["AdminFaxView"]) if (istype(fax, /obj/item/weapon/paper)) var/obj/item/weapon/paper/P = fax @@ -1676,6 +1681,9 @@ usr << "\red The faxed item is not viewable. This is probably a bug, and should be reported on the tracker: [fax.type]" else if (href_list["AdminFaxViewPage"]) + if(!check_rights(R_ADMIN)) + return + var/page = text2num(href_list["AdminFaxViewPage"]) var/obj/item/weapon/paper_bundle/bundle = locate(href_list["paper_bundle"]) @@ -1689,51 +1697,155 @@ H.show(src.owner) return - else if(href_list["CentcommFaxReply"]) - var/mob/sender = locate(href_list["CentcommFaxReply"]) + else if(href_list["AdminFaxCreate"]) + if(!check_rights(R_ADMIN)) + return + + var/mob/sender = locate(href_list["AdminFaxCreate"]) var/obj/machinery/photocopier/faxmachine/fax = locate(href_list["originfax"]) + var/faxtype = href_list["faxtype"] + var/reply_to = locate(href_list["replyto"]) + var/destination + var/notify - var/input = input(src.owner, "Please enter a message to reply to [key_name(sender)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use
for line breaks.", "Outgoing message from Centcomm", "") as message|null - if(!input) return + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(null) //hopefully the null loc won't cause trouble for us - var/customname = input(src.owner, "Pick a title for the report", "Title") as text|null + if(!fax) + var/list/departmentoptions = alldepartments + "All Departments" + destination = input(usr, "To which department?", "Choose a department", "") as null|anything in departmentoptions + if(!destination) + del(P) + return + + for(var/obj/machinery/photocopier/faxmachine/F in allfaxes) + if(destination != "All Departments" && F.department == destination) + fax = F + + + var/input = input(src.owner, "Please enter a message to send a fax via secure connection. Use
for line breaks. Both pencode and HTML work.", "Outgoing message from Centcomm", "") as message|null + if(!input) + del(P) + return + input = P.parsepencode(input) // Encode everything from pencode to html + + var/customname = input(src.owner, "Pick a title for the fax.", "Fax Title") as text|null + if(!customname) + customname = "paper" + + var/stampname + var/stamptype + var/stampvalue + var/sendername + switch(faxtype) + if("Central Command") + stamptype = "icon" + stampvalue = "cent" + sendername = command_name() + if("Syndicate") + sendername = "UNKNOWN" + if("Administrator") + stamptype = input(src.owner, "Pick a stamp type.", "Stamp Type") as null|anything in list("icon","text","none") + if(stamptype == "icon") + stampname = input(src.owner, "Pick a stamp icon.", "Stamp Icon") as null|anything in list("centcom","granted","denied","clown") + switch(stampname) + if("centcom") + stampvalue = "cent" + if("granted") + stampvalue = "ok" + if("denied") + stampvalue = "deny" + if("clown") + stampvalue = "clown" + else if(stamptype == "text") + stampvalue = input(src.owner, "What should the stamp say?", "Stamp Text") as text|null + else if(stamptype == "none") + stamptype = "" + else + del(P) + return + + sendername = input(src.owner, "What organization does the fax come from? This determines the prefix of the paper (i.e. Central Command- Title). This is optional.", "Organization") as text|null + + if(sender) + notify = alert(src.owner, "Would you like to inform the original sender that a fax has arrived?","Notify Sender","Yes","No") // Create the reply message - var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( null ) //hopefully the null loc won't cause trouble for us - P.name = "[command_name()]- [customname]" + if(sendername) + P.name = "[sendername]- [customname]" + else + P.name = "[customname]" P.info = input P.update_icon() - P.stamps += "
" - var/image/stampoverlay = image('icons/obj/bureaucracy.dmi') P.x = rand(-2, 0) P.y = rand(-1, 2) P.offset_x += P.x P.offset_y += P.y - stampoverlay.pixel_x = P.x - stampoverlay.pixel_y = P.y + if(stamptype) + var/image/stampoverlay = image('icons/obj/bureaucracy.dmi') + stampoverlay.pixel_x = P.x + stampoverlay.pixel_y = P.y - if(!P.ico) - P.ico = new - P.ico += "paper_stamp-cent" - stampoverlay.icon_state = "paper_stamp-cent" + if(!P.ico) + P.ico = new + P.ico += "paper_stamp-[stampvalue]" + stampoverlay.icon_state = "paper_stamp-[stampvalue]" - // Stamps - if(!P.stamped) - P.stamped = new - P.stamped += /obj/item/weapon/stamp/centcom - P.overlays += stampoverlay + if(stamptype == "icon") + if(!P.stamped) + P.stamped = new + P.stamped += /obj/item/weapon/stamp/centcom + P.overlays += stampoverlay + P.stamps += "
" - if(fax.recievefax(P)) - src.owner << "\blue Message reply to transmitted successfully." - log_admin("[key_name(src.owner)] replied to a fax message from [key_name(sender)]: [input]") - message_admins("[key_name_admin(src.owner)] replied to a fax message from [key_name_admin(sender)]", 1) + else if(stamptype == "text") + if(!P.stamped) + P.stamped = new + P.stamped += /obj/item/weapon/stamp + P.overlays += stampoverlay + P.stamps += "
[stampvalue]" + + if(destination != "All Departments") + if(!fax.receivefax(P)) + src.owner << "\red Message transmission failed." + return else - src.owner << "\red Message reply failed." + for(var/obj/machinery/photocopier/faxmachine/F in allfaxes) + if((F.z in config.station_levels)) + if(!F.receivefax(P)) + src.owner << "\red Message transmission to [F.department] failed." - spawn(100) - del(P) + var/datum/fax/admin/A = new /datum/fax/admin() + A.name = P.name + A.from_department = faxtype + if(destination != "All Departments") + A.to_department = fax.department + else + A.to_department = "All Departments" + A.origin = "Administrator" + A.message = P + A.reply_to = reply_to + A.sent_by = usr + A.sent_at = world.time + + src.owner << "\blue Message transmitted successfully." + if(notify == "Yes") + var/mob/living/carbon/human/H = sender + if(istype(H) && H.stat == 1 && (istype(H.l_ear, /obj/item/device/radio/headset) || istype(H.r_ear, /obj/item/device/radio/headset))) + sender << "Your headset pings, notifying you that a reply to your fax has arrived." + if(sender) + log_admin("[key_name(src.owner)] replied to a fax message from [key_name(sender)]: [input]") + message_admins("[key_name_admin(src.owner)] replied to a fax message from [key_name_admin(sender)] (VIEW).", 1) + else + log_admin("[key_name(src.owner)] sent a fax message to [destination]: [input]") + message_admins("[key_name_admin(src.owner)] sent a fax message to [destination] (VIEW).", 1) return + else if(href_list["refreshfaxpanel"]) + if(!check_rights(R_ADMIN)) + return + + fax_panel(usr) + else if(href_list["jumpto"]) if(!check_rights(R_ADMIN)) return @@ -1992,11 +2104,11 @@ if(gravity_is_on) log_admin("[key_name(usr)] toggled gravity on.", 1) message_admins("\blue [key_name_admin(usr)] toggled gravity on.", 1) - command_alert("Gravity generators are again functioning within normal parameters. Sorry for any inconvenience.") + command_announcement.Announce("Gravity generators are again functioning within normal parameters. Sorry for any inconvenience.") else log_admin("[key_name(usr)] toggled gravity off.", 1) message_admins("\blue [key_name_admin(usr)] toggled gravity off.", 1) - command_alert("Feedback surge detected in mass-distributions systems. Artifical gravity has been disabled whilst the system reinitializes. Further failures may result in a gravitational collapse and formation of blackholes. Have a nice day.") + command_announcement.Announce("Feedback surge detected in mass-distributions systems. Artifical gravity has been disabled whilst the system reinitializes. Further failures may result in a gravitational collapse and formation of blackholes. Have a nice day.") if("wave") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","Meteor") @@ -2095,7 +2207,7 @@ for(var/mob/living/carbon/human/H in mob_list) var/turf/loc = find_loc(H) var/security = 0 - if(loc.z > 1 || prisonwarped.Find(H)) + if(!(loc.z in config.station_levels) || prisonwarped.Find(H)) //don't warp them if they aren't ready or are already there continue @@ -2408,7 +2520,7 @@ message_admins("[key_name_admin(usr)] made the floor LAVA! It'll last [length] seconds and it will deal [damage] damage to everyone.", 1) for(var/turf/simulated/floor/F in world) - if(F.z == 1) + if((F.z in config.station_levels)) F.name = "lava" F.desc = "The floor is LAVA!" F.overlays += "lava" @@ -2433,7 +2545,7 @@ sleep(10) for(var/turf/simulated/floor/F in world) // Reset everything. - if(F.z == 1) + if((F.z in config.station_levels)) F.name = initial(F.name) F.desc = initial(F.desc) F.overlays.Cut() @@ -2481,11 +2593,10 @@ feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","EgL") for(var/obj/machinery/door/airlock/W in world) - if(W.z == 1 && !istype(get_area(W), /area/bridge) && !istype(get_area(W), /area/crew_quarters) && !istype(get_area(W), /area/security/prison)) + if((W.z in config.station_levels) && !istype(get_area(W), /area/bridge) && !istype(get_area(W), /area/crew_quarters) && !istype(get_area(W), /area/security/prison)) W.req_access = list() message_admins("[key_name_admin(usr)] activated Egalitarian Station mode") - command_alert("Centcomm airlock control override activated. Please take this time to get acquainted with your coworkers.") - world << sound('sound/AI/commandreport.ogg') + command_announcement.Announce("Centcomm airlock control override activated. Please take this time to get acquainted with your coworkers.", new_sound = 'sound/AI/commandreport.ogg') if("dorf") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","DF") @@ -2500,8 +2611,7 @@ message_admins("[key_name_admin(usr)] triggered an ion storm") var/show_log = alert(usr, "Show ion message?", "Message", "Yes", "No") if(show_log == "Yes") - command_alert("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert") - world << sound('sound/AI/ionstorm.ogg') + command_announcement.Announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", new_sound = 'sound/AI/ionstorm.ogg') if("carp") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","Crp") diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 3038b414334..2dd6ed7f892 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -21,7 +21,7 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," src.verbs += /client/verb/adminhelp // 2 minute cool-down for adminhelps//Go to hell **/ var/msg - var/list/type = list("Player Complaint","Question","Bug Report","Event") + var/list/type = list("Question","Player Complaint") var/selected_type = input("Pick a category.", "Admin Help", null, null) as null|anything in type if(selected_type) msg = input("Please enter your message.", "Admin Help", null, null) as text @@ -100,11 +100,9 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," var/admin_number_afk = 0 var/list/modholders = list() var/list/banholders = list() - var/list/debugholders = list() var/list/adminholders = list() - var/list/eventholders = list() for(var/client/X in admins) - if(R_MOD & X.holder.rights) + if((R_MOD | R_MENTOR) & X.holder.rights) if(X.is_afk()) admin_number_afk++ modholders += X @@ -114,10 +112,6 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," adminholders += X if(R_BAN & X.holder.rights) banholders += X - if(R_DEBUG & X.holder.rights) - debugholders += X - if(R_EVENT & X.holder.rights) - eventholders += X switch(selected_type) if("Question") @@ -132,30 +126,6 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," if(X.prefs.sound & SOUND_ADMINHELP) X << 'sound/effects/adminhelp.ogg' X << msg - else if("Bug Report") - if(debugholders.len) - for(var/client/X in debugholders) - if(X.prefs.sound & SOUND_ADMINHELP) - X << 'sound/effects/adminhelp.ogg' - X << msg - else - if(adminholders.len) - for(var/client/X in adminholders) - if(X.prefs.sound & SOUND_ADMINHELP) - X << 'sound/effects/adminhelp.ogg' - X << msg - else if("Event") - if(eventholders.len) - for(var/client/X in eventholders) - if(X.prefs.sound & SOUND_ADMINHELP) - X << 'sound/effects/adminhelp.ogg' - X << msg - else - if(banholders.len) - for(var/client/X in banholders) - if(X.prefs.sound & SOUND_ADMINHELP) - X << 'sound/effects/adminhelp.ogg' - X << msg else if("Player Complaint") if(banholders.len) for(var/client/X in banholders) diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 83f43ba6d9c..0b244992381 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -103,7 +103,7 @@ //mod PMs are maroon //PMs sent from admins and mods display their rank if(holder) - if( holder.rights & R_MOD && !holder.rights & R_ADMIN ) + if( holder.rights & (R_MOD | R_MENTOR) && !holder.rights & R_ADMIN ) recieve_color = "maroon" else recieve_color = "red" @@ -204,20 +204,14 @@ var/list/modholders = list() var/list/banholders = list() - var/list/debugholders = list() var/list/adminholders = list() - var/list/eventholders = list() for(var/client/X in admins) - if(R_MOD & X.holder.rights) + if((R_MOD | R_MENTOR) & X.holder.rights) modholders += X if(R_ADMIN & X.holder.rights) adminholders += X - if(R_DEBUG & X.holder.rights) - debugholders += X if(R_BAN & X.holder.rights) banholders += X - if(R_EVENT & X.holder.rights) - eventholders += X //we don't use message_admins here because the sender/receiver might get it too for(var/client/X in admins) @@ -227,20 +221,10 @@ if(X.key!=key && X.key!=C.key) switch(type) if("Question") - if(X.holder.rights & R_MOD) + if(X.holder.rights & (R_MOD | R_MENTOR)) X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: \blue [msg]" //inform X else if(!modholders.len && X.holder.rights & R_ADMIN) X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: \blue [msg]" //Any admins in backup of mod question - if("Bug Report") - if(X.holder.rights & R_DEBUG) - X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: \blue [msg]" //inform X - else if(!debugholders.len && X.holder.rights & R_ADMIN) - X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: \blue [msg]" //Any admins in backup of bug reports - if("Event") - if(X.holder.rights & R_EVENT) - X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: \blue [msg]" //inform X - else if(!eventholders.len && X.holder.rights & R_BAN) - X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: \blue [msg]" //Quality in backup of Event if("Player Complaint") if(X.holder.rights & R_BAN) X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: \blue [msg]" //There should always be at least 1 person with +BAN on @@ -273,6 +257,6 @@ for(var/client/X in admins) if(X == src) continue - if((X.holder.rights & R_ADMIN) || (X.holder.rights & R_MOD)) + if((X.holder.rights & R_ADMIN) || (X.holder.rights & (R_MOD | R_MENTOR))) X << "PM: [key_name(src, X, 0)]->IRC-Admins: \blue [msg]" diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 4ae2a560421..954c0618e16 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -14,23 +14,14 @@ client/proc/one_click_antag() var/dat = {"One-click Antagonist
Make Traitors
- Make Changlings
- Make Revs
+ Make Changelings
+ Make Revolutionaries
Make Cult
Make Malf AI
Make Wizard (Requires Ghosts)
- Make Vox Raiders (Requires Ghosts)
+ Make Vampires
+ Make Vox Raiders (Requires Ghosts)
"} -/* These dont work just yet - Ninja, aliens and deathsquad I have not looked into yet - Nuke team is getting a null mob returned from makebody() (runtime error: null.mind. Line 272) - - Make Nuke Team (Requires Ghosts)
- Make Space Ninja (Requires Ghosts)
- Make Aliens (Requires Ghosts)
- Make Deathsquad (Syndicate) (Requires Ghosts)
- "} -*/ usr << browse(dat, "window=oneclickantag;size=400x400") return @@ -42,7 +33,7 @@ client/proc/one_click_antag() var/datum/mind/themind = null for(var/mob/living/silicon/ai/ai in player_list) - if(ai.client) + if(ai.client && ai.client.prefs.be_special & BE_MALF) AIs += ai if(AIs.len) @@ -67,12 +58,14 @@ client/proc/one_click_antag() for(var/mob/living/carbon/human/applicant in player_list) if(applicant.client.prefs.be_special & BE_TRAITOR) - if(!applicant.stat) - if(applicant.mind) - if (!applicant.mind.special_role) - if(!jobban_isbanned(applicant, "traitor") && !jobban_isbanned(applicant, "Syndicate")) - if(!(applicant.job in temp.restricted_jobs)) - candidates += applicant + if(player_old_enough_antag(applicant.client,BE_TRAITOR)) + if(!applicant.stat) + if(applicant.mind) + if (!applicant.mind.special_role) + if(!jobban_isbanned(applicant, "traitor") && !jobban_isbanned(applicant, "Syndicate")) + if(!(applicant.mind.assigned_role in temp.restricted_jobs)) + if(!(applicant.client.prefs.species in temp.protected_species)) + candidates += applicant if(candidates.len) var/numTratiors = min(candidates.len, 3) @@ -99,12 +92,14 @@ client/proc/one_click_antag() for(var/mob/living/carbon/human/applicant in player_list) if(applicant.client.prefs.be_special & BE_CHANGELING) - if(!applicant.stat) - if(applicant.mind) - if (!applicant.mind.special_role) - if(!jobban_isbanned(applicant, "changeling") && !jobban_isbanned(applicant, "Syndicate")) - if(!(applicant.job in temp.restricted_jobs)) - candidates += applicant + if(player_old_enough_antag(applicant.client,BE_CHANGELING)) + if(!applicant.stat) + if(applicant.mind) + if (!applicant.mind.special_role) + if(!jobban_isbanned(applicant, "changeling") && !jobban_isbanned(applicant, "Syndicate")) + if(!(applicant.mind.assigned_role in temp.restricted_jobs)) + if(!(applicant.client.prefs.species in temp.protected_species)) + candidates += applicant if(candidates.len) var/numChanglings = min(candidates.len, 3) @@ -129,12 +124,14 @@ client/proc/one_click_antag() for(var/mob/living/carbon/human/applicant in player_list) if(applicant.client.prefs.be_special & BE_REV) - if(applicant.stat == CONSCIOUS) - if(applicant.mind) - if(!applicant.mind.special_role) - if(!jobban_isbanned(applicant, "revolutionary") && !jobban_isbanned(applicant, "Syndicate")) - if(!(applicant.job in temp.restricted_jobs)) - candidates += applicant + if(player_old_enough_antag(applicant.client,BE_REV)) + if(applicant.stat == CONSCIOUS) + if(applicant.mind) + if(!applicant.mind.special_role) + if(!jobban_isbanned(applicant, "revolutionary") && !jobban_isbanned(applicant, "Syndicate")) + if(!(applicant.mind.assigned_role in temp.restricted_jobs)) + if(!(applicant.client.prefs.species in temp.protected_species)) + candidates += applicant if(candidates.len) var/numRevs = min(candidates.len, 3) @@ -153,17 +150,19 @@ client/proc/one_click_antag() var/time_passed = world.time for(var/mob/G in respawnable_list) - if(!jobban_isbanned(G, "wizard") && !jobban_isbanned(G, "Syndicate")) - spawn(0) - switch(G.timed_alert("Do you wish to be considered for the position of Space Wizard Foundation 'diplomat'?","Please answer in 30 seconds!","No",300,"Yes","No"))//alert(G, "Do you wish to be considered for the position of Space Wizard Foundation 'diplomat'?","Please answer in 30 seconds!","Yes","No")) - if("Yes") - if((world.time-time_passed)>300)//If more than 30 game seconds passed. - return - candidates += G - if("No") - return - else - return + if(G.client.prefs.be_special & BE_WIZARD) + if(!jobban_isbanned(G, "wizard") && !jobban_isbanned(G, "Syndicate")) + if(player_old_enough_antag(G.client,BE_WIZARD)) + spawn(0) + switch(G.timed_alert("Do you wish to be considered for the position of Space Wizard Foundation 'diplomat'?","Please answer in 30 seconds!","No",300,"Yes","No"))//alert(G, "Do you wish to be considered for the position of Space Wizard Foundation 'diplomat'?","Please answer in 30 seconds!","Yes","No")) + if("Yes") + if((world.time-time_passed)>300)//If more than 30 game seconds passed. + return + candidates += G + if("No") + return + else + return sleep(300) @@ -194,12 +193,14 @@ client/proc/one_click_antag() for(var/mob/living/carbon/human/applicant in player_list) if(applicant.client.prefs.be_special & BE_CULTIST) - if(applicant.stat == CONSCIOUS) - if(applicant.mind) - if(!applicant.mind.special_role) - if(!jobban_isbanned(applicant, "cultist") && !jobban_isbanned(applicant, "Syndicate")) - if(!(applicant.job in temp.restricted_jobs)) - candidates += applicant + if(player_old_enough_antag(applicant.client,BE_CULTIST)) + if(applicant.stat == CONSCIOUS) + if(applicant.mind) + if(!applicant.mind.special_role) + if(!jobban_isbanned(applicant, "cultist") && !jobban_isbanned(applicant, "Syndicate")) + if(!(applicant.mind.assigned_role in temp.restricted_jobs)) + if(!(applicant.client.prefs.species in temp.protected_species)) + candidates += applicant if(candidates.len) var/numCultists = min(candidates.len, 4) @@ -223,17 +224,19 @@ client/proc/one_click_antag() var/time_passed = world.time for(var/mob/G in respawnable_list) - if(!jobban_isbanned(G, "operative") && !jobban_isbanned(G, "Syndicate")) - spawn(0) - switch(alert(G,"Do you wish to be considered for a nuke team being sent in?","Please answer in 30 seconds!","Yes","No")) - if("Yes") - if((world.time-time_passed)>300)//If more than 30 game seconds passed. - return - candidates += G - if("No") - return - else - return + if(G.client.prefs.be_special & BE_OPERATIVE) + if(!jobban_isbanned(G, "operative") && !jobban_isbanned(G, "Syndicate")) + if(player_old_enough_antag(G.client,BE_OPERATIVE)) + spawn(0) + switch(alert(G,"Do you wish to be considered for a nuke team being sent in?","Please answer in 30 seconds!","Yes","No")) + if("Yes") + if((world.time-time_passed)>300)//If more than 30 game seconds passed. + return + candidates += G + if("No") + return + else + return sleep(300) @@ -328,16 +331,17 @@ client/proc/one_click_antag() //Generates a list of commandos from active ghosts. Then the user picks which characters to respawn as the commandos. for(var/mob/G in respawnable_list) - spawn(0) - switch(alert(G,"Do you wish to be considered for an elite syndicate strike team being sent in?","Please answer in 30 seconds!","Yes","No")) - if("Yes") - if((world.time-time_passed)>300)//If more than 30 game seconds passed. + if(!jobban_isbanned(G, "Syndicate")) + spawn(0) + switch(alert(G,"Do you wish to be considered for an elite syndicate strike team being sent in?","Please answer in 30 seconds!","Yes","No")) + if("Yes") + if((world.time-time_passed)>300)//If more than 30 game seconds passed. + return + candidates += G + if("No") + return + else return - candidates += G - if("No") - return - else - return sleep(300) for(var/mob/dead/observer/G in candidates) @@ -445,16 +449,19 @@ client/proc/one_click_antag() //Generates a list of candidates from active ghosts. for(var/mob/G in respawnable_list) - spawn(0) - switch(alert(G,"Do you wish to be considered for a vox raiding party arriving on the station?","Please answer in 30 seconds!","Yes","No")) - if("Yes") - if((world.time-time_passed)>300)//If more than 30 game seconds passed. - return - candidates += G - if("No") - return - else - return + if(G.client.prefs.be_special & BE_RAIDER) + if(player_old_enough_antag(G.client,BE_RAIDER)) + if(!jobban_isbanned(G, "raider") && !jobban_isbanned(G, "Syndicate")) + spawn(0) + switch(alert(G,"Do you wish to be considered for a vox raiding party arriving on the station?","Please answer in 30 seconds!","Yes","No")) + if("Yes") + if((world.time-time_passed)>300)//If more than 30 game seconds passed. + return + candidates += G + if("No") + return + else + return sleep(300) //Debug. @@ -532,4 +539,36 @@ client/proc/one_click_antag() ticker.mode.traitors += new_vox.mind new_vox.equip_vox_raider() - return new_vox \ No newline at end of file + return new_vox + +/datum/admins/proc/makeVampires() + + var/datum/game_mode/vampire/temp = new + if(config.protect_roles_from_antagonist) + temp.restricted_jobs += temp.protected_jobs + + var/list/mob/living/carbon/human/candidates = list() + var/mob/living/carbon/human/H = null + + for(var/mob/living/carbon/human/applicant in player_list) + if(applicant.client.prefs.be_special & BE_VAMPIRE) + if(player_old_enough_antag(applicant.client,BE_VAMPIRE)) + if(!applicant.stat) + if(applicant.mind) + if (!applicant.mind.special_role) + if(!jobban_isbanned(applicant, "vampire") && !jobban_isbanned(applicant, "Syndicate")) + if(!(applicant.job in temp.restricted_jobs)) + if(!(applicant.client.prefs.species in temp.protected_species)) + candidates += applicant + + if(candidates.len) + var/numVampires = min(candidates.len, 3) + + for(var/i = 0, i 1) + if (!(computer.z in config.station_levels)) usr << "\red Unable to establish a connection: \black You're too far away from the station!" return @@ -68,11 +74,11 @@ authenticated = 1 if(access_captain in I.GetAccess()) authenticated = 2 - if(istype(I,/obj/item/weapon/card/emag)) - authenticated = 2 - computer.emagged = 1 + crew_announcement.announcer = GetNameAndAssignmentFromId(I) + if("logout" in href_list) authenticated = 0 + crew_announcement.announcer = "" if("swipeidseclevel" in href_list) var/mob/M = usr @@ -104,13 +110,13 @@ usr << "You need to swipe your ID." if("announce" in href_list) if(authenticated==2) - if(message_cooldown) return - var/input = stripped_input(usr, "Please choose a message to announce to the station crew.", "What?") + if(message_cooldown) + usr << "Please allow at least one minute to pass between announcements" + return + var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement") if(!input || !interactable()) return - captain_announce(input)//This should really tell who is, IE HoP, CE, HoS, RD, Captain - log_say("[key_name(usr)] has made a captain announcement: [input]") - message_admins("[key_name_admin(usr)] has made a captain announcement.", 1) + crew_announcement.Announce(input) message_cooldown = 1 spawn(600)//One minute cooldown message_cooldown = 0 diff --git a/code/modules/computer3/computers/shuttle.dm b/code/modules/computer3/computers/shuttle.dm index 5d5fab6528b..9f0619ce321 100644 --- a/code/modules/computer3/computers/shuttle.dm +++ b/code/modules/computer3/computers/shuttle.dm @@ -60,11 +60,13 @@ world << "\blue All authorizations to shorting time for shuttle launch have been revoked!" src.authorized.len = 0 src.authorized = list( ) - - else if (istype(W, /obj/item/card/emag) && !emagged) + return + + emag_act(user as mob) + if (!emagged) var/choice = alert(user, "Would you like to launch the shuttle?","Shuttle control", "Launch", "Cancel") - if(!emagged && emergency_shuttle.location == 1 && user.get_active_hand() == W) + if(!emagged && emergency_shuttle.location == 1) switch(choice) if("Launch") world << "\blue Alert: Shuttle launch time shortened to 10 seconds!" @@ -72,4 +74,3 @@ emagged = 1 if("Cancel") return - return diff --git a/code/modules/economy/Accounts.dm b/code/modules/economy/Accounts.dm index 91d8662227c..018ce78cd3a 100644 --- a/code/modules/economy/Accounts.dm +++ b/code/modules/economy/Accounts.dm @@ -125,13 +125,13 @@ var/global/list/all_money_accounts = list() var/money = 0 var/suspended = 0 var/list/transaction_log = list() - var/security_level = 1 //0 - auto-identify from worn ID, require only account number + var/security_level = 0 //0 - auto-identify from worn ID, require only account number //1 - require manual login / account number and pin //2 - require card and manual login /datum/money_account/New() ..() - security_level = pick (0,1) //Stealing is now slightly viable + //security_level = pick (0,1) //Stealing is now slightly viable /datum/transaction var/target_name = "" diff --git a/code/modules/economy/Economy.dm b/code/modules/economy/Economy.dm index cf78723a683..b41a080d251 100644 --- a/code/modules/economy/Economy.dm +++ b/code/modules/economy/Economy.dm @@ -67,7 +67,15 @@ var/setup_economy = 0 /proc/setup_economy() if(setup_economy) return + var/datum/feed_channel/newChannel = new /datum/feed_channel + newChannel.channel_name = "Public Station Announcements" + newChannel.author = "Automated Announcement Listing" + newChannel.locked = 1 + newChannel.is_admin_channel = 1 + news_network.network_channels += newChannel + + newChannel = new /datum/feed_channel newChannel.channel_name = "Tau Ceti Daily" newChannel.author = "CentComm Minister of Information" newChannel.locked = 1 diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm index a86219ba03a..b69a656ca1d 100644 --- a/code/modules/events/alien_infestation.dm +++ b/code/modules/events/alien_infestation.dm @@ -15,18 +15,17 @@ /datum/event/alien_infestation/announce() if(successSpawn) - command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert") - world << sound('sound/AI/aliens.ogg') + command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') /datum/event/alien_infestation/start() var/list/vents = list() for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world) - if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network) + if((temp_vent.loc.z in config.station_levels) && !temp_vent.welded && temp_vent.network) if(temp_vent.network.normal_members.len > 50) //Stops Aliens getting stuck in small networks. See: Security, Virology vents += temp_vent - var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET,"alien","Syndicate") + var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET) while(spawncount > 0 && vents.len && candidates.len) var/obj/vent = pick_n_take(vents) diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm index 96729f0014c..abc3fa87d48 100644 --- a/code/modules/events/blob.dm +++ b/code/modules/events/blob.dm @@ -7,8 +7,7 @@ /datum/event/blob/announce() - command_alert("Confirmed outbreak of level 7 biohazard aboard [station_name()]. Nanotrasen has issued a directive 7-10. The station is to be considered quarantined.", "Biohazard Alert") - world << sound('sound/AI/blob_confirmed.ogg') + command_announcement.Announce("Confirmed outbreak of level 7 biohazard aboard [station_name()]. Nanotrasen has issued a directive 7-10. The station is to be considered quarantined.", "Biohazard Alert", new_sound = 'sound/AI/blob_confirmed.ogg') for (var/mob/living/silicon/ai/aiPlayer in player_list) if (aiPlayer.client) @@ -39,14 +38,14 @@ /datum/event/blob/proc/announce_nuke() var/nukecode = "ERROR" for(var/obj/machinery/nuclearbomb/bomb in world) - if(bomb && bomb.r_code && bomb.z == 1) + if(bomb && bomb.r_code && (bomb.z in config.station_levels)) nukecode = bomb.r_code - command_alert("The biohazard has grown out of control and will soon reach critical mass. Activate the nuclear failsafe to maintain quarantine. The Nuclear Authentication Code is [nukecode] ", "Biohazard Alert") + command_announcement.Announce("The biohazard has grown out of control and will soon reach critical mass. Activate the nuclear failsafe to maintain quarantine. The Nuclear Authentication Code is [nukecode] ", "Biohazard Alert") set_security_level("gamma") var/obj/machinery/door/airlock/vault/V = locate(/obj/machinery/door/airlock/vault) in world - if(V && V.z == 1) + if(V && (V.z in config.station_levels)) V.locked = 0 V.update_icon() @@ -64,7 +63,7 @@ spawn(10) if(Blob || blob_cores.len) return - command_alert("The level 7 biohazard aboard [station_name()] has been eliminated. Directive 7-10 has been lifted, and the station is no longer quarantined.", "Biohazard Update") + command_announcement.Announce("The level 7 biohazard aboard [station_name()] has been eliminated. Directive 7-10 has been lifted, and the station is no longer quarantined.", "Biohazard Update") for (var/mob/living/silicon/ai/aiPlayer in player_list) if (aiPlayer.client) diff --git a/code/modules/events/borers.dm b/code/modules/events/borers.dm index 60d342628bd..14010e22fc3 100644 --- a/code/modules/events/borers.dm +++ b/code/modules/events/borers.dm @@ -12,18 +12,17 @@ /datum/event/borer_infestation/announce() if(successSpawn) - command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert") - world << sound('sound/AI/aliens.ogg') + command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') /datum/event/borer_infestation/start() var/list/vents = list() for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world) - if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network) + if((temp_vent.loc.z in config.station_levels) && !temp_vent.welded && temp_vent.network) //Stops cortical borers getting stuck in small networks. See: Security, Virology if(temp_vent.network.normal_members.len > 50) vents += temp_vent - var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET,"alien","Syndicate") + var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET) while(spawncount > 0 && vents.len && candidates.len) var/obj/vent = pick_n_take(vents) var/client/C = pick_n_take(candidates) diff --git a/code/modules/events/brand_intelligence.dm b/code/modules/events/brand_intelligence.dm index a2436f2ac75..4f2616e7c0f 100644 --- a/code/modules/events/brand_intelligence.dm +++ b/code/modules/events/brand_intelligence.dm @@ -8,11 +8,11 @@ var/obj/machinery/vending/originMachine /datum/event/brand_intelligence/announce() - command_alert("Rampant brand intelligence has been detected aboard [station_name()], please stand-by.", "Machine Learning Alert") + command_announcement.Announce("Rampant brand intelligence has been detected aboard [station_name()], please stand-by.", "Machine Learning Alert") /datum/event/brand_intelligence/start() for(var/obj/machinery/vending/V in machines) - if(V.z != 1) continue + if(!(V.z in config.station_levels)) continue vendingMachines.Add(V) if(!vendingMachines.len) diff --git a/code/modules/events/cargobonus.dm b/code/modules/events/cargobonus.dm index f0c84b86f54..fb1a3ac277e 100644 --- a/code/modules/events/cargobonus.dm +++ b/code/modules/events/cargobonus.dm @@ -2,7 +2,7 @@ announceWhen = 5 /datum/event/cargo_bonus/announce() - command_alert("Congratulations! [station_name()] was chosen for supply limit increase, please contact local cargo department for details!", "Supply Alert") + command_announcement.Announce("Congratulations! [station_name()] was chosen for supply limit increase, please contact local cargo department for details!", "Supply Alert") /datum/event/cargo_bonus/start() supply_controller.points+=rand(100,500) \ No newline at end of file diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm index 7cf82ff1f67..303f5686e8e 100644 --- a/code/modules/events/carp_migration.dm +++ b/code/modules/events/carp_migration.dm @@ -8,7 +8,7 @@ endWhen = rand(600,1200) /datum/event/carp_migration/announce() - command_alert("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert") + command_announcement.Announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert") /datum/event/carp_migration/start() for(var/obj/effect/landmark/C in landmarks_list) diff --git a/code/modules/events/comms_blackout.dm b/code/modules/events/comms_blackout.dm index 2f5cbea97b3..6b948538d5d 100644 --- a/code/modules/events/comms_blackout.dm +++ b/code/modules/events/comms_blackout.dm @@ -1,6 +1,6 @@ /proc/communications_blackout(var/silent = 1) if(!silent) - command_alert("Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you-BZZT") + command_announcement.Announce("Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you-BZZT") else // AIs will always know if there's a comm blackout, rogue AIs could then lie about comm blackouts in the future while they shutdown comms for(var/mob/living/silicon/ai/A in player_list) A << "
" diff --git a/code/modules/events/communications_blackout.dm b/code/modules/events/communications_blackout.dm index d437d85684e..d39517f5343 100644 --- a/code/modules/events/communications_blackout.dm +++ b/code/modules/events/communications_blackout.dm @@ -12,7 +12,7 @@ A << "
" if(prob(30)) //most of the time, we don't want an announcement, so as to allow AIs to fake blackouts. - command_alert(alert) + command_announcement.Announce(alert) /datum/event/communications_blackout/start() for(var/obj/machinery/telecomms/T in telecomms_list) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index a12aa2147c5..ec4ea8b8d3a 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -3,8 +3,7 @@ oneShot = 1 /datum/event/disease_outbreak/announce() - command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert") - world << sound('sound/AI/outbreak7.ogg') + command_announcement.Announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg') /datum/event/disease_outbreak/setup() announceWhen = rand(15, 30) @@ -17,7 +16,7 @@ var/turf/T = get_turf(H) if(!T) continue - if(T.z != 1) + if(!(T.z in config.station_levels)) continue for(var/datum/disease/D in H.viruses) foundAlready = 1 diff --git a/code/modules/events/electrical_storm.dm b/code/modules/events/electrical_storm.dm index 2b9b989e5e9..a8254d02c7a 100644 --- a/code/modules/events/electrical_storm.dm +++ b/code/modules/events/electrical_storm.dm @@ -3,7 +3,7 @@ var/lightsoutRange = 25 /datum/event/electrical_storm/announce() - command_alert("An electrical storm has been detected in your area, please repair potential electronic overloads.", "Electrical Storm Alert") + command_announcement.Announce("An electrical storm has been detected in your area, please repair potential electronic overloads.", "Electrical Storm Alert") /datum/event/electrical_storm/start() var/list/epicentreList = list() diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 622e62b5172..effa2845d01 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -135,8 +135,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Vermin Infestation",/datum/event/infestation, 100, list(ASSIGNMENT_JANITOR = 100)), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Wallrot", /datum/event/wallrot, 0, list(ASSIGNMENT_ENGINEER = 30, ASSIGNMENT_GARDENER = 50)), // NON-BAY EVENTS - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Cargo Bonus", /datum/event/cargo_bonus, 150), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Mass Hallucination",/datum/event/mass_hallucination,200), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Cargo Bonus", /datum/event/cargo_bonus, 100) ) /datum/event_container/moderate @@ -145,9 +144,9 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT new /datum/event_meta(EVENT_LEVEL_MODERATE, "Nothing", /datum/event/nothing, 1230), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Carp School", /datum/event/carp_migration, 100, list(ASSIGNMENT_ENGINEER = 10, ASSIGNMENT_SECURITY = 20), 1), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Rogue Drones", /datum/event/rogue_drone, 20, list(ASSIGNMENT_SECURITY = 20)), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space vines", /datum/event/spacevine, 200, list(ASSIGNMENT_ENGINEER = 10)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space Vines", /datum/event/spacevine, 200, list(ASSIGNMENT_ENGINEER = 10)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meteor Shower", /datum/event/meteor_shower, 0, list(ASSIGNMENT_ENGINEER = 20)), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meaty Ores", /datum/event/dust/meaty, 0, list(ASSIGNMENT_ENGINEER = 20)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meaty Ores", /datum/event/dust/meaty, 0, list(ASSIGNMENT_ENGINEER = 30)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Communication Blackout", /datum/event/communications_blackout, 500, list(ASSIGNMENT_AI = 150, ASSIGNMENT_SECURITY = 120)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Prison Break", /datum/event/prison_break, 0, list(ASSIGNMENT_SECURITY = 100)), // new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grid Check", /datum/event/grid_check, 200, list(ASSIGNMENT_ENGINEER = 60)), @@ -156,18 +155,19 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT new /datum/event_meta(EVENT_LEVEL_MODERATE, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 150)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ionstorm, 0, list(ASSIGNMENT_AI = 50, ASSIGNMENT_CYBORG = 50, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5)), - new /datum/event_meta/alien(EVENT_LEVEL_MODERATE, "Alien Infestation", /datum/event/alien_infestation, 2.5, list(ASSIGNMENT_SECURITY = 1), 1, 0, 5), - new /datum/event_meta/ninja(EVENT_LEVEL_MODERATE, "Space Ninja", /datum/event/space_ninja, 0, list(ASSIGNMENT_SECURITY = 1), 1, 0, 5), + new /datum/event_meta/alien(EVENT_LEVEL_MODERATE, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 20), 1), + new /datum/event_meta/ninja(EVENT_LEVEL_MODERATE, "Space Ninja", /datum/event/space_ninja, 0, list(ASSIGNMENT_SECURITY = 15), 1), // NON-BAY EVENTS - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space Dust", /datum/event/dust, 50, list(ASSIGNMENT_ENGINEER = 50)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Mass Hallucination", /datum/event/mass_hallucination, 300), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space Dust", /datum/event/dust, 50, list(ASSIGNMENT_ENGINEER = 50)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Dimensional Tear", /datum/event/tear, 0, list(ASSIGNMENT_SECURITY = 25)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Vent Clog", /datum/event/vent_clog, 250), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Wormholes", /datum/event/wormholes, 150), - - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Pyro Anomaly", /datum/event/anomaly/anomaly_pyro, 100, list(ASSIGNMENT_ENGINEER = 60)), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Vortex Anomaly", /datum/event/anomaly/anomaly_vortex, 50, list(ASSIGNMENT_ENGINEER = 25)), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Bluespace Anomaly", /datum/event/anomaly/anomaly_bluespace, 50, list(ASSIGNMENT_ENGINEER = 25)), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Flux Anomaly", /datum/event/anomaly/anomaly_flux, 50, list(ASSIGNMENT_ENGINEER = 50)), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Gravitational Anomaly", /datum/event/anomaly/anomaly_grav, 200), +// new /datum/event_meta(EVENT_LEVEL_MODERATE, "Pyro Anomaly", /datum/event/anomaly/anomaly_pyro, 100, list(ASSIGNMENT_ENGINEER = 60)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Vortex Anomaly", /datum/event/anomaly/anomaly_vortex, 50, list(ASSIGNMENT_ENGINEER = 25)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Bluespace Anomaly", /datum/event/anomaly/anomaly_bluespace, 50, list(ASSIGNMENT_ENGINEER = 25)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Flux Anomaly", /datum/event/anomaly/anomaly_flux, 50, list(ASSIGNMENT_ENGINEER = 50)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Gravitational Anomaly", /datum/event/anomaly/anomaly_grav, 200), ) /datum/event_container/major diff --git a/code/modules/events/event_dynamic.dm b/code/modules/events/event_dynamic.dm index df494ddc245..1dd1956c7ab 100644 --- a/code/modules/events/event_dynamic.dm +++ b/code/modules/events/event_dynamic.dm @@ -79,7 +79,7 @@ var/global/list/possibleEvents = list() if(!spacevines_spawned) possibleEvents[/datum/event/spacevine] = 10 + 5 * active_with_role["Engineer"] if(minutes_passed >= 30) // Give engineers time to set up engine - possibleEvents[/datum/event/anomaly/anomaly_pyro] = 100 + 60 * active_with_role["Engineer"] +// possibleEvents[/datum/event/anomaly/anomaly_pyro] = 100 + 60 * active_with_role["Engineer"] possibleEvents[/datum/event/anomaly/anomaly_vortex] = 50 + 25 * active_with_role["Engineer"] possibleEvents[/datum/event/anomaly/anomaly_bluespace] = 50 + 25 * active_with_role["Engineer"] possibleEvents[/datum/event/anomaly/anomaly_flux] = 50 + 50 * active_with_role["Engineer"] @@ -152,10 +152,7 @@ var/global/list/possibleEvents = list() /*switch(picked_event) if("Meteor") - command_alert("Meteors have been detected on collision course with the station.", "Meteor Alert") - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << sound('sound/AI/meteors.ogg') + command_announcement.Announce("Meteors have been detected on collision course with the station.", "Meteor Alert", new_sound = 'sound/AI/meteors.ogg') spawn(100) meteor_wave(10) spawn_meteors() diff --git a/code/modules/events/event_manager.dm b/code/modules/events/event_manager.dm index caff07fb8cc..604a4007ab9 100644 --- a/code/modules/events/event_manager.dm +++ b/code/modules/events/event_manager.dm @@ -3,6 +3,7 @@ var/window_y = 600 var/report_at_round_end = 0 var/table_options = " align='center'" + var/head_options = " style='font-weight:bold;'" var/row_options1 = " width='85px'" var/row_options2 = " width='260px'" var/row_options3 = " width='150px'" @@ -87,7 +88,7 @@ html += "
" html += "

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

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

Add Event

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

Event Start

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

Next Event

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

Running Events

" html += "Estimated times, affected by master controller delays." html += "" - html += "SeverityNameEnds AtEnds InStop" + html += "SeverityNameEnds AtEnds InStop" for(var/datum/event/E in active_events) if(!E.event_meta) continue diff --git a/code/modules/events/grid_check.dm b/code/modules/events/grid_check.dm index 71d78d96e4a..c485827efbc 100644 --- a/code/modules/events/grid_check.dm +++ b/code/modules/events/grid_check.dm @@ -8,9 +8,7 @@ power_failure(0) /datum/event/grid_check/announce() - command_alert("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Automated Grid Check") - for(var/mob/M in player_list) - M << sound('sound/AI/poweroff.ogg') + command_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Automated Grid Check", new_sound = 'sound/AI/poweroff.ogg') /datum/event/grid_check/end() power_restore() diff --git a/code/modules/events/infestation.dm b/code/modules/events/infestation.dm index 8971db74853..444da4675ef 100644 --- a/code/modules/events/infestation.dm +++ b/code/modules/events/infestation.dm @@ -102,7 +102,7 @@ /datum/event/infestation/announce() - command_alert("Bioscans indicate that [vermstring] have been breeding in [locstring]. Clear them out, before this starts to affect productivity.", "Lifesign Alert") + command_announcement.Announce("Bioscans indicate that [vermstring] have been breeding in [locstring]. Clear them out, before this starts to affect productivity.", "Lifesign Alert") #undef LOC_KITCHEN #undef LOC_ATMOS diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm index 7f66a4366a9..9e8f5d43b57 100644 --- a/code/modules/events/ion_storm.dm +++ b/code/modules/events/ion_storm.dm @@ -6,7 +6,7 @@ /datum/event/ionstorm/announce() endWhen = rand(500, 1500) -// command_alert("The station has entered an ion storm. Monitor all electronic equipment for malfunctions", "Anomaly Alert") +// command_announcement.Announce("The station has entered an ion storm. Monitor all electronic equipment for malfunctions", "Anomaly Alert") for (var/mob/living/carbon/human/player in world) if(player.client) players += player.real_name @@ -86,7 +86,7 @@ /datum/event/ionstorm/end() spawn(rand(5000,8000)) if(prob(50)) - command_alert("It has come to our attention that the station passed through an ion storm. Please monitor all electronic equipment for malfunctions.", "Anomaly Alert") + command_announcement.Announce("It has come to our attention that the station passed through an ion storm. Please monitor all electronic equipment for malfunctions.", "Anomaly Alert") /* /proc/IonStorm(botEmagChance = 10) @@ -212,21 +212,21 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is spawn(0) world << "Started processing APCs" for (var/obj/machinery/power/apc/APC in world) - if(APC.z == 1) + if((APC.z in config.station_levels)) APC.ion_act() apcnum++ world << "Finished processing APCs. Processed: [apcnum]" spawn(0) world << "Started processing SMES" for (var/obj/machinery/power/smes/SMES in world) - if(SMES.z == 1) + if((SMES.z in config.station_levels)) SMES.ion_act() smesnum++ world << "Finished processing SMES. Processed: [smesnum]" spawn(0) world << "Started processing AIRLOCKS" for (var/obj/machinery/door/airlock/D in world) - if(D.z == 1) + if((D.z in config.station_levels)) //if(length(D.req_access) > 0 && !(12 in D.req_access)) //not counting general access and maintenance airlocks airlocknum++ spawn(0) @@ -235,7 +235,7 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is spawn(0) world << "Started processing FIREDOORS" for (var/obj/machinery/door/firedoor/D in world) - if(D.z == 1) + if((D.z in config.station_levels)) firedoornum++; spawn(0) D.ion_act() diff --git a/code/modules/events/mass_hallucination.dm b/code/modules/events/mass_hallucination.dm index 571a9ae7d1f..b3fbea5343c 100644 --- a/code/modules/events/mass_hallucination.dm +++ b/code/modules/events/mass_hallucination.dm @@ -3,4 +3,4 @@ if(!(C.species.flags & IS_SYNTHETIC)) C.hallucination += rand(50, 100) /datum/event/mass_hallucination/announce() - command_alert("It seems that station [station_name()] is passing through a minor radiation field, this may cause some hallucination, but no further damage") \ No newline at end of file + command_announcement.Announce("It seems that station [station_name()] is passing through a minor radiation field, this may cause some hallucination, but no further damage") \ No newline at end of file diff --git a/code/modules/events/meteors.dm b/code/modules/events/meteors.dm index 0f74d65b7d9..42b0b1eda1d 100644 --- a/code/modules/events/meteors.dm +++ b/code/modules/events/meteors.dm @@ -9,15 +9,14 @@ endWhen = rand(10,25) * 3 /datum/event/meteor_wave/announce() - command_alert("Meteors have been detected on collision course with the station.", "Meteor Alert") - world << sound('sound/AI/meteors.ogg') - + command_announcement.Announce("Meteors have been detected on collision course with the station.", "Meteor Alert", new_sound = 'sound/AI/meteors.ogg') + /datum/event/meteor_wave/tick() if(IsMultiple(activeFor, 3)) spawn_meteors(rand(2,5)) /datum/event/meteor_wave/end() - command_alert("The station has cleared the meteor storm.", "Meteor Alert") + command_announcement.Announce("The station has cleared the meteor storm.", "Meteor Alert") // /datum/event/meteor_shower @@ -30,7 +29,7 @@ waves = rand(1,4) /datum/event/meteor_shower/announce() - command_alert("The station is now in a meteor shower.", "Meteor Alert") + command_announcement.Announce("The station is now in a meteor shower.", "Meteor Alert") //meteor showers are lighter and more common, /datum/event/meteor_shower/tick() @@ -44,4 +43,4 @@ endWhen = next_meteor + 1 /datum/event/meteor_shower/end() - command_alert("The station has cleared the meteor shower", "Meteor Alert") + command_announcement.Announce("The station has cleared the meteor shower", "Meteor Alert") diff --git a/code/modules/events/prison_break.dm b/code/modules/events/prison_break.dm index 87135bda526..676661f2b7e 100644 --- a/code/modules/events/prison_break.dm +++ b/code/modules/events/prison_break.dm @@ -15,7 +15,7 @@ /datum/event/prison_break/announce() if(prisonAreas && prisonAreas.len > 0) - command_alert("[pick("Gr3y.T1d3 virus","Malignant trojan")] detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert") + command_announcement.Announce("[pick("Gr3y.T1d3 virus","Malignant trojan")] detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert") else world.log << "ERROR: Could not initate grey-tide. Unable find prison or brig area." kill() @@ -30,7 +30,7 @@ /datum/event/prison_break/announce() if(prisonAreas && prisonAreas.len > 0) - command_alert("[pick("Gr3y.T1d3 virus","Malignant trojan")] detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert") + command_announcement.Announce("[pick("Gr3y.T1d3 virus","Malignant trojan")] detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert") else world.log << "ERROR: Could not initate grey-tide. Unable find prison or brig area." kill() diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm index 58b5f60c2cc..5daabc84799 100644 --- a/code/modules/events/radiation_storm.dm +++ b/code/modules/events/radiation_storm.dm @@ -22,11 +22,10 @@ /datum/event/radiation_storm/start() spawn() - world << sound('sound/AI/radiation.ogg') - command_alert("High levels of radiation detected near the station. Please evacuate into one of the shielded maintenance tunnels.", "Anomaly Alert") + command_announcement.Announce("High levels of radiation detected near the station. Please evacuate into one of the shielded maintenance tunnels.", "Anomaly Alert", new_sound = 'sound/AI/radiation.ogg') for(var/area/A in world) - if(A.z != 1 || is_safe_zone(A)) + if(!(A.z in config.station_levels) || is_safe_zone(A)) continue A.radiation_alert() @@ -36,7 +35,7 @@ sleep(600) - command_alert("The station has entered the radiation belt. Please remain in a sheltered area until we have passed the radiation belt.", "Anomaly Alert") + command_announcement.Announce("The station has entered the radiation belt. Please remain in a sheltered area until we have passed the radiation belt.", "Anomaly Alert") for(var/i = 0, i < 10, i++) for(var/mob/living/carbon/human/H in living_mob_list) @@ -45,7 +44,7 @@ var/turf/T = get_turf(H) if(!T) continue - if(T.z != 1 || is_safe_zone(T.loc)) + if(!(T.z in config.station_levels) || is_safe_zone(T.loc)) continue if(istype(H,/mob/living/carbon/human)) @@ -64,16 +63,16 @@ var/turf/T = get_turf(M) if(!T) continue - if(T.z != 1) + if(!(T.z in config.station_levels)) continue M.apply_effect((rand(5,25)),IRRADIATE,0) sleep(100) - command_alert("The station has passed the radiation belt. Please report to medbay if you experience any unusual symptoms. Maintenance will lose all access again shortly.", "Anomaly Alert") + command_announcement.Announce("The station has passed the radiation belt. Please report to medbay if you experience any unusual symptoms. Maintenance will lose all access again shortly.", "Anomaly Alert") for(var/area/A in world) - if(A.z != 1 || is_safe_zone(A)) + if(!(A.z in config.station_levels) || is_safe_zone(A)) continue A.reset_radiation_alert() diff --git a/code/modules/events/rogue_drones.dm b/code/modules/events/rogue_drones.dm index d3ccaa4d89a..d96c80f60f8 100644 --- a/code/modules/events/rogue_drones.dm +++ b/code/modules/events/rogue_drones.dm @@ -30,7 +30,7 @@ msg = "Contact has been lost with a combat drone wing operating out of the NMV Icarus. If any are sighted in the area, approach with caution." else msg = "Unidentified hackers have targetted a combat drone wing deployed from the NMV Icarus. If any are sighted in the area, approach with caution." - command_alert(msg, "Rogue drone alert") + command_announcement.Announce(msg, "Rogue drone alert") /datum/event/rogue_drone/tick() @@ -49,6 +49,6 @@ num_recovered++ if(num_recovered > drones_list.len * 0.75) - command_alert("Icarus drone control reports the malfunctioning wing has been recovered safely.", "Rogue drone alert") + command_announcement.Announce("Icarus drone control reports the malfunctioning wing has been recovered safely.", "Rogue drone alert") else - command_alert("Icarus drone control registers disappointment at the loss of the drones, but the survivors have been recovered.", "Rogue drone alert") + command_announcement.Announce("Icarus drone control registers disappointment at the loss of the drones, but the survivors have been recovered.", "Rogue drone alert") diff --git a/code/modules/events/sayuevents/meaty_ores.dm b/code/modules/events/sayuevents/meaty_ores.dm index a44708693ef..d6e640934d9 100644 --- a/code/modules/events/sayuevents/meaty_ores.dm +++ b/code/modules/events/sayuevents/meaty_ores.dm @@ -1,9 +1,8 @@ /datum/event/dust/meaty/announce() if(prob(16)) - command_alert("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert") + command_announcement.Announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert") else - command_alert("Meaty ores have been detected on collision course with the station.", "Meaty Ore Alert") - world << sound('sound/AI/meteors.ogg') + command_announcement.Announce("Meaty ores have been detected on collision course with the station.", "Meaty Ore Alert",new_sound = 'sound/AI/meteors.ogg') /datum/event/dust/meaty/setup() qnty = rand(45,125) diff --git a/code/modules/events/sayuevents/undead.dm b/code/modules/events/sayuevents/undead.dm index f9d82baf086..84c1c0bb1b1 100644 --- a/code/modules/events/sayuevents/undead.dm +++ b/code/modules/events/sayuevents/undead.dm @@ -8,7 +8,7 @@ RS.start() RS.kill() for(var/area/A) - if(A.z != 1) continue //Spook on main station only. + if(!(A.z in config.station_levels)) continue //Spook on main station only. if(A.luminosity) continue // if(A.lighting_space) continue if(A.type == /area) continue diff --git a/code/modules/events/sayuevents/wormholes.dm b/code/modules/events/sayuevents/wormholes.dm index e120d11630d..c31645d7a00 100644 --- a/code/modules/events/sayuevents/wormholes.dm +++ b/code/modules/events/sayuevents/wormholes.dm @@ -13,7 +13,7 @@ /datum/event/wormholes/start() for(var/turf/simulated/floor/T in world) - if(T.z == 1) + if((T.z in config.station_levels)) pick_turfs += T for(var/i = 1, i <= number_of_wormholes, i++) @@ -21,10 +21,7 @@ wormholes += new /obj/effect/portal/wormhole(T, null, null, -1) /datum/event/wormholes/announce() - command_alert("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert") - for(var/mob/M in player_list) - if(!istype(M, /mob/new_player)) - M << sound('sound/AI/spanomalies.ogg') + command_announcement.Announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", new_sound = 'sound/AI/spanomalies.ogg') /datum/event/wormholes/tick() if(activeFor % shift_frequency == 0) diff --git a/code/modules/events/spider_infestation.dm b/code/modules/events/spider_infestation.dm index 7a953d3fd40..227737ba99c 100644 --- a/code/modules/events/spider_infestation.dm +++ b/code/modules/events/spider_infestation.dm @@ -12,15 +12,13 @@ sent_spiders_to_station = 1 /datum/event/spider_infestation/announce() - command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert") - world << sound('sound/AI/aliens.ogg') - + command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') /datum/event/spider_infestation/start() var/list/vents = list() for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world) - if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network) + if((temp_vent.loc.z in config.station_levels) && !temp_vent.welded && temp_vent.network) if(temp_vent.network.normal_members.len > 50) vents += temp_vent diff --git a/code/modules/events/tear.dm b/code/modules/events/tear.dm index d5d572c3b6a..a11455b351d 100644 --- a/code/modules/events/tear.dm +++ b/code/modules/events/tear.dm @@ -5,7 +5,7 @@ var/obj/effect/tear/TE /datum/event/tear/announce() - command_alert("A tear in the fabric of space and time has opened. Expected location: [impact_area.name].", "Anomaly Alert") + command_announcement.Announce("A tear in the fabric of space and time has opened. Expected location: [impact_area.name].", "Anomaly Alert") /datum/event/tear/start() diff --git a/code/modules/events/tgevents/alien_infestation.dm b/code/modules/events/tgevents/alien_infestation.dm deleted file mode 100644 index 3d1dca58bc2..00000000000 --- a/code/modules/events/tgevents/alien_infestation.dm +++ /dev/null @@ -1,40 +0,0 @@ -/var/global/sent_aliens_to_station = 0 - -/datum/event/alien_infestation - announceWhen = 400 - - var/spawncount = 1 - var/successSpawn = 0 //So we don't make a command report if nothing gets spawned. - - -/datum/event/alien_infestation/setup() - announceWhen = rand(announceWhen, announceWhen + 50) - spawncount = rand(1, 2) - sent_aliens_to_station = 1 - - -/datum/event/alien_infestation/announce() - if(successSpawn) - command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert") - world << sound('sound/AI/aliens.ogg') - - -/datum/event/alien_infestation/start() - var/list/vents = list() - for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world) - if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network) - if(temp_vent.network.normal_members.len > 50) //Stops Aliens getting stuck in small networks. See: Security, Virology - vents += temp_vent - - var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET,"alien","Syndicate") - - while(spawncount > 0 && vents.len && candidates.len) - var/obj/vent = pick_n_take(vents) - var/client/C = pick_n_take(candidates) - if(C) - respawnable_list -= C - var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc) - new_xeno.key = C.key - - spawncount-- - successSpawn = 1 \ No newline at end of file diff --git a/code/modules/events/tgevents/anomaly.dm b/code/modules/events/tgevents/anomaly.dm index 7ab1f25c9ca..a1f951f5747 100644 --- a/code/modules/events/tgevents/anomaly.dm +++ b/code/modules/events/tgevents/anomaly.dm @@ -15,7 +15,7 @@ setup(safety_loop) /datum/event/anomaly/announce() - command_alert("Localized hyper-energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert") + command_announcement.Announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert") /datum/event/anomaly/start() var/turf/T = pick(get_area_turfs(impact_area)) diff --git a/code/modules/events/tgevents/anomaly_bluespace.dm b/code/modules/events/tgevents/anomaly_bluespace.dm index 224f6f0e2de..852680e69fa 100644 --- a/code/modules/events/tgevents/anomaly_bluespace.dm +++ b/code/modules/events/tgevents/anomaly_bluespace.dm @@ -4,7 +4,7 @@ endWhen = 160 /datum/event/anomaly/anomaly_bluespace/announce() - command_alert("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") + command_announcement.Announce("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") /datum/event/anomaly/anomaly_bluespace/start() @@ -21,7 +21,7 @@ var/obj/item/device/radio/beacon/chosen var/list/possible = list() for(var/obj/item/device/radio/beacon/W in world) - if(W.z != 1) + if(!(W.z in config.station_levels)) continue possible += W @@ -35,7 +35,7 @@ var/turf/TO = get_turf(chosen) // the turf of origin we're travelling TO playsound(TO, 'sound/effects/phasein.ogg', 100, 1) - command_alert("Massive bluespace translocation detected.", "Anomaly Alert") + command_announcement.Announce("Massive bluespace translocation detected.", "Anomaly Alert") var/list/flashers = list() for(var/mob/living/carbon/human/M in viewers(TO, null)) diff --git a/code/modules/events/tgevents/anomaly_flux.dm b/code/modules/events/tgevents/anomaly_flux.dm index bf2cb2d18cc..d02af07b3ef 100644 --- a/code/modules/events/tgevents/anomaly_flux.dm +++ b/code/modules/events/tgevents/anomaly_flux.dm @@ -4,7 +4,7 @@ endWhen = 180 /datum/event/anomaly/anomaly_flux/announce() - command_alert("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") + command_announcement.Announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") /datum/event/anomaly/anomaly_flux/start() var/turf/T = pick(get_area_turfs(impact_area)) diff --git a/code/modules/events/tgevents/anomaly_grav.dm b/code/modules/events/tgevents/anomaly_grav.dm index c5430625ea8..0c9f3776f82 100644 --- a/code/modules/events/tgevents/anomaly_grav.dm +++ b/code/modules/events/tgevents/anomaly_grav.dm @@ -4,7 +4,7 @@ endWhen = 70 /datum/event/anomaly/anomaly_grav/announce() - command_alert("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") + command_announcement.Announce("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") /datum/event/anomaly/anomaly_grav/start() var/turf/T = pick(get_area_turfs(impact_area)) diff --git a/code/modules/events/tgevents/anomaly_pyro.dm b/code/modules/events/tgevents/anomaly_pyro.dm index 4e7f6a0b947..df4805121cd 100644 --- a/code/modules/events/tgevents/anomaly_pyro.dm +++ b/code/modules/events/tgevents/anomaly_pyro.dm @@ -4,7 +4,7 @@ endWhen = 110 /datum/event/anomaly/anomaly_pyro/announce() - command_alert("Atmospheric anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") + command_announcement.Announce("Atmospheric anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") /datum/event/anomaly/anomaly_pyro/start() var/turf/T = pick(get_area_turfs(impact_area)) diff --git a/code/modules/events/tgevents/anomaly_vortex.dm b/code/modules/events/tgevents/anomaly_vortex.dm index 6f2f999e728..c950444978e 100644 --- a/code/modules/events/tgevents/anomaly_vortex.dm +++ b/code/modules/events/tgevents/anomaly_vortex.dm @@ -4,7 +4,7 @@ endWhen = 80 /datum/event/anomaly/anomaly_vortex/announce() - command_alert("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert") + command_announcement.Announce("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert") /datum/event/anomaly/anomaly_vortex/start() var/turf/T = pick(get_area_turfs(impact_area)) diff --git a/code/modules/events/tgevents/brand_intelligence.dm b/code/modules/events/tgevents/brand_intelligence.dm index 893cee98cf1..1cfeba0cd08 100644 --- a/code/modules/events/tgevents/brand_intelligence.dm +++ b/code/modules/events/tgevents/brand_intelligence.dm @@ -8,7 +8,7 @@ /datum/event/brand_intelligence/announce() - command_alert("Rampant brand intelligence has been detected aboard [station_name()], please stand-by.", "Machine Learning Alert") + command_announcement.Announce("Rampant brand intelligence has been detected aboard [station_name()], please stand-by.", "Machine Learning Alert") /datum/event/brand_intelligence/start() diff --git a/code/modules/events/tgevents/immovable_rod.dm b/code/modules/events/tgevents/immovable_rod.dm index 25c3d0308d4..ec86e89981f 100644 --- a/code/modules/events/tgevents/immovable_rod.dm +++ b/code/modules/events/tgevents/immovable_rod.dm @@ -12,7 +12,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 announceWhen = 5 /datum/event/immovable_rod/announce() - command_alert("What the fuck was that?!", "General Alert") + command_announcement.Announce("What the fuck was that?!", "General Alert") /datum/event/immovable_rod/start() var/startx = 0 diff --git a/code/modules/events/tgevents/mass_hallucination.dm b/code/modules/events/tgevents/mass_hallucination.dm index 6a34331acb3..f23a2c15510 100644 --- a/code/modules/events/tgevents/mass_hallucination.dm +++ b/code/modules/events/tgevents/mass_hallucination.dm @@ -6,4 +6,4 @@ if(!(C.species.flags & IS_SYNTHETIC)) C.hallucination += rand(50, 100) /datum/event/mass_hallucination/announce() - command_alert("It seems that station [station_name()] is passing through a minor radiation field, this may cause some hallucination, but no further damage") \ No newline at end of file + command_announcement.Announce("It seems that station [station_name()] is passing through a minor radiation field, this may cause some hallucination, but no further damage") \ No newline at end of file diff --git a/code/modules/events/tgevents/spider_infestation.dm b/code/modules/events/tgevents/spider_infestation.dm deleted file mode 100644 index 1f4cccdf418..00000000000 --- a/code/modules/events/tgevents/spider_infestation.dm +++ /dev/null @@ -1,33 +0,0 @@ -/var/global/sent_spiders_to_station = 0 - -/datum/event/spider_infestation - announceWhen = 400 - - var/spawncount = 1 - - -/datum/event/spider_infestation/setup() - announceWhen = rand(announceWhen, announceWhen + 50) - spawncount = round(num_players() * 1.5) - sent_spiders_to_station = 1 - -/datum/event/spider_infestation/announce() - command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert") - world << sound('sound/AI/aliens.ogg') - - -/datum/event/spider_infestation/start() - - var/list/vents = list() - for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world) - if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network) - if(temp_vent.network.normal_members.len > 50) - vents += temp_vent - - while((spawncount >= 1) && vents.len) - var/obj/vent = pick(vents) - var/obj/effect/spider/spiderling/S = new(vent.loc) - if(prob(66)) - S.grow_as = /mob/living/simple_animal/hostile/giant_spider/nurse - vents -= vent - spawncount-- \ No newline at end of file diff --git a/code/modules/events/tgevents/vent_clog.dm b/code/modules/events/tgevents/vent_clog.dm index 885552dff28..061450a197d 100755 --- a/code/modules/events/tgevents/vent_clog.dm +++ b/code/modules/events/tgevents/vent_clog.dm @@ -6,13 +6,13 @@ var/list/vents = list() /datum/event/vent_clog/announce() - command_alert("The scrubbers network is experiencing a backpressure surge. Some ejection of contents may occur.", "Atmospherics alert") + command_announcement.Announce("The scrubbers network is experiencing a backpressure surge. Some ejection of contents may occur.", "Atmospherics alert") /datum/event/vent_clog/setup() endWhen = rand(25, 100) for(var/obj/machinery/atmospherics/unary/vent_scrubber/temp_vent in machines) - if(temp_vent.loc.z == 1 && temp_vent.network) + if((temp_vent.loc.z in config.station_levels) && temp_vent.network) if(temp_vent.network.normal_members.len > 50) vents += temp_vent diff --git a/code/modules/events/viral_infection.dm b/code/modules/events/viral_infection.dm index 876e3453896..9ee3a47077a 100644 --- a/code/modules/events/viral_infection.dm +++ b/code/modules/events/viral_infection.dm @@ -8,8 +8,7 @@ datum/event/viral_infection/setup() severity = rand(1, 3) datum/event/viral_infection/announce() - command_alert("Confirmed outbreak of level five viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert") - world << sound('sound/AI/outbreak5.ogg') + command_announcement.Announce("Confirmed outbreak of level five viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak5.ogg') datum/event/viral_infection/start() var/list/candidates = list() //list of candidate keys diff --git a/code/modules/events/viral_outbreak.dm b/code/modules/events/viral_outbreak.dm index f11acd511f3..9e139f5742b 100644 --- a/code/modules/events/viral_outbreak.dm +++ b/code/modules/events/viral_outbreak.dm @@ -8,8 +8,7 @@ datum/event/viral_outbreak/setup() severity = rand(2, 4) datum/event/viral_outbreak/announce() - command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert") - world << sound('sound/AI/outbreak7.ogg') + command_announcement.Announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg') datum/event/viral_outbreak/start() var/list/candidates = list() //list of candidate keys diff --git a/code/modules/events/wallrot.dm b/code/modules/events/wallrot.dm index 739ca92411b..b36f7f93760 100644 --- a/code/modules/events/wallrot.dm +++ b/code/modules/events/wallrot.dm @@ -3,7 +3,7 @@ datum/event/wallrot/setup() endWhen = announceWhen + 1 datum/event/wallrot/announce() - command_alert("Harmful fungi detected on station. Station structures may be contaminated.", "Biohazard Alert") + command_announcement.Announce("Harmful fungi detected on station. Station structures may be contaminated.", "Biohazard Alert") datum/event/wallrot/start() spawn() diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm index 12924560685..0b97d51c8b3 100644 --- a/code/modules/karma/karma.dm +++ b/code/modules/karma/karma.dm @@ -52,42 +52,42 @@ var/list/karma_spenders = list() set name = "Award Karma" set desc = "Let the gods know whether someone's been nice. Can only be used once per round." set category = "Special Verbs" - + if(!ticker || !player_list.len) usr << "\red You can't award karma until the game has started." return - + if(ticker.current_state == GAME_STATE_PREGAME) usr << "\red You can't award karma until the game has started." - return + return var/list/karma_list = list("Cancel") - for(var/mob/M in player_list) if(M.client && M.mind) + for(var/mob/M in player_list) if(M.client && M.mind) var/special_role = M.mind.special_role if (special_role == "Wizard" || special_role == "Ninja" || special_role == "Syndicate" || special_role == "Syndicate Commando" || special_role == "Vox Raider" || special_role == "Alien") // Don't include special roles, because players use it to meta continue karma_list += M - + if(!karma_list.len || karma_list.len == 1) usr << "\red There's no-one to spend your karma on." return - + var/pickedmob = input("Who would you like to award Karma to?", "Award Karma", "Cancel") as null|mob in karma_list - + if(isnull(pickedmob)) return - + if(!istype(pickedmob, /mob)) usr << "\red That's not a mob." - return - + return + spend_karma(pickedmob) - -/mob/verb/spend_karma(var/mob/M) + +/mob/verb/spend_karma(var/mob/M) set name = "Award Karma to Player" set desc = "Let the gods know whether someone's been nice. Can only be used once per round." set category = "Special Verbs" - + if(!M) usr << "Please right click a mob to award karma directly, or use the 'Award Karma' verb to select a player from the player listing." return @@ -115,6 +115,9 @@ var/list/karma_spenders = list() if(!choice || choice == "Cancel") return if(choice == "Good" && !(src.client.karma_spent)) + if(src.client.karma_spent) + usr << "\red You've already spent your karma for the round." + return M.client.karma += 1 usr << "[choice] karma spent on [M.name]." src.client.karma_spent = 1 @@ -199,7 +202,7 @@ You've gained [totalkarma] total karma in your time here.
"} Unlock Vox -- 45KP
Unlock Slime People -- 45KP
"} - + if (2) // Karma Refunds var/list/refundable = list() var/list/purchased = checkpurchased() @@ -208,31 +211,31 @@ You've gained [totalkarma] total karma in your time here.
"} dat += "Refund Tajaran Ambassador -- 30KP
" if("Unathi Ambassador" in purchased) refundable += "Unathi Ambassador" - dat += "Refund Unathi Ambassador -- 30KP
" + dat += "Refund Unathi Ambassador -- 30KP
" if("Skrell Ambassador" in purchased) refundable += "Skrell Ambassador" - dat += "Refund Skrell Ambassador -- 30KP
" + dat += "Refund Skrell Ambassador -- 30KP
" if("Diona Ambassador" in purchased) refundable += "Diona Ambassador" - dat += "Refund Diona Ambassador -- 30KP
" + dat += "Refund Diona Ambassador -- 30KP
" if("Kidan Ambassador" in purchased) refundable += "Kidan Ambassador" - dat += "Refund Kidan Ambassador -- 30KP
" + dat += "Refund Kidan Ambassador -- 30KP
" if("Slime People Ambassador" in purchased) refundable += "Slime People Ambassador" - dat += "Refund Slime People Ambassador -- 30KP
" + dat += "Refund Slime People Ambassador -- 30KP
" if("Grey Ambassador" in purchased) refundable += "Grey Ambassador" - dat += "Refund Grey Ambassador -- 30KP
" + dat += "Refund Grey Ambassador -- 30KP
" if("Vox Ambassador" in purchased) refundable += "Vox Ambassador" dat += "Refund Vox Ambassador -- 30KP
" if("Customs Officer" in purchased) refundable += "Customs Officer" - dat += "Refund Customs Officer -- 30KP
" + dat += "Refund Customs Officer -- 30KP
" if("Nanotrasen Recruiter" in purchased) refundable += "Nanotrasen Recruiter" - dat += "Refund Nanotrasen Recruiter -- 10KP
" + dat += "Refund Nanotrasen Recruiter -- 10KP
" if(!refundable.len) dat += "You do not have any refundable karma purchases.
" @@ -345,7 +348,7 @@ You've gained [totalkarma] total karma in your time here.
"} usr << "You have been charged [cost] karma." message_admins("[key_name(usr)] has been charged [cost] karma.") return - + /client/proc/karmarefund(var/type,var/name,var/cost) if(name == "Tajaran Ambassador") cost = 30 @@ -368,12 +371,12 @@ You've gained [totalkarma] total karma in your time here.
"} else if(name == "Nanotrasen Recruiter") cost = 10 else - usr << "\red That job is not refundable." + usr << "\red That job is not refundable." return - + var/DBQuery/query = dbcon.NewQuery("SELECT * FROM whitelist WHERE ckey='[usr.key]'") query.Execute() - + var/dbjob var/dbspecies var/dbckey @@ -381,7 +384,7 @@ You've gained [totalkarma] total karma in your time here.
"} dbckey = query.item[2] dbjob = query.item[3] dbspecies = query.item[4] - + if(dbckey) var/list/typelist = list() if(type == "job") @@ -389,8 +392,8 @@ You've gained [totalkarma] total karma in your time here.
"} else if(type == "species") typelist = text2list(dbspecies,",") else - usr << "\red Type [type] is not a valid column." - + usr << "\red Type [type] is not a valid column." + if(name in typelist) typelist -= name var/newtypelist = list2text(typelist,",") @@ -406,14 +409,14 @@ You've gained [totalkarma] total karma in your time here.
"} karmacharge(text2num(cost),1) else usr << "\red You have not bought [name]." - + else - usr << "\red Your ckey ([dbckey]) was not found." - + usr << "\red Your ckey ([dbckey]) was not found." + /client/proc/checkpurchased(var/name = null) // If the first parameter is null, return a full list of purchases var/DBQuery/query = dbcon.NewQuery("SELECT * FROM whitelist WHERE ckey='[usr.key]'") - query.Execute() - + query.Execute() + var/dbjob var/dbspecies var/dbckey @@ -421,7 +424,7 @@ You've gained [totalkarma] total karma in your time here.
"} dbckey = query.item[2] dbjob = query.item[3] dbspecies = query.item[4] - + if(dbckey) var/list/joblist = text2list(dbjob,",") var/list/specieslist = text2list(dbspecies,",") @@ -434,4 +437,4 @@ You've gained [totalkarma] total karma in your time here.
"} else return combinedlist else - return 0 + return 0 diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index c1fdb193485..66c19bfcda0 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -238,8 +238,6 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f onclose(user, "library") /obj/machinery/librarycomp/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (src.density && istype(W, /obj/item/weapon/card/emag)) - src.emagged = 1 if(istype(W, /obj/item/weapon/barcodescanner)) var/obj/item/weapon/barcodescanner/scanner = W scanner.computer = src @@ -248,6 +246,10 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f V.show_message("[src] lets out a low, short blip.", 2) else ..() + +/obj/machinery/librarycomp/emag_act(user as mob) + if (src.density) + src.emagged = 1 /obj/machinery/librarycomp/Topic(href, href_list) if(..()) diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm index 1a0315b957d..82bc3a0f287 100644 --- a/code/modules/mining/equipment_locker.dm +++ b/code/modules/mining/equipment_locker.dm @@ -324,7 +324,7 @@ var/list/L = list() for(var/obj/item/device/radio/beacon/B in world) var/turf/T = get_turf(B) - if(T.z == 1) + if((T.z in config.station_levels)) L += B if(!L.len) user << "The [src.name] failed to create a wormhole." diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm index 0e0889bc637..ed588a76482 100644 --- a/code/modules/mining/laborcamp/laborstacker.dm +++ b/code/modules/mining/laborcamp/laborstacker.dm @@ -63,9 +63,10 @@ /obj/machinery/mineral/labor_claim_console/attackby(obj/item/I as obj, mob/user as mob) if(istype(I, /obj/item/weapon/card/id)) return attack_hand(user) - else if(istype(I, /obj/item/weapon/card/emag)) - return emag(user) ..() + +/obj/machinery/mineral/labor_claim_console/emag_act(user as mob) + emag(user) /obj/machinery/mineral/labor_claim_console/proc/emag(mob/user as mob) if(!emagged) diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 3a39126d517..f6c03ee308b 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -55,19 +55,22 @@ flags = CONDUCT slot_flags = SLOT_BELT force = 15.0 - throwforce = 4.0 + throwforce = 10.0 item_state = "pickaxe" w_class = 4.0 m_amt = 3750 //one sheet, but where can you make them? var/digspeed = 40 //moving the delay to an item var so R&D can make improved picks. --NEO origin_tech = "materials=1;engineering=1" attack_verb = list("hit", "pierced", "sliced", "attacked") - var/drill_sound = 'sound/weapons/Genhit.ogg' + var/list/digsound = list('sound/effects/picaxe1.ogg','sound/effects/picaxe2.ogg','sound/effects/picaxe3.ogg') var/drill_verb = "picking" sharp = 1 var/excavation_amount = 100 + proc/playDigSound() + playsound(src, pick(digsound),20,1) + hammer name = "sledgehammer" //icon_state = "sledgehammer" Waiting on sprite @@ -86,6 +89,8 @@ icon_state = "handdrill" item_state = "jackhammer" digspeed = 30 + hitsound = 'sound/weapons/drill.ogg' + digsound = list('sound/weapons/drill.ogg') origin_tech = "materials=2;powerstorage=3;engineering=2" desc = "Yours is the drill that will pierce through the rock walls." @@ -94,6 +99,8 @@ icon_state = "jackhammer" item_state = "jackhammer" digspeed = 15 //faster than drill, but cannot dig + hitsound = 'sound/weapons/sonic_jackhammer.ogg' + digsound = list('sound/weapons/sonic_jackhammer.ogg') origin_tech = "materials=3;powerstorage=2;engineering=2" desc = "Cracks rocks with sonic blasts, perfect for killing cave lizards." @@ -112,6 +119,8 @@ w_class = 3.0 //it is smaller than the pickaxe damtype = "fire" digspeed = 20 //Can slice though normal walls, all girders, or be used in reinforced wall deconstruction/ light thermite on fire + hitsound = 'sound/weapons/plasma_cutter.ogg' + digsound = list('sound/weapons/plasma_cutter.ogg') origin_tech = "materials=4;plasmatech=3;engineering=3" desc = "A rock cutter that uses bursts of hot plasma. You could use it to cut limbs off of xenos! Or, you know, mine stuff." @@ -129,6 +138,8 @@ item_state = "jackhammer" digspeed = 5 //Digs through walls, girders, and can dig up sand origin_tech = "materials=6;powerstorage=4;engineering=5" + hitsound = 'sound/weapons/drill.ogg' + digsound = list('sound/weapons/drill.ogg') desc = "Yours is the drill that will pierce the heavens!" traitor //Pocket-sized traitor diamond drill. @@ -143,6 +154,8 @@ icon_state = "jackhammer" item_state = "jackhammer" digspeed = 15 + hitsound = 'sound/weapons/drill.ogg' + digsound = list('sound/weapons/drill.ogg') desc = "" /*****************************Shovel********************************/ diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index b315ae31e5b..97216012983 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -137,7 +137,7 @@ return last_act = world.time - playsound(user, P.drill_sound, 20, 1) + P.playDigSound() //handle any archaeological finds we might uncover var/fail_message diff --git a/code/modules/mining/ore.dm b/code/modules/mining/ore.dm index fd3598ae985..866b46bae50 100644 --- a/code/modules/mining/ore.dm +++ b/code/modules/mining/ore.dm @@ -84,7 +84,7 @@ /obj/item/weapon/ore/New() pixel_x = rand(0,16)-8 pixel_y = rand(0,8)-8 - if(src.z == 5) score_oremined++ //When ore spawns, increment score. Only include ore spawned on mining asteroid (No Clown Planet) + if(src.z == ASTEROID_Z) score_oremined++ //When ore spawns, increment score. Only include ore spawned on mining asteroid (No Clown Planet) /obj/item/weapon/ore/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W,/obj/item/device/core_sampler)) diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm index 517a91a3501..2db6b56b75a 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -74,7 +74,7 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds AttemptGrow() /obj/item/alien_embryo/proc/AttemptGrow(var/gib_on_success = 1) - var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET,"alien","Syndicate") + var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET,1) var/client/C = null // To stop clientless larva, we will check that our host has a client diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 99c5e7a1ced..dfdd8b41195 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -130,7 +130,9 @@ //handcuffed? if(handcuffed) - if(istype(handcuffed, /obj/item/weapon/handcuffs/cable)) + if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/cable/zipties)) + msg += "[t_He] [t_is] \icon[handcuffed] restrained with zipties!\n" + else if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/cable)) msg += "[t_He] [t_is] \icon[handcuffed] restrained with cable!\n" else msg += "[t_He] [t_is] \icon[handcuffed] handcuffed!\n" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 2216038aeaa..5f3a0cca482 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -538,7 +538,21 @@ var/obj/vehicle/V = AM V.RunOver(src) - +// Get rank from ID, ID inside PDA, PDA, ID in wallet, etc. +/mob/living/carbon/human/proc/get_authentification_rank(var/if_no_id = "No id", var/if_no_job = "No job") + var/obj/item/device/pda/pda = wear_id + if (istype(pda)) + if (pda.id) + return pda.id.rank + else + return pda.ownrank + else + var/obj/item/weapon/card/id/id = get_idcard() + if(id) + return id.rank ? id.rank : if_no_job + else + return if_no_id + //gets assignment from ID or ID inside PDA or PDA itself //Useful when player do something with computers /mob/living/carbon/human/proc/get_assignment(var/if_no_id = "No id", var/if_no_job = "No job") diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 11ef4a1d587..de100bc759b 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -198,7 +198,17 @@ emp_act I.emp_act(severity) ..() - +/mob/living/carbon/human/emag_act(user as mob, var/datum/organ/external/affecting) + if(!(affecting.status & ORGAN_ROBOT)) + user << "\red That limb isn't robotic." + return + if(affecting.sabotaged) + user << "\red [src]'s [affecting.display_name] is already sabotaged!" + else + user << "\red You sneakily slide the card into the dataport on [src]'s [affecting.display_name] and short out the safeties." + affecting.sabotaged = 1 + return 1 + //Returns 1 if the attack hit, 0 if it missed. /mob/living/carbon/human/proc/attacked_by(var/obj/item/I, var/mob/living/user, var/def_zone) if(!I || !user) return 0 @@ -236,17 +246,8 @@ emp_act return 0 if(istype(I,/obj/item/weapon/card/emag)) - if(!(affecting.status & ORGAN_ROBOT)) - user << "\red That limb isn't robotic." - return - if(affecting.sabotaged) - user << "\red [src]'s [affecting.display_name] is already sabotaged!" - else - user << "\red You sneakily slide [I] into the dataport on [src]'s [affecting.display_name] and short out the safeties." - var/obj/item/weapon/card/emag/emag = I - emag.uses-- - affecting.sabotaged = 1 - return 1 + emag_act(user, affecting) + if(! I.discrete) if(I.attack_verb.len) visible_message("\red [src] has been [pick(I.attack_verb)] in the [hit_area] with [I.name] by [user]!") @@ -337,6 +338,15 @@ emp_act /mob/living/carbon/human/hitby(atom/movable/AM as mob|obj,var/speed = 5) if(istype(AM,/obj/)) var/obj/O = AM + + if(in_throw_mode && !get_active_hand() && speed <= 5) //empty active hand and we're in throw mode + if(canmove && !restrained()) + if(isturf(O.loc)) + put_in_active_hand(O) + visible_message("[src] catches [O]!") + throw_mode_off() + return + var/zone = ran_zone("chest", 65) var/dtype = BRUTE if(istype(O,/obj/item/weapon)) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 8eb38c1e7b0..8319046d5d5 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1537,7 +1537,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc // Not on the station or mining? var/turf/temp_turf = get_turf(remoteview_target) - if((temp_turf.z != 1 && temp_turf.z != 5) || remoteview_target.stat!=CONSCIOUS) + if((!(temp_turf.z in config.contact_levels)) || remoteview_target.stat!=CONSCIOUS) src << "\red Your psy-connection grows too faint to maintain!" isRemoteObserve = 0 if(!isRemoteObserve && client && !client.adminobs) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 200ade3009a..9a47536c759 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -918,7 +918,7 @@ proc/get_damage_icon_part(damage_state, body_part) var/obj/screen/inventory/L = hud_used.adding[8] R.overlays += image("icon"='icons/mob/screen_gen.dmi', "icon_state"="markus") L.overlays += image("icon"='icons/mob/screen_gen.dmi', "icon_state"="gabrielle") - if(istype(handcuffed, /obj/item/weapon/handcuffs/pinkcuffs)) + if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/pinkcuffs)) overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "pinkcuff1") else overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff1") diff --git a/code/modules/mob/living/carbon/monkey/inventory.dm b/code/modules/mob/living/carbon/monkey/inventory.dm index 2c5934da530..8ccadd0349c 100644 --- a/code/modules/mob/living/carbon/monkey/inventory.dm +++ b/code/modules/mob/living/carbon/monkey/inventory.dm @@ -164,7 +164,7 @@ W.layer = initial(W.layer) W.add_fingerprint(source) else - if (istype(item, /obj/item/weapon/handcuffs)) + if (istype(item, /obj/item/weapon/restraints/handcuffs)) source.drop_item() target.handcuffed = item item.loc = target diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index f159a9ca08c..246f6a1ba01 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -658,8 +658,8 @@ CM.handcuffed = null CM.update_inv_handcuffed() else - var/obj/item/weapon/handcuffs/HC = CM.handcuffed - var/breakouttime = 1200 //A default in case you are somehow handcuffed with something that isn't an obj/item/weapon/handcuffs type + var/obj/item/weapon/restraints/handcuffs/HC = CM.handcuffed + var/breakouttime = 1200 //A default in case you are somehow handcuffed with something that isn't an obj/item/weapon/restraints/handcuffs type var/displaytime = 2 //Minutes to display in the "this will take X minutes." if(istype(HC)) //If you are handcuffed with actual handcuffs... Well what do I know, maybe someone will want to handcuff you with toilet paper in the future... breakouttime = HC.breakouttime @@ -695,7 +695,7 @@ CM.legcuffed = null CM.update_inv_legcuffed() else - var/obj/item/weapon/legcuffs/HC = CM.legcuffed + var/obj/item/weapon/restraints/legcuffs/HC = CM.legcuffed var/breakouttime = 1200 //A default in case you are somehow legcuffed with something that isn't an obj/item/weapon/legcuffs type var/displaytime = 2 //Minutes to display in the "this will take X minutes." if(istype(HC)) //If you are legcuffed with actual legcuffs... Well what do I know, maybe someone will want to legcuff you with toilet paper in the future... diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 1714449cd21..117a2d127d5 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -1,3 +1,6 @@ +#define AI_CHECK_WIRELESS 1 +#define AI_CHECK_RADIO 2 + var/list/ai_list = list() //Not sure why this is necessary... @@ -77,8 +80,8 @@ var/list/ai_list = list() possibleNames -= pickedName pickedName = null - real_name = pickedName - name = real_name + aiPDA = new/obj/item/device/pda/ai(src) + SetName(pickedName) anchored = 1 canmove = 0 density = 1 @@ -96,11 +99,6 @@ var/list/ai_list = list() verbs += /mob/living/silicon/ai/proc/show_laws_verb - aiPDA = new/obj/item/device/pda/ai(src) - aiPDA.owner = name - aiPDA.ownjob = "AI" - aiPDA.name = name + " (" + aiPDA.ownjob + ")" - aiMulti = new(src) aiRadio = new(src) aiRadio.myAi = src @@ -112,7 +110,7 @@ var/list/ai_list = list() if (istype(loc, /turf)) verbs.Add(/mob/living/silicon/ai/proc/ai_network_change, \ /mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \ - /mob/living/silicon/ai/proc/toggle_camera_light, /mob/living/silicon/ai/proc/botcall, /mob/living/silicon/ai/proc/control_integrated_radio, /mob/living/silicon/ai/proc/control_hud, /mob/living/silicon/ai/proc/change_arrival_message, /mob/living/silicon/ai/proc/ai_store_location, /mob/living/silicon/ai/proc/ai_goto_location, /mob/living/silicon/ai/proc/ai_remove_location) + /mob/living/silicon/ai/proc/toggle_camera_light, /mob/living/silicon/ai/proc/botcall, /mob/living/silicon/ai/proc/control_integrated_radio, /mob/living/silicon/ai/proc/control_hud, /mob/living/silicon/ai/proc/change_arrival_message, /mob/living/silicon/ai/proc/ai_store_location, /mob/living/silicon/ai/proc/ai_goto_location, /mob/living/silicon/ai/proc/ai_remove_location, /mob/living/silicon/ai/proc/nano_crew_monitor, /mob/living/silicon/ai/proc/ai_cancel_call) if(!safety)//Only used by AIize() to successfully spawn an AI. if (!B)//If there is no player/brain inside. @@ -127,7 +125,7 @@ var/list/ai_list = list() verbs.Remove(,/mob/living/silicon/ai/proc/ai_call_shuttle,/mob/living/silicon/ai/proc/ai_camera_track, \ /mob/living/silicon/ai/proc/ai_camera_list, /mob/living/silicon/ai/proc/ai_network_change, \ /mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \ - /mob/living/silicon/ai/proc/toggle_camera_light,/mob/living/silicon/ai/verb/pick_icon,/mob/living/silicon/ai/proc/control_hud, /mob/living/silicon/ai/proc/change_arrival_message) + /mob/living/silicon/ai/proc/toggle_camera_light,/mob/living/silicon/ai/verb/pick_icon,/mob/living/silicon/ai/proc/control_hud, /mob/living/silicon/ai/proc/change_arrival_message, /mob/living/silicon/ai/proc/ai_cancel_call) laws = new /datum/ai_laws/alienmov else B.brainmob.mind.transfer_to(src) @@ -155,11 +153,25 @@ var/list/ai_list = list() hud_list[IMPCHEM_HUD] = image('icons/mob/hud.dmi', src, "hudblank") hud_list[IMPTRACK_HUD] = image('icons/mob/hud.dmi', src, "hudblank") hud_list[SPECIALROLE_HUD] = image('icons/mob/hud.dmi', src, "hudblank") - hud_list[NATIONS_HUD] = image('icons/mob/hud.dmi', src, "hudblank") + hud_list[NATIONS_HUD] = image('icons/mob/hud.dmi', src, "hudblank") + init_subsystems() + ai_list += src ..() return + +/mob/living/silicon/ai/proc/SetName(pickedName as text) + real_name = pickedName + name = pickedName + if(eyeobj) + eyeobj.name = "[pickedName] (AI Eye)" + + // Set ai pda name + if(aiPDA) + aiPDA.ownjob = "AI" + aiPDA.owner = pickedName + aiPDA.name = pickedName + " (" + aiPDA.ownjob + ")" /mob/living/silicon/ai/Destroy() ai_list -= src @@ -301,14 +313,15 @@ var/list/ai_list = list() if(src.stat == 2) src << "You can't call the shuttle because you are dead!" return - if(istype(usr,/mob/living/silicon/ai)) - var/mob/living/silicon/ai/AI = src - if(AI.control_disabled) - usr << "Wireless control is disabled!" - return + + if(check_unable(AI_CHECK_WIRELESS)) + return var/confirm = alert("Are you sure you want to call the shuttle?", "Confirm Shuttle Call", "Yes", "No") + if(check_unable(AI_CHECK_WIRELESS)) + return + if(confirm == "Yes") call_shuttle_proc(src) @@ -317,38 +330,57 @@ var/list/ai_list = list() var/obj/machinery/computer/communications/C = locate() in machines if(C) C.post_status("shuttle") - return + +/mob/living/silicon/ai/proc/ai_cancel_call() + set name = "Recall Emergency Shuttle" + set category = "AI Commands" + + if(src.stat == 2) + src << "You can't send the shuttle back because you are dead!" + return + + if(check_unable(AI_CHECK_WIRELESS)) + return + + var/confirm = alert("Are you sure you want to recall the shuttle?", "Confirm Shuttle Recall", "Yes", "No") + + if(check_unable(AI_CHECK_WIRELESS)) + return + + if(confirm == "Yes") + cancel_call_proc(src) /mob/living/silicon/ai/cancel_camera() src.view_core() /mob/living/silicon/ai/verb/toggle_anchor() - set category = "AI Commands" - set name = "Toggle Floor Bolts" - if(!isturf(loc)) // if their location isn't a turf - return // stop - anchored = !anchored // Toggles the anchor + set category = "AI Commands" + set name = "Toggle Floor Bolts" + + if(!isturf(loc)) // if their location isn't a turf + return // stop + + anchored = !anchored // Toggles the anchor - src << "[anchored ? "You are now anchored." : "You are now unanchored."]" - // the message in the [] will change depending whether or not the AI is anchored + src << "[anchored ? "You are now anchored." : "You are now unanchored."]" /mob/living/silicon/ai/update_canmove() return 0 - - -/mob/living/silicon/ai/proc/ai_cancel_call() - set category = "Malfunction" + +/mob/living/silicon/ai/proc/announcement() + set name = "Announcement" + set desc = "Create a vocal announcement by typing in the available words to create a sentence." + set category = "AI Commands" + if(src.stat == 2) - src << "You can't send the shuttle back because you are dead!" + src << "You can't call make an announcement because you are dead!" return - if(istype(usr,/mob/living/silicon/ai)) - var/mob/living/silicon/ai/AI = src - if(AI.control_disabled) - src << "Wireless control is disabled!" - return - cancel_call_proc(src) - return + + if(check_unable(AI_CHECK_WIRELESS | AI_CHECK_RADIO)) + return + + ai_announcement() /mob/living/silicon/ai/check_eye(var/mob/user as mob) if (!current) @@ -581,9 +613,9 @@ var/list/ai_list = list() src << "Critical error. System offline." return - if(control_disabled) - src << "Wireless communication is disabled." + if(check_unable(AI_CHECK_WIRELESS | AI_CHECK_RADIO)) return + var/ai_allowed_Zlevel = list(1,3,5) var/d var/area/bot_area @@ -704,6 +736,9 @@ var/list/ai_list = list() set name = "Jump To Network" unset_machine() var/cameralist[0] + + if(check_unable()) + return if(usr.stat == 2) usr << "You can't change your camera network because you are dead!" @@ -721,6 +756,9 @@ var/list/ai_list = list() cameralist[i] = i var/old_network = network network = input(U, "Which network would you like to view?") as null|anything in cameralist + + if(check_unable()) + return if(!U.eyeobj) U.view_core() @@ -752,8 +790,16 @@ var/list/ai_list = list() if(usr.stat == 2) usr <<"You cannot change your emotional status because you are dead!" return + + if(check_unable()) + return + var/list/ai_emotions = list("Very Happy", "Happy", "Neutral", "Unsure", "Confused", "Sad", "BSOD", "Blank", "Problems?", "Awesome", "Facepalm", "Friend Computer") var/emote = input("Please, select a status!", "AI Status", null, null) in ai_emotions + + if(check_unable()) + return + for (var/obj/machinery/M in machines) //change status if(istype(M, /obj/machinery/ai_status_display)) var/obj/machinery/ai_status_display/AISD = M @@ -773,6 +819,9 @@ var/list/ai_list = list() set name = "Change Hologram" set desc = "Change the default hologram available to AI to something else." set category = "AI Commands" + + if(check_unable()) + return var/input if(alert("Would you like to select a hologram based on a crew member or switch to unique avatar?",,"Crew Member","Unique")=="Crew Member") @@ -827,6 +876,9 @@ var/list/ai_list = list() if(stat != CONSCIOUS) return + + if(check_unable()) + return camera_light_on = !camera_light_on src << "Camera lights [camera_light_on ? "activated" : "deactivated"]." @@ -904,8 +956,11 @@ var/list/ai_list = list() set name = "Radio Settings" set desc = "Allows you to change settings of your radio." set category = "AI Commands" - - src << "Accessing Subspace Transceiver control..." + + if(check_unable(AI_CHECK_RADIO)) + return + + src << "Accessing Subspace Transceiver control..." if (src.aiRadio) src.aiRadio.interact(src) @@ -956,4 +1011,25 @@ var/list/ai_list = list() src << "\red You deny the request." else src << "\red You've failed to open an airlock for [target]" - return \ No newline at end of file + return + + +/mob/living/silicon/ai/proc/check_unable(var/flags = 0) + if(stat == DEAD) + usr << "\red You are dead!" + return 1 + + if((flags & AI_CHECK_WIRELESS) && src.control_disabled) + usr << "\red Wireless control is disabled!" + return 1 + if((flags & AI_CHECK_RADIO) && src.aiRadio.disabledAi) + src << "\red System Error - Transceiver Disabled!" + return 1 + return 0 + +/mob/living/silicon/ai/proc/is_in_chassis() + return istype(loc, /turf) + +#undef AI_CHECK_WIRELESS +#undef AI_CHECK_RADIO + diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm index c9541858467..dfa05ddc5d0 100644 --- a/code/modules/mob/living/silicon/ai/death.dm +++ b/code/modules/mob/living/silicon/ai/death.dm @@ -15,21 +15,21 @@ var/callshuttle = 0 for(var/obj/machinery/computer/communications/commconsole in world) - if(commconsole.z == 2) + if((commconsole.z in config.admin_levels)) continue if(istype(commconsole.loc,/turf)) break callshuttle++ for(var/obj/item/weapon/circuitboard/communications/commboard in world) - if(commboard.z == 2) + if((commboard.z in config.admin_levels)) continue if(istype(commboard.loc,/turf) || istype(commboard.loc,/obj/item/weapon/storage)) break callshuttle++ for(var/mob/living/silicon/ai/shuttlecaller in player_list) - if(shuttlecaller.z == 2) + if((shuttlecaller.z in config.admin_levels)) continue if(!shuttlecaller.stat && shuttlecaller.client && istype(shuttlecaller.loc,/turf)) break diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index 8218bec993e..ec02433c46a 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -134,7 +134,7 @@ src << "ERROR: Eyeobj not found. Creating new eye..." src.eyeobj = new(src.loc) src.eyeobj.ai = src - src.eyeobj.name = "[src.name] (AI Eye)" // Give it a name + src.SetName(src.name) if(client && client.eye) client.eye = src diff --git a/code/modules/mob/living/silicon/ai/nano.dm b/code/modules/mob/living/silicon/ai/nano.dm new file mode 100644 index 00000000000..f9bb7a25d79 --- /dev/null +++ b/code/modules/mob/living/silicon/ai/nano.dm @@ -0,0 +1,10 @@ +var/obj/nano_module/crew_monitor/crew_monitor + +/mob/living/silicon/ai/proc/init_subsystems() + crew_monitor = new(src) + +/mob/living/silicon/ai/proc/nano_crew_monitor() + set category = "AI Commands" + set name = "Crew Monitor" + + crew_monitor.ui_interact(usr) \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm index e535a2dedee..b596fd53541 100644 --- a/code/modules/mob/living/silicon/ai/say.dm +++ b/code/modules/mob/living/silicon/ai/say.dm @@ -1,32 +1,32 @@ /mob/living/silicon/ai/say(var/message) - if(parent && istype(parent) && parent.stat != 2) - parent.say(message) - return - //If there is a defined "parent" AI, it is actually an AI, and it is alive, anything the AI tries to say is said by the parent instead. - ..(message) + if(parent && istype(parent) && parent.stat != 2) + parent.say(message) //If there is a defined "parent" AI, it is actually an AI, and it is alive, anything the AI tries to say is said by the parent instead. + return + + ..(message) /mob/living/silicon/ai/say_understands(var/other) - if (istype(other, /mob/living/carbon/human)) - return 1 - if (istype(other, /mob/living/silicon/robot)) - return 1 - if (istype(other, /mob/living/silicon/decoy)) - return 1 - if (istype(other, /mob/living/carbon/brain)) - return 1 - if (istype(other, /mob/living/silicon/pai)) - return 1 - return ..() + if (istype(other, /mob/living/carbon/human)) + return 1 + if (istype(other, /mob/living/silicon/robot)) + return 1 + if (istype(other, /mob/living/silicon/decoy)) + return 1 + if (istype(other, /mob/living/carbon/brain)) + return 1 + if (istype(other, /mob/living/silicon/pai)) + return 1 + return ..() /mob/living/silicon/ai/say_quote(var/text) - var/ending = copytext(text, length(text)) + var/ending = copytext(text, length(text)) - if (ending == "?") - return "queries, \"[text]\""; - else if (ending == "!") - return "declares, \"[text]\""; + if (ending == "?") + return "queries, \"[text]\""; + else if (ending == "!") + return "declares, \"[text]\""; - return "states, \"[text]\""; + return "states, \"[text]\""; /mob/living/silicon/ai/proc/IsVocal() @@ -36,44 +36,28 @@ var/const/VOX_DELAY = 100 var/const/VOX_PATH = "sound/vox_fem/" /mob/living/silicon/ai/verb/announcement_help() - - set name = "Announcement Help" - set desc = "Display a list of vocal words to announce to the crew." - set category = "AI Commands" - - - var/dat = "Here is a list of words you can type into the 'Announcement' button to create sentences to vocally announce to everyone on the same level at you.
\ -
  • You can also click on the word to preview it.
  • \ -
  • You can only say 30 words for every announcement.
  • \ -
  • Do not use punctuation as you would normally, if you want a pause you can use the full stop and comma characters by separating them with spaces, like so: 'Alpha . Test , Bravo'.
\ - WARNING:
Misuse of the announcement system will get you job banned.
" - - var/index = 0 - for(var/word in vox_sounds) - index++ - dat += "[capitalize(word)]" - if(index != vox_sounds.len) - dat += " / " - - var/datum/browser/popup = new(src, "announce_help", "Announcement Help", 500, 400) - popup.set_content(dat) - popup.open() - - -/mob/living/silicon/ai/proc/announcement() - - set name = "Announcement" - set desc = "Create a vocal announcement by typing in the available words to create a sentence." + set name = "Announcement Help" + set desc = "Display a list of vocal words to announce to the crew." set category = "AI Commands" - if(src.stat == 2) - src << "You can't call the shuttle because you are dead!" - return - if(istype(usr,/mob/living/silicon/ai)) - var/mob/living/silicon/ai/AI = src - if(AI.control_disabled) - usr << "Wireless control is disabled!" - return + var/dat = "Here is a list of words you can type into the 'Announcement' button to create sentences to vocally announce to everyone on the same level at you.
\ +
  • You can also click on the word to preview it.
  • \ +
  • You can only say 30 words for every announcement.
  • \ +
  • Do not use punctuation as you would normally, if you want a pause you can use the full stop and comma characters by separating them with spaces, like so: 'Alpha . Test , Bravo'.
\ + WARNING:
Misuse of the announcement system will get you job banned.
" + + var/index = 0 + for(var/word in vox_sounds) + index++ + dat += "[capitalize(word)]" + if(index != vox_sounds.len) + dat += " / " + + var/datum/browser/popup = new(src, "announce_help", "Announcement Help", 500, 400) + popup.set_content(dat) + popup.open() + +/mob/living/silicon/ai/proc/ai_announcement() if(announcing_vox > world.time) src << "Please wait [round((announcing_vox - world.time) / 10)] seconds." return @@ -112,27 +96,24 @@ var/const/VOX_PATH = "sound/vox_fem/" /proc/play_vox_word(var/word, var/z_level, var/mob/only_listener) + word = lowertext(word) + if(vox_sounds[word]) + var/sound_file = vox_sounds[word] + var/sound/voice = sound(sound_file, wait = 1, channel = VOX_CHANNEL) + voice.status = SOUND_STREAM - word = lowertext(word) - - if(vox_sounds[word]) - - var/sound_file = vox_sounds[word] - var/sound/voice = sound(sound_file, wait = 1, channel = VOX_CHANNEL) - voice.status = SOUND_STREAM - - // If there is no single listener, broadcast to everyone in the same z level - if(!only_listener) - // Play voice for all mobs in the z level - for(var/mob/M in player_list) - if(M.client) - var/turf/T = get_turf(M) - if(T.z == z_level) - M << voice - else - only_listener << voice - return 1 - return 0 + // If there is no single listener, broadcast to everyone in the same z level + if(!only_listener) + // Play voice for all mobs in the z level + for(var/mob/M in player_list) + if(M.client) + var/turf/T = get_turf(M) + if(T.z == z_level && !isdeaf(M)) + M << voice + else + only_listener << voice + return 1 + return 0 // VOX sounds moved to /code/defines/vox_sounds.dm diff --git a/code/modules/mob/living/silicon/mommi/mommi.dm b/code/modules/mob/living/silicon/mommi/mommi.dm index 91defdaedfb..b6e508d9d3a 100644 --- a/code/modules/mob/living/silicon/mommi/mommi.dm +++ b/code/modules/mob/living/silicon/mommi/mommi.dm @@ -149,7 +149,7 @@ They can only use one tool at a time, they can't choose modules, and they have 1 name = real_name /mob/living/silicon/robot/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do + if (istype(W, /obj/item/weapon/restraints/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do return if (istype(W, /obj/item/weapon/weldingtool)) @@ -240,68 +240,6 @@ They can only use one tool at a time, they can't choose modules, and they have 1 else user << "\red Access denied." - else if(istype(W, /obj/item/weapon/card/emag)) // trying to unlock with an emag card - if(!opened)//Cover is closed - if(locked) - if(prob(90)) - user << "You emag the cover lock." - locked = 0 - else - user << "You fail to emag the cover lock." - if(prob(25)) - src << "Hack attempt detected." - else - user << "The cover is already unlocked." - return - - if(opened)//Cover is open - if(emagged) return//Prevents the X has hit Y with Z message also you cant emag them twice - if(wiresexposed) - user << "You must close the panel first" - return - else - sleep(6) - if(prob(50)) - emagged = 1 - lawupdate = 0 - connected_ai = null - user << "You emag [src]'s interface." -// message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.") - log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.") - clear_supplied_laws() - clear_inherent_laws() - laws = new /datum/ai_laws/syndicate_override - var/time = time2text(world.realtime,"hh:mm:ss") - lawchanges.Add("[time] : [user.name]([user.key]) emagged [name]([key])") - set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.") - src << "\red ALERT: Foreign software detected." - sleep(5) - src << "\red Initiating diagnostics..." - sleep(20) - src << "\red SynBorg v1.7 loaded." - sleep(5) - src << "\red LAW SYNCHRONISATION ERROR" - sleep(5) - src << "\red Would you like to send a report to NanoTraSoft? Y/N" - sleep(10) - src << "\red > N" - sleep(20) - src << "\red ERRORERRORERROR" - src << "Obey these laws:" - laws.show_laws(src) - src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands." - if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner)) - for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules) - del(D) - src.module.modules += new /obj/item/weapon/pickaxe/diamonddrill(src.module) - src.module.rebuild() - updateicon() - else - user << "You fail to [ locked ? "unlock" : "lock"] [src]'s interface." - if(prob(25)) - src << "Hack attempt detected." - return - else if(istype(W, /obj/item/borg/upgrade/)) var/obj/item/borg/upgrade/U = W if(!opened) @@ -322,6 +260,68 @@ They can only use one tool at a time, they can't choose modules, and they have 1 else spark_system.start() return ..() + +/mob/living/silicon/robot/mommi/emag_act(user as mob) + if(!opened)//Cover is closed + if(locked) + if(prob(90)) + user << "You emag the cover lock." + locked = 0 + else + user << "You fail to emag the cover lock." + if(prob(25)) + src << "Hack attempt detected." + else + user << "The cover is already unlocked." + return + + if(opened)//Cover is open + if(emagged) return//Prevents the X has hit Y with Z message also you cant emag them twice + if(wiresexposed) + user << "You must close the panel first" + return + else + sleep(6) + if(prob(50)) + emagged = 1 + lawupdate = 0 + connected_ai = null + user << "You emag [src]'s interface." +// message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.") + log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.") + clear_supplied_laws() + clear_inherent_laws() + laws = new /datum/ai_laws/syndicate_override + var/time = time2text(world.realtime,"hh:mm:ss") + lawchanges.Add("[time] : [user.name]([user.key]) emagged [name]([key])") + set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.") + src << "\red ALERT: Foreign software detected." + sleep(5) + src << "\red Initiating diagnostics..." + sleep(20) + src << "\red SynBorg v1.7 loaded." + sleep(5) + src << "\red LAW SYNCHRONISATION ERROR" + sleep(5) + src << "\red Would you like to send a report to NanoTraSoft? Y/N" + sleep(10) + src << "\red > N" + sleep(20) + src << "\red ERRORERRORERROR" + src << "Obey these laws:" + laws.show_laws(src) + src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands." + if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner)) + for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules) + del(D) + src.module.modules += new /obj/item/weapon/pickaxe/diamonddrill(src.module) + src.module.rebuild() + updateicon() + else + user << "You fail to [ locked ? "unlock" : "lock"] [src]'s interface." + if(prob(25)) + src << "Hack attempt detected." + return /mob/living/silicon/robot/mommi/attack_hand(mob/user) add_fingerprint(user) diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 0073729778d..e3a04f2cd0f 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -172,41 +172,6 @@ user << "The machine is hermetically sealed. You can't open the case." return - else if (istype(W, /obj/item/weapon/card/emag)) - - if(!client || stat == 2) - user << "\red There's not much point subverting this heap of junk." - return - - if(emagged) - src << "\red [user] attempts to load subversive software into you, but your hacked subroutined ignore the attempt." - user << "\red You attempt to subvert [src], but the sequencer has no effect." - return - - user << "\red You swipe the sequencer across [src]'s interface and watch its eyes flicker." - src << "\red You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script." - - var/obj/item/weapon/card/emag/emag = W - emag.uses-- - - message_admins("[key_name_admin(user)] emagged drone [key_name_admin(src)]. Laws overridden.") - log_game("[key_name(user)] emagged drone [key_name(src)]. Laws overridden.") - var/time = time2text(world.realtime,"hh:mm:ss") - lawchanges.Add("[time] : [user.name]([user.key]) emagged [name]([key])") - - emagged = 1 - lawupdate = 0 - connected_ai = null - clear_supplied_laws() - clear_inherent_laws() - laws = new /datum/ai_laws/syndicate_override - set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.") - - src << "Obey these laws:" - laws.show_laws(src) - src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands." - return - else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) if(stat == 2) @@ -242,6 +207,41 @@ return ..() + +/mob/living/silicon/robot/drone/emag_act(user as mob) + if(!client || stat == 2) + user << "\red There's not much point subverting this heap of junk." + return + + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + + if(emagged) + src << "\red [user] attempts to load subversive software into you, but your hacked subroutined ignore the attempt." + user << "\red You attempt to subvert [src], but the sequencer has no effect." + return + + user << "\red You swipe the sequencer across [src]'s interface and watch its eyes flicker." + src << "\red You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script." + + message_admins("[key_name_admin(user)] emagged drone [key_name_admin(src)]. Laws overridden.") + log_game("[key_name(user)] emagged drone [key_name(src)]. Laws overridden.") + var/time = time2text(world.realtime,"hh:mm:ss") + lawchanges.Add("[time] : [H.name]([H.key]) emagged [name]([key])") + + emagged = 1 + lawupdate = 0 + connected_ai = null + clear_supplied_laws() + clear_inherent_laws() + laws = new /datum/ai_laws/syndicate_override + set_zeroth_law("Only [H.real_name] and people he designates as being such are Syndicate Agents.") + + src << "Obey these laws:" + laws.show_laws(src) + src << "\red \b ALERT: [H.real_name] is your new master. Obey your new laws and his commands." + return //DRONE LIFE/DEATH diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 1e0a62eedb2..e28f9ac8b7d 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -188,12 +188,12 @@ /mob/living/silicon/robot/proc/pick_module() if(module) return - var/list/modules = list("Standard", "Engineering", "Surgeon", "Crisis", "Miner", "Janitor", "Service", "Security") + var/list/modules = list("Standard", "Engineering", "Medical", "Miner", "Janitor", "Service", "Security") if(security_level == (SEC_LEVEL_GAMMA || SEC_LEVEL_EPSILON) || crisis) src << "\red Crisis mode active. Combat module available." modules+="Combat" if(mmi != null && mmi.alien) - modules="Hunter" + modules = "Hunter" modtype = input("Please, select a module!", "Robot", null, null) in modules designation = modtype var/module_sprites[0] //Used to store the associations between sprite names and sprite index. @@ -237,8 +237,8 @@ module_sprites["Advanced Droid"] = "droid-miner" module_sprites["Treadhead"] = "Miner" - if("Crisis") - module = new /obj/item/weapon/robot_module/crisis(src) + if("Medical") + module = new /obj/item/weapon/robot_module/medical(src) channels = list("Medical" = 1) if(camera && "Robots" in camera.network) camera.network.Add("Medical") @@ -247,17 +247,6 @@ module_sprites["Advanced Droid"] = "droid-medical" module_sprites["Needles"] = "medicalrobot" - if("Surgeon") - module = new /obj/item/weapon/robot_module/surgeon(src) - channels = list("Medical" = 1) - if(camera && "Robots" in camera.network) - camera.network.Add("Medical") - - module_sprites["Basic"] = "Medbot" - module_sprites["Standard"] = "surgeon" - module_sprites["Advanced Droid"] = "droid-medical" - module_sprites["Needles"] = "medicalrobot" - if("Security") module = new /obj/item/weapon/robot_module/security(src) channels = list("Security" = 1) @@ -643,7 +632,7 @@ /mob/living/silicon/robot/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do + if (istype(W, /obj/item/weapon/restraints/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do return if(opened) // Are they trying to insert something? @@ -808,72 +797,6 @@ else user << "\red Access denied." - else if(istype(W, /obj/item/weapon/card/emag)) // trying to unlock with an emag card - if(!opened)//Cover is closed - if(locked) - if(prob(90)) - var/obj/item/weapon/card/emag/emag = W - emag.uses-- - user << "You emag the cover lock." - locked = 0 - else - user << "You fail to emag the cover lock." - if(prob(25)) - src << "Hack attempt detected." - else - user << "The cover is already unlocked." - return - - if(opened)//Cover is open - if(emagged) return//Prevents the X has hit Y with Z message also you cant emag them twice - if(wiresexposed) - user << "You must close the panel first" - return - else - sleep(6) - if(prob(50)) - emagged = 1 - if(user.hud_used) - user.hud_used.update_robot_modules_display() //Shows/hides the emag item if the inventory screen is already open. - lawupdate = 0 - connected_ai = null - user << "You emag [src]'s interface." -// message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.") - log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.") - clear_supplied_laws() - clear_inherent_laws() - laws = new /datum/ai_laws/syndicate_override - var/time = time2text(world.realtime,"hh:mm:ss") - lawchanges.Add("[time] : [user.name]([user.key]) emagged [name]([key])") - set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.") - src << "\red ALERT: Foreign software detected." - sleep(5) - src << "\red Initiating diagnostics..." - sleep(20) - src << "\red SynBorg v1.7 loaded." - sleep(5) - src << "\red LAW SYNCHRONISATION ERROR" - sleep(5) - src << "\red Would you like to send a report to NanoTraSoft? Y/N" - sleep(10) - src << "\red > N" - sleep(20) - src << "\red ERRORERRORERROR" - src << "Obey these laws:" - laws.show_laws(src) - src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands." - if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner)) - for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules) - del(D) - src.module.modules += new /obj/item/weapon/pickaxe/diamonddrill(src.module) - src.module.rebuild() - updateicon() - else - user << "You fail to [ locked ? "unlock" : "lock"] [src]'s interface." - if(prob(25)) - src << "Hack attempt detected." - return - else if(istype(W, /obj/item/borg/upgrade/)) var/obj/item/borg/upgrade/U = W if(!opened) @@ -894,6 +817,73 @@ else spark_system.start() return ..() + +/mob/living/silicon/robot/emag_act(user as mob) + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + if(!opened)//Cover is closed + if(locked) + if(prob(90)) + user << "You emag the cover lock." + locked = 0 + else + user << "You fail to emag the cover lock." + if(prob(25)) + src << "Hack attempt detected." + else + user << "The cover is already unlocked." + return + + if(opened)//Cover is open + if(emagged) return//Prevents the X has hit Y with Z message also you cant emag them twice + if(wiresexposed) + user << "You must close the panel first" + return + else + sleep(6) + if(prob(50)) + emagged = 1 + if(H.hud_used) + H.hud_used.update_robot_modules_display() //Shows/hides the emag item if the inventory screen is already open. + lawupdate = 0 + connected_ai = null + user << "You emag [src]'s interface." +// message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.") + log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.") + clear_supplied_laws() + clear_inherent_laws() + laws = new /datum/ai_laws/syndicate_override + var/time = time2text(world.realtime,"hh:mm:ss") + lawchanges.Add("[time] : [H.name]([H.key]) emagged [name]([key])") + set_zeroth_law("Only [H.real_name] and people he designates as being such are Syndicate Agents.") + src << "\red ALERT: Foreign software detected." + sleep(5) + src << "\red Initiating diagnostics..." + sleep(20) + src << "\red SynBorg v1.7 loaded." + sleep(5) + src << "\red LAW SYNCHRONISATION ERROR" + sleep(5) + src << "\red Would you like to send a report to NanoTraSoft? Y/N" + sleep(10) + src << "\red > N" + sleep(20) + src << "\red ERRORERRORERROR" + src << "Obey these laws:" + laws.show_laws(src) + src << "\red \b ALERT: [H.real_name] is your new master. Obey your new laws and his commands." + if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner)) + for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules) + del(D) + src.module.modules += new /obj/item/weapon/pickaxe/diamonddrill(src.module) + src.module.rebuild() + updateicon() + else + user << "You fail to [ locked ? "unlock" : "lock"] [src]'s interface." + if(prob(25)) + src << "Hack attempt detected." + return /mob/living/silicon/robot/verb/unlock_own_cover() set category = "Robot Commands" diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 831c6badf1e..a2c1fcb7347 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -71,10 +71,12 @@ src.emag = new /obj/item/weapon/melee/energy/sword/cyborg(src) return -/obj/item/weapon/robot_module/surgeon - name = "surgeon robot module" +/obj/item/weapon/robot_module/medical + name = "medical robot module" stacktypes = list( /obj/item/stack/medical/advanced/bruise_pack = 5, + /obj/item/stack/medical/advanced/ointment = 5, + /obj/item/stack/medical/splint = 5, /obj/item/stack/nanopaste = 5 ) @@ -82,7 +84,18 @@ src.modules += new /obj/item/device/flashlight(src) src.modules += new /obj/item/device/flash/cyborg(src) src.modules += new /obj/item/device/healthanalyzer(src) - src.modules += new /obj/item/weapon/reagent_containers/borghypo/surgeon(src) + src.modules += new /obj/item/device/reagent_scanner/adv(src) + src.modules += new /obj/item/weapon/borg_defib(src) + src.modules += new /obj/item/roller_holder(src) + src.modules += new /obj/item/weapon/reagent_containers/borghypo(src) + src.modules += new /obj/item/weapon/reagent_containers/glass/beaker/large(src) + src.modules += new /obj/item/weapon/reagent_containers/dropper(src) + src.modules += new /obj/item/weapon/reagent_containers/syringe(src) + src.modules += new /obj/item/weapon/extinguisher/mini(src) + src.modules += new /obj/item/stack/medical/advanced/bruise_pack(src) + src.modules += new /obj/item/stack/medical/advanced/ointment(src) + src.modules += new /obj/item/stack/medical/splint(src) + src.modules += new /obj/item/stack/nanopaste(src) src.modules += new /obj/item/weapon/scalpel(src) src.modules += new /obj/item/weapon/hemostat(src) src.modules += new /obj/item/weapon/retractor(src) @@ -92,9 +105,6 @@ src.modules += new /obj/item/weapon/bonesetter(src) src.modules += new /obj/item/weapon/circular_saw(src) src.modules += new /obj/item/weapon/surgicaldrill(src) - src.modules += new /obj/item/weapon/extinguisher/mini(src) - src.modules += new /obj/item/stack/medical/advanced/bruise_pack(src) - src.modules += new /obj/item/stack/nanopaste(src) src.emag = new /obj/item/weapon/reagent_containers/spray(src) @@ -102,59 +112,12 @@ src.emag.name = "Polyacid spray" return -/obj/item/weapon/robot_module/surgeon/respawn_consumable(var/mob/living/silicon/robot/R) +/obj/item/weapon/robot_module/medical/respawn_consumable(var/mob/living/silicon/robot/R) if(src.emag) var/obj/item/weapon/reagent_containers/spray/PS = src.emag PS.reagents.add_reagent("pacid", 2) ..() -/obj/item/weapon/robot_module/crisis - name = "crisis robot module" - stacktypes = list( - /obj/item/stack/medical/advanced/ointment = 5, - /obj/item/stack/medical/advanced/bruise_pack = 5, - /obj/item/stack/medical/splint = 5 - ) - - - New() - src.modules += new /obj/item/device/flashlight(src) - src.modules += new /obj/item/device/flash/cyborg(src) - src.modules += new /obj/item/device/healthanalyzer(src) - src.modules += new /obj/item/device/reagent_scanner/adv(src) - src.modules += new /obj/item/roller_holder(src) - src.modules += new /obj/item/stack/medical/advanced/ointment(src) - src.modules += new /obj/item/stack/medical/advanced/bruise_pack(src) - src.modules += new /obj/item/stack/medical/splint(src) - src.modules += new /obj/item/weapon/reagent_containers/borghypo/crisis(src) - src.modules += new /obj/item/weapon/reagent_containers/glass/beaker/large(src) - src.modules += new /obj/item/weapon/reagent_containers/robodropper(src) - src.modules += new /obj/item/weapon/reagent_containers/syringe(src) - src.modules += new /obj/item/weapon/extinguisher/mini(src) - - src.emag = new /obj/item/weapon/reagent_containers/spray(src) - - src.emag.reagents.add_reagent("pacid", 250) - src.emag.name = "Polyacid spray" - var/obj/item/weapon/reagent_containers/spray/S = emag - S.banned_reagents = list() - return - -/obj/item/weapon/robot_module/crisis/respawn_consumable(var/mob/living/silicon/robot/R) - - var/obj/item/weapon/reagent_containers/syringe/S = locate() in src.modules - if(S.mode == 2) - S.reagents.clear_reagents() - S.mode = initial(S.mode) - S.desc = initial(S.desc) - S.update_icon() - - if(src.emag) - var/obj/item/weapon/reagent_containers/spray/PS = src.emag - PS.reagents.add_reagent("pacid", 2) - - ..() - /obj/item/weapon/robot_module/engineering name = "engineering robot module" @@ -220,7 +183,7 @@ New() src.modules += new /obj/item/device/flashlight/seclite(src) src.modules += new /obj/item/device/flash/cyborg(src) - src.modules += new /obj/item/weapon/handcuffs/cyborg(src) + src.modules += new /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg(src) src.modules += new /obj/item/weapon/melee/baton/robot(src) src.modules += new /obj/item/weapon/gun/energy/disabler/cyborg(src) src.modules += new /obj/item/taperoll/police(src) diff --git a/code/modules/mob/living/simple_animal/friendly/butterfly.dm b/code/modules/mob/living/simple_animal/friendly/butterfly.dm new file mode 100644 index 00000000000..4c4841a77e9 --- /dev/null +++ b/code/modules/mob/living/simple_animal/friendly/butterfly.dm @@ -0,0 +1,21 @@ +/mob/living/simple_animal/butterfly + name = "butterfly" + desc = "A colorful butterfly, how'd it get up here?" + icon_state = "butterfly" + icon_living = "butterfly" + icon_dead = "butterfly_dead" + turns_per_move = 1 + emote_see = list("flutters") + response_help = "shoos" + response_disarm = "brushes aside" + response_harm = "aquashes" + speak_chance = 0 + maxHealth = 2 + health = 2 + harm_intent_damage = 1 + friendly = "nudges" + pass_flags = PASSTABLE + +/mob/living/simple_animal/butterfly/New() + ..() + color = rgb(rand(0, 255), rand(0, 255), rand(0, 255)) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm index 9b638505e28..c9dfb0cccef 100644 --- a/code/modules/mob/living/simple_animal/friendly/corgi.dm +++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm @@ -25,7 +25,15 @@ var/obj/item/inventory_back var/facehugger -/mob/living/simple_animal/corgi/Life() +/mob/living/simple_animal/corgi/New() + ..() + regenerate_icons() + +/mob/living/simple_animal/corgi/Die() + ..() + regenerate_icons() + +/mob/living/simple_animal/corgi/revive() ..() regenerate_icons() @@ -33,7 +41,7 @@ user.set_machine(src) if(user.stat) return - var/dat = "
Inventory of [name]

" + var/dat = "

Inventory of [real_name]

" if(inventory_head) dat += "
Head: [inventory_head] (Remove)" else @@ -85,6 +93,7 @@ SetLuminosity(0) inventory_head.loc = src.loc inventory_head = null + regenerate_icons() else usr << "\red There is nothing to remove from its [remove_from]." return @@ -92,6 +101,7 @@ if(inventory_back) inventory_back.loc = src.loc inventory_back = null + regenerate_icons() else usr << "\red There is nothing to remove from its [remove_from]." return @@ -163,6 +173,7 @@ usr.drop_item() place_on_head(item_to_add) + regenerate_icons() if("back") if(inventory_back) @@ -383,7 +394,7 @@ ..() /mob/living/simple_animal/corgi/regenerate_icons() - overlays = list() + overlays.Cut() if(inventory_head) var/head_icon_state = inventory_head.icon_state @@ -471,14 +482,12 @@ icon_living = "borgi" var/emagged = 0 -/mob/living/simple_animal/corgi/Ian/borgi/attackby(var/obj/item/O as obj, var/mob/user as mob) - if (istype(O, /obj/item/weapon/card/emag) && !emagged) +/mob/living/simple_animal/corgi/Ian/borgi/emag_act(user as mob) + if(!emagged) emagged = 1 visible_message("[user] swipes a card through [src].", "You overload [src]s internal reactor.") spawn (1000) src.explode() - return - ..() /mob/living/simple_animal/corgi/Ian/borgi/proc/explode() for(var/mob/M in viewers(src, null)) diff --git a/code/modules/mob/living/simple_animal/friendly/pug.dm b/code/modules/mob/living/simple_animal/friendly/pug.dm new file mode 100644 index 00000000000..62456ed8a8b --- /dev/null +++ b/code/modules/mob/living/simple_animal/friendly/pug.dm @@ -0,0 +1,42 @@ +//Corgi //best comment 2014 +/mob/living/simple_animal/pug + name = "\improper pug" + real_name = "pug" + desc = "It's a pug." + icon_state = "pug" + icon_living = "pug" + icon_dead = "pug_dead" + speak = list("YAP", "Woof!", "Bark!", "AUUUUUU") + speak_emote = list("barks", "woofs") + emote_hear = list("barks!", "woofs!", "yaps.","pants.") + emote_see = list("shakes its head.", "chases its tail.","shivers.") + speak_chance = 1 + turns_per_move = 10 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/pug + meat_amount = 3 + response_help = "pets" + response_disarm = "bops" + response_harm = "kicks" + see_in_dark = 5 + +/mob/living/simple_animal/pug/Life() + ..() + + if(!stat && !resting && !buckled) + if(prob(1)) + emote("me", 1, pick("chases its tail.")) + spawn(0) + for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2)) + dir = i + sleep(1) + +/mob/living/simple_animal/pug/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri + if(istype(O, /obj/item/weapon/newspaper)) + if(!stat) + user.visible_message("[user] baps [name] on the nose with the rolled up [O]") + spawn(0) + for(var/i in list(1,2,4,8,4,2,1,2)) + dir = i + sleep(1) + else + ..() diff --git a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm index aa64a6fe921..73c4018e3b9 100644 --- a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm +++ b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm @@ -125,18 +125,6 @@ else user << "\red You swipe your card, with no effect." return 0 - else if (istype(O, /obj/item/weapon/card/emag)) - if (emagged) - user << "\red [src] is already overloaded - better run." - return 0 - else - var/obj/item/weapon/card/emag/emag = O - emag.uses-- - emagged = 1 - user << "\blue You short out the security protocols and overload [src]'s cell, priming it to explode in a short time." - spawn(100) src << "\red Your cell seems to be outputting a lot of power..." - spawn(200) src << "\red Internal heat sensors are spiking! Something is badly wrong with your cell!" - spawn(300) src.explode() else if(O.force) @@ -152,6 +140,17 @@ for(var/mob/M in viewers(src, null)) if ((M.client && !( M.blinded ))) M.show_message("\red [user] gently taps [src] with the [O]. ") + +/mob/living/simple_animal/spiderbot/emag_act(user as mob) + if (emagged) + user << "\red [src] is already overloaded - better run." + return 0 + else + emagged = 1 + user << "\blue You short out the security protocols and overload [src]'s cell, priming it to explode in a short time." + spawn(100) src << "\red Your cell seems to be outputting a lot of power..." + spawn(200) src << "\red Internal heat sensors are spiking! Something is badly wrong with your cell!" + spawn(300) src.explode() /mob/living/simple_animal/spiderbot/proc/transfer_personality(var/obj/item/device/mmi/M as obj) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 890c953c632..800d9967ca7 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -29,6 +29,7 @@ var/response_disarm = "shoves" var/response_harm = "hits" var/harm_intent_damage = 3 + var/force_threshold = 0 //Minimum force required to deal any damage //Temperature effect var/minbodytemp = 250 @@ -372,7 +373,6 @@ /mob/living/simple_animal/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri if(istype(O, /obj/item/stack/medical)) - if(stat != DEAD) var/obj/item/stack/medical/MED = O if(health < maxHealth) @@ -399,20 +399,22 @@ if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch)) harvest() else + var/damage = 0 if(O.force) - var/damage = O.force - if (O.damtype == STAMINA) - damage = 0 - adjustBruteLoss(damage) - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b "+"[src] has been attacked with [O] by [user]. ") + if(O.force >= force_threshold) + damage = O.force + if (O.damtype == STAMINA) + damage = 0 + visible_message("[user] has [O.attack_verb.len ? "[pick(O.attack_verb)]": "attacked"] [src] with [O]!",\ + "[user] has [O.attack_verb.len ? "[pick(O.attack_verb)]": "attacked"] you with [O]!") + else + visible_message("[O] bounces harmlessly off of [src].",\ + "[O] bounces harmlessly off of [src].") + playsound(loc, O.hitsound, 50, 1, -1) else - usr << "\red This weapon is ineffective, it does no damage." - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red [user] gently taps [src] with [O]. ") - + user.visible_message("[user] gently taps [src] with [O].",\ + "This weapon is ineffective, it does no damage.") + adjustBruteLoss(damage) /mob/living/simple_animal/movement_delay() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 8e5b93a01f0..7b197aafcb2 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -399,13 +399,13 @@ var/list/slot_equipment_priority = list( \ if(slot_handcuffed) if(H.handcuffed) return 0 - if(!istype(src, /obj/item/weapon/handcuffs)) + if(!istype(src, /obj/item/weapon/restraints/handcuffs)) return 0 return 1 if(slot_legcuffed) if(H.legcuffed) return 0 - if(!istype(src, /obj/item/weapon/legcuffs)) + if(!istype(src, /obj/item/weapon/restraints/legcuffs)) return 0 return 1 if(slot_in_backpack) @@ -881,8 +881,9 @@ var/list/slot_equipment_priority = list( \ stat(null, "Bots-[master_controller.aibots_cost]\t#[aibots.len]") stat(null, "Obj-[master_controller.objects_cost]\t#[processing_objects.len]") stat(null, "PiNet-[master_controller.networks_cost]\t#[pipe_networks.len]") - stat(null, "Ponet-[master_controller.powernets_cost]\t#[powernets.len]") + stat(null, "PoNet-[master_controller.powernets_cost]\t#[powernets.len]") stat(null, "NanoUI-[master_controller.nano_cost]\t#[nanomanager.processing_uis.len]") + stat(null,"Events-[master_controller.events_cost]\t#[event_manager.active_events.len]") // stat(null, "GC-[master_controller.gc_cost]\t#[garbage.queue.len]") stat(null, "Tick-[master_controller.ticker_cost]") stat(null, "ALL-[master_controller.total_cost]") diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index ee3c953fb7e..d422fe644e6 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -158,6 +158,12 @@ proc/isnewplayer(A) proc/hasorgans(A) return ishuman(A) + +proc/isdeaf(A) + if(istype(A, /mob)) + var/mob/M = A + return (M.sdisabilities & DEAF) || M.ear_deaf + return 0 /proc/hsl2rgb(h, s, l) return diff --git a/code/modules/mob/mob_transformation_simple.dm b/code/modules/mob/mob_transformation_simple.dm index bea08693fbc..399eeb1c83e 100644 --- a/code/modules/mob/mob_transformation_simple.dm +++ b/code/modules/mob/mob_transformation_simple.dm @@ -30,7 +30,7 @@ if(!M || !ismob(M)) usr << "Type path is not a mob (new_type = [new_type]) in change_mob_type(). Contact a coder." - del(M) + qdel(M) return if( istext(new_name) ) @@ -43,12 +43,12 @@ if(src.dna) M.dna = src.dna.Clone() - if(mind) + if(mind && istype(M, /mob/living)) mind.transfer_to(M) else M.key = key if(delete_old_mob) spawn(1) - del(src) + qdel(src) return M diff --git a/code/modules/nano/modules/crew_monitor.dm b/code/modules/nano/modules/crew_monitor.dm new file mode 100644 index 00000000000..c27c0446395 --- /dev/null +++ b/code/modules/nano/modules/crew_monitor.dm @@ -0,0 +1,88 @@ +/obj/nano_module/crew_monitor + name = "Crew monitor" + var/list/tracked = new + +/obj/nano_module/crew_monitor/Topic(href, href_list) + if(..()) return + var/turf/T = get_turf(src) + if (!T || !(T.z in config.player_levels)) + usr << "Unable to establish a connection: You're too far away from the station!" + return 0 + if(href_list["close"] ) + var/mob/user = usr + var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main") + usr.unset_machine() + ui.close() + return 0 + if(href_list["update"]) + src.updateDialog() + return 1 + +/obj/nano_module/crew_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) + src.scan() + + var/data[0] + var/turf/T = get_turf(src) + var/list/crewmembers = list() + for(var/obj/item/clothing/under/C in src.tracked) + + var/turf/pos = get_turf(C) + + if((C) && (C.has_sensor) && (pos) && (T && pos.z == T.z) && (C.sensor_mode != SUIT_SENSOR_OFF)) + if(istype(C.loc, /mob/living/carbon/human)) + + var/mob/living/carbon/human/H = C.loc + if(H.w_uniform != C) + continue + + var/list/crewmemberData = list("dead"=0, "oxy"=-1, "tox"=-1, "fire"=-1, "brute"=-1, "area"="", "x"=-1, "y"=-1) + + crewmemberData["sensor_type"] = C.sensor_mode + crewmemberData["name"] = H.get_authentification_name(if_no_id="Unknown") + crewmemberData["rank"] = H.get_authentification_rank(if_no_id="Unknown", if_no_job="No Job") + crewmemberData["assignment"] = H.get_assignment(if_no_id="Unknown", if_no_job="No Job") + + if(C.sensor_mode >= SUIT_SENSOR_BINARY) + crewmemberData["dead"] = H.stat > 1 + + if(C.sensor_mode >= SUIT_SENSOR_VITAL) + crewmemberData["oxy"] = round(H.getOxyLoss(), 1) + crewmemberData["tox"] = round(H.getToxLoss(), 1) + crewmemberData["fire"] = round(H.getFireLoss(), 1) + crewmemberData["brute"] = round(H.getBruteLoss(), 1) + + if(C.sensor_mode >= SUIT_SENSOR_TRACKING) + var/area/A = get_area(H) + crewmemberData["area"] = sanitize(A.name) + crewmemberData["x"] = pos.x + crewmemberData["y"] = pos.y + + crewmembers[++crewmembers.len] = crewmemberData + + crewmembers = sortByKey(crewmembers, "name") + + data["crewmembers"] = crewmembers + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + ui = new(user, src, ui_key, "crew_monitor.tmpl", "Crew Monitoring Computer", 900, 800) + + // adding a template with the key "mapContent" enables the map ui functionality + ui.add_template("mapContent", "crew_monitor_map_content.tmpl") + // adding a template with the key "mapHeader" replaces the map header content + ui.add_template("mapHeader", "crew_monitor_map_header.tmpl") + + ui.set_initial_data(data) + ui.open() + + // should make the UI auto-update; doesn't seem to? + ui.set_auto_update(1) + +/obj/nano_module/crew_monitor/proc/scan() + for(var/mob/living/carbon/human/H in mob_list) + if(istype(H.w_uniform, /obj/item/clothing/under)) + var/obj/item/clothing/under/C = H.w_uniform + if (C.has_sensor) + tracked |= C + return 1 diff --git a/code/modules/nano/nanomanager.dm b/code/modules/nano/nanomanager.dm index 2ce8de3b08b..36241b2ec75 100644 --- a/code/modules/nano/nanomanager.dm +++ b/code/modules/nano/nanomanager.dm @@ -1,8 +1,9 @@ // This is the window/UI manager for Nano UI // There should only ever be one (global) instance of nanomanger /datum/nanomanager - // the list of current open /nanoui UIs + // a list of current open /nanoui UIs, grouped by src_object and ui_key var/open_uis[0] + // a list of current open /nanoui UIs, not grouped, for use in processing var/list/processing_uis = list() // a list of asset filenames which are to be sent to the client on user logon var/list/asset_files = list() @@ -26,7 +27,8 @@ filenames = flist(path) for(var/filename in filenames) if(copytext(filename, length(filename)) != "/") // filenames which end in "/" are actually directories, which we want to ignore - asset_files.Add(file(path + filename)) // add this file to asset_files for sending to clients when they connect + if(fexists(path + filename)) + asset_files.Add(fcopy_rsc(path + filename)) // add this file to asset_files for sending to clients when they connect return @@ -85,7 +87,7 @@ /** * Update all /nanoui uis attached to src_object * - * @param src_object /obj|/mob The obj or mob which the uis belong to + * @param src_object /obj|/mob The obj or mob which the uis are attached to * * @return int The number of uis updated */ @@ -97,7 +99,7 @@ var/update_count = 0 for (var/ui_key in open_uis[src_object_key]) for (var/datum/nanoui/ui in open_uis[src_object_key][ui_key]) - if(ui && ui.src_object && ui.user) + if(ui && ui.src_object && ui.user && ui.src_object.nano_host()) ui.process(1) update_count++ return update_count @@ -245,4 +247,3 @@ for(var/file in asset_files) client << browse_rsc(file) // send the file to the client - return 1 // success diff --git a/code/modules/nano/nanoprocs.dm b/code/modules/nano/nanoprocs.dm new file mode 100644 index 00000000000..81b939cf5c4 --- /dev/null +++ b/code/modules/nano/nanoprocs.dm @@ -0,0 +1,11 @@ +/atom/movable/proc/nano_host() + return src + +/obj/nano_module/nano_host() + return loc + +/atom/movable/proc/nano_can_update() + return 1 + +/obj/machinery/nano_can_update() + return !(stat & (NOPOWER|BROKEN)) diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index 01792ad0c3d..6b37eb96948 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -6,11 +6,6 @@ nanoui class (or whatever Byond calls classes) nanoui is used to open and update nano browser uis **********************************************************/ - -#define STATUS_INTERACTIVE 2 // GREEN Visability -#define STATUS_UPDATE 1 // ORANGE Visability -#define STATUS_DISABLED 0 // RED Visability - /datum/nanoui // the user who opened this ui var/mob/user @@ -143,36 +138,122 @@ nanoui is used to open and update nano browser uis * @return nothing */ /datum/nanoui/proc/update_status(var/push_update = 0) - if (istype(user, /mob/living/silicon/ai)) - set_status(STATUS_INTERACTIVE, push_update) // interactive (green visibility) - else if (istype(user, /mob/living/silicon/robot)) - if (src_object in view(7, user)) // robots can see and interact with things they can see within 7 tiles - set_status(STATUS_INTERACTIVE, push_update) // interactive (green visibility) - else - set_status(STATUS_DISABLED, push_update) // no updates, completely disabled (red visibility) + var/atom/movable/host = src_object.nano_host() + if(!host.nano_can_update()) + close() + return + + var/status = user.can_interact_with_interface(host.nano_host()) + if(status == STATUS_CLOSE) + close() else - var/dist = get_dist(src_object, user) + set_status(status, push_update) + +/* + Procs called by update_status() +*/ - if (dist > 4) - close() - return +/mob/living/silicon/pai/can_interact_with_interface(src_object) + if(src_object == src && !stat) + return STATUS_INTERACTIVE + else + return ..() - if ((allowed_user_stat > -1) && (user.stat > allowed_user_stat)) - set_status(STATUS_DISABLED, push_update) // no updates, completely disabled (red visibility) - else if (user.restrained() || user.lying) - set_status(STATUS_UPDATE, push_update) // update only (orange visibility) - else if (istype(src_object, /obj/item/device/uplink/hidden)) // You know what if they have the uplink open let them use the UI - set_status(STATUS_INTERACTIVE, push_update) // Will build in distance checks on the topics for sanity. - else if (!(src_object in view(4, user))) // If the src object is not in visable, set status to 0 - set_status(STATUS_DISABLED, push_update) // interactive (green visibility) - else if (dist <= 1) - set_status(STATUS_INTERACTIVE, push_update) // interactive (green visibility) - else if (dist <= 2) - set_status(STATUS_UPDATE, push_update) // update only (orange visibility) - else if (istype(src_object, /obj/item/device/uplink/hidden)) // You know what if they have the uplink open let them use the UI - set_status(STATUS_INTERACTIVE, push_update) // Will build in distance checks on the topics for sanity. - else if (dist <= 4) - set_status(STATUS_DISABLED, push_update) // no updates, completely disabled (red visibility) +/mob/proc/can_interact_with_interface(var/src_object) + return STATUS_CLOSE // By default no mob can do anything with NanoUI + +/mob/dead/observer/can_interact_with_interface() + if(check_rights(R_ADMIN, 0)) + return STATUS_INTERACTIVE // Admins are more equal + return STATUS_UPDATE // Ghosts can view updates + +/mob/living/silicon/robot/can_interact_with_interface(var/src_object) + if(stat || !client) + return STATUS_CLOSE + if(lockcharge || stunned || weakened) + return STATUS_DISABLED + if (src_object in view(client.view, src)) // robots can see and interact with things they can see within their view range + return STATUS_INTERACTIVE // interactive (green visibility) + return STATUS_DISABLED // no updates, completely disabled (red visibility) + +/mob/living/silicon/robot/syndicate/can_interact_with_interface(var/src_object) + . = ..() + if(. != STATUS_INTERACTIVE) + return + + if(z in config.admin_levels) // Syndicate borgs can interact with everything on the admin level + return STATUS_INTERACTIVE + if(istype(get_area(src), /area/syndicate_station) || istype(get_area(src), /area/traitor)) // If elsewhere, they can interact with everything on the syndicate shuttle and traitor station + return STATUS_INTERACTIVE + if(istype(src_object, /obj/machinery)) // And they can also interact with everything else + /*var/obj/machinery/Machine = src_object + if(Machine.emagged) // Uncomment so they can only interact with emagged machinery + return STATUS_INTERACTIVE*/ + return STATUS_INTERACTIVE + return STATUS_UPDATE + +/mob/living/silicon/ai/can_interact_with_interface(var/src_object) + if(!client || check_unable(1)) + return STATUS_CLOSE + // Prevents the AI from using Topic on admin levels (by for example viewing through the court/thunderdome cameras) + // unless it's on the same level as the object it's interacting with. + var/turf/T = get_turf(src_object) + if(!T || !(z == T.z || (T.z in config.player_levels))) + return STATUS_CLOSE + + // If an object is in view then we can interact with it + if(src_object in view(client.view, src)) + return STATUS_INTERACTIVE + + // If we're installed in a chassi, rather than transfered to an inteliCard or other container, then check if we have camera view + if(is_in_chassis()) + //stop AIs from leaving windows open and using then after they lose vision + //apc_override is needed here because AIs use their own APC when powerless + if(cameranet && !cameranet.checkTurfVis(get_turf(src_object))) + return apc_override ? STATUS_INTERACTIVE : STATUS_CLOSE + return STATUS_INTERACTIVE + + return STATUS_CLOSE + +/mob/living/proc/shared_living_nano_interaction(var/src_object) + if (src.stat != CONSCIOUS) + return STATUS_CLOSE // no updates, close the interface + else if (restrained() || lying || stat || stunned || weakened) + return STATUS_UPDATE // update only (orange visibility) + return STATUS_INTERACTIVE + +/mob/living/proc/shared_living_nano_distance(var/atom/movable/src_object) + if(!isturf(src_object.loc)) + if(src_object.loc == src) // Item in the inventory + return STATUS_INTERACTIVE + if(src.contents.Find(src_object.loc)) // A hidden uplink inside an item + return STATUS_INTERACTIVE + + if (!(src_object in view(4, src))) // If the src object is not in visable, disable updates + return STATUS_CLOSE + + var/dist = get_dist(src_object, src) + if (dist <= 1) + return STATUS_INTERACTIVE // interactive (green visibility) + else if (dist <= 2) + return STATUS_UPDATE // update only (orange visibility) + else if (dist <= 4) + return STATUS_DISABLED // no updates, completely disabled (red visibility) + return STATUS_CLOSE + +/mob/living/can_interact_with_interface(var/src_object, var/be_close = 1) + . = shared_living_nano_interaction(src_object) + if(. == STATUS_INTERACTIVE && be_close) + . = shared_living_nano_distance(src_object) + if(STATUS_INTERACTIVE) + return STATUS_UPDATE + +/mob/living/carbon/human/can_interact_with_interface(var/src_object, var/be_close = 1) + . = shared_living_nano_interaction(src_object) + if(. == STATUS_INTERACTIVE && be_close) + . = shared_living_nano_distance(src_object) + if(. == STATUS_UPDATE && (M_TK in mutations)) // If we have telekinesis and remain close enough, allow interaction. + return STATUS_INTERACTIVE /** * Set the ui to auto update (every master_controller tick) diff --git a/code/modules/paperwork/fax.dm b/code/modules/paperwork/fax.dm new file mode 100644 index 00000000000..a4b13a2876f --- /dev/null +++ b/code/modules/paperwork/fax.dm @@ -0,0 +1,87 @@ +// Fax datum - holds all faxes sent during the round +var/list/faxes = list() +var/list/adminfaxes = list() + +/datum/fax + var/name = "fax" + var/from_department = null + var/to_department = null + var/origin = null + var/message = null + var/sent_by = null + var/sent_at = null + +/datum/fax/New() + faxes += src + +/datum/fax/admin + var/list/reply_to = null + +/datum/fax/admin/New() + adminfaxes += src + +// Fax panel - lets admins check all faxes sent during the round +/client/proc/fax_panel() + set name = "Fax Panel" + set category = "Event" + if(holder) + holder.fax_panel(usr) + feedback_add_details("admin_verb","FXP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + return + +/datum/admins/proc/fax_panel(var/mob/living/user) + var/html = "Refresh" + html += "Create Fax" + + html += "

" + html += "

Admin Faxes

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

Departmental Faxes

" + html += "" + html += "" + for(var/datum/fax/F in faxes) + html += "" + html += "" + html += "" + html += "" + html += "" + if(F.sent_by) + var/mob/living/S = F.sent_by + html += "" + else + html += "" + html += "" + html += "" + html += "
NameFrom DepartmentTo DepartmentSent AtSent ByView
[F.name][F.from_department][F.to_department][worldtime2text(F.sent_at)][S.name]UnknownView
" + html += "
" + + var/datum/browser/popup = new(user, "fax_panel", "Fax Panel", 950, 450) + popup.set_content(html) + popup.open() diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index a727a3f59c3..98726004ea4 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -1,9 +1,8 @@ var/list/obj/machinery/photocopier/faxmachine/allfaxes = list() var/list/admin_departments = list("Central Command") +var/list/hidden_admin_departments = list("Syndicate") var/list/alldepartments = list() -var/list/adminfaxes = list() //cache for faxes that have been sent to admins - /obj/machinery/photocopier/faxmachine name = "fax machine" icon = 'icons/obj/library.dmi' @@ -22,6 +21,8 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins var/department = "Unknown" // our department var/destination = "Central Command" // the department we're sending to + + var/data[0] /obj/machinery/photocopier/faxmachine/New() ..() @@ -31,111 +32,146 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins alldepartments |= department /obj/machinery/photocopier/faxmachine/attack_hand(mob/user as mob) - user.set_machine(src) - - var/dat = "Fax Machine
" - - var/scan_name + ui_interact(user) + +/obj/machinery/photocopier/faxmachine/attackby(obj/item/weapon/item, mob/user) + if(istype(item,/obj/item/weapon/card/id) && !scan) + scan(item) + else if(istype(item, /obj/item/weapon/paper) || istype(item, /obj/item/weapon/photo) || istype(item, /obj/item/weapon/paper_bundle)) + ..() + nanomanager.update_uis(src) + else + return ..() + +/obj/machinery/photocopier/faxmachine/emag_act(user as mob) + if(!emagged) + emagged = 1 + user << "The transmitters realign to an unknown source!" + else + user << "You swipe the card through [src], but nothing happens." + +/obj/machinery/photocopier/faxmachine/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) if(scan) - scan_name = scan.name + data["scan_name"] = scan.name else - scan_name = "--------" - - dat += "Confirm Identity: [scan_name]
" - - if(authenticated) - dat += "{Log Out}" + data["scan_name"] = "-----" + data["authenticated"] = authenticated + if(!authenticated) + data["network"] = "Disconnected" + else if(!emagged) + data["network"] = "Central Command Quantum Entanglement Network" else - dat += "{Log In}" - - dat += "
" - - if(authenticated) - dat += "Logged in to: Central Command Quantum Entanglement Network

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

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

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

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

" + data["paper"] = "-----" + data["paperinserted"] = 0 + data["destination"] = destination + data["cooldown"] = sendcooldown + if((destination in admin_departments) || (destination in hidden_admin_departments)) + data["respectcooldown"] = 1 + else + data["respectcooldown"] = 0 - if(copyitem) - dat += "Remove Item
" - - user << browse(dat, "window=copier") - onclose(user, "copier") - return + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "faxmachine.tmpl", "Fax Machine UI", 540, 450) + ui.set_initial_data(data) + ui.open() /obj/machinery/photocopier/faxmachine/Topic(href, href_list) + if(..()) + return 1 + if(href_list["send"]) - if(copyitem) - if (destination in admin_departments) + if(copyitem && authenticated) + if ((destination in admin_departments) || (destination in hidden_admin_departments)) send_admin_fax(usr, destination) else - sendfax(destination) + sendfax(destination,usr) if (sendcooldown) spawn(sendcooldown) // cooldown time sendcooldown = 0 + nanomanager.update_uis(src) - else if(href_list["remove"]) + if(href_list["paper"]) if(copyitem) copyitem.loc = usr.loc usr.put_in_hands(copyitem) usr << "You take \the [copyitem] out of \the [src]." copyitem = null - updateUsrDialog() + else + var/obj/item/I = usr.get_active_hand() + if (istype(I, /obj/item/weapon/paper) || istype(I, /obj/item/weapon/photo) || istype(I, /obj/item/weapon/paper_bundle)) + usr.drop_item() + copyitem = I + I.loc = src + usr << "You insert \the [I] into \the [src]." + flick(insert_anim, src) if(href_list["scan"]) - if (scan) - if(ishuman(usr)) - scan.loc = usr.loc - if(!usr.get_active_hand()) - usr.put_in_hands(scan) - scan = null - else - scan.loc = src.loc - scan = null + scan() + + if(href_list["dept"]) + if(authenticated) + var/lastdestination = destination + var/list/combineddepartments = alldepartments + admin_departments + if(emagged) + combineddepartments += hidden_admin_departments + destination = input(usr, "To which department?", "Choose a department", "") as null|anything in combineddepartments + if(!destination) + destination = lastdestination + + if(href_list["auth"]) + if((!authenticated) && scan) + if(check_access(scan)) + authenticated = 1 + else if(authenticated) + authenticated = 0 + + if(href_list["rename"]) + if(copyitem) + var/n_name = copytext(sanitize(input(usr, "What would you like to label the fax?", "Fax Labelling", copyitem.name) as text), 1, MAX_MESSAGE_LEN) + if((copyitem && copyitem.loc == src && usr.stat == 0)) + if (istype(copyitem, /obj/item/weapon/paper)) + copyitem.name = "[(n_name ? text("[n_name]") : initial(copyitem.name))]" + copyitem.desc = "This is a paper titled '" + copyitem.name + "'." + else if(istype(copyitem, /obj/item/weapon/photo)) + copyitem.name = "[(n_name ? text("[n_name]") : "photo")]" + else if(istype(copyitem, /obj/item/weapon/paper_bundle)) + copyitem.name = "[(n_name ? text("[n_name]") : "paper")]" + data["name"] = copyitem.name + + nanomanager.update_uis(src) + +/obj/machinery/photocopier/faxmachine/proc/scan(var/obj/item/weapon/card/id/card = null) + if(scan) // Card is in machine + if(ishuman(usr)) + scan.loc = usr.loc + if(!usr.get_active_hand()) + usr.put_in_hands(scan) + scan = null else + scan.loc = src.loc + scan = null + else + if(!card) var/obj/item/I = usr.get_active_hand() if (istype(I, /obj/item/weapon/card/id)) usr.drop_item() I.loc = src scan = I - authenticated = 0 + else + if(istype(card)) + usr.drop_item() + card.loc = src + scan = card + nanomanager.update_uis(src) - if(href_list["dept"]) - var/lastdestination = destination - destination = input(usr, "Which department?", "Choose a department", "") as null|anything in (alldepartments + admin_departments) - if(!destination) destination = lastdestination - - if(href_list["auth"]) - if ( (!( authenticated ) && (scan)) ) - if (check_access(scan)) - authenticated = 1 - - if(href_list["logout"]) - authenticated = 0 - - updateUsrDialog() - -/obj/machinery/photocopier/faxmachine/proc/sendfax(var/destination) +/obj/machinery/photocopier/faxmachine/proc/sendfax(var/destination,var/mob/sender) if(stat & (BROKEN|NOPOWER)) return @@ -144,15 +180,24 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins var/success = 0 for(var/obj/machinery/photocopier/faxmachine/F in allfaxes) if( F.department == destination ) - success = F.recievefax(copyitem) + success = F.receivefax(copyitem) if (success) + var/datum/fax/F = new /datum/fax() + F.name = copyitem.name + F.from_department = department + F.to_department = destination + F.origin = src + F.message = copyitem + F.sent_by = sender + F.sent_at = world.time + visible_message("[src] beeps, \"Message transmitted successfully.\"") //sendcooldown = 600 else visible_message("[src] beeps, \"Error transmitting message.\"") -/obj/machinery/photocopier/faxmachine/proc/recievefax(var/obj/item/incoming) +/obj/machinery/photocopier/faxmachine/proc/receivefax(var/obj/item/incoming) if(stat & (BROKEN|NOPOWER)) return 0 @@ -195,20 +240,29 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins return rcvdcopy.loc = null //hopefully this shouldn't cause trouble - adminfaxes += rcvdcopy + + var/datum/fax/admin/A = new /datum/fax/admin() + A.name = rcvdcopy.name + A.from_department = department + A.to_department = destination + A.origin = src + A.message = rcvdcopy + A.sent_by = sender + A.sent_at = world.time //message badmins that a fax has arrived switch(destination) if ("Central Command") - message_admins(sender, "CENTCOMM FAX", rcvdcopy, "CentcommFaxReply", "#006100") - + message_admins(sender, "CENTCOM FAX", destination, rcvdcopy, "#006100") + if ("Syndicate") + message_admins(sender, "SYNDICATE FAX", destination, rcvdcopy, "#DC143C") sendcooldown = 1800 sleep(50) visible_message("[src] beeps, \"Message transmitted successfully.\"") -/obj/machinery/photocopier/faxmachine/proc/message_admins(var/mob/sender, var/faxname, var/obj/item/sent, var/reply_type, font_colour="#006100") - var/msg = "\blue [faxname]: [key_name(sender, 1)] (PP) (VV) (SM) (JMP) (CA) (REPLY): Receiving '[sent.name]' via secure connection ... view message" +/obj/machinery/photocopier/faxmachine/proc/message_admins(var/mob/sender, var/faxname, var/faxtype, var/obj/item/sent, font_colour="#006100") + var/msg = "\blue [faxname]: [key_name(sender, 1)] (PP) (VV) (SM) (JMP) (CA) (BSA) (REPLY): Receiving '[sent.name]' via secure connection... view message" for(var/client/C in admins) if(R_ADMIN & C.holder.rights) diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 972fec5eddb..fce6c2acda6 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -76,7 +76,7 @@ if((M_CLUMSY in usr.mutations) && prob(50)) usr << "You cut yourself on the paper." return - var/n_name = copytext(sanitize(input(usr, "What would you like to label the paper?", "Paper Labelling", null) as text), 1, MAX_MESSAGE_LEN) + var/n_name = copytext(sanitize(input(usr, "What would you like to label the paper?", "Paper Labelling", name) as text), 1, MAX_MESSAGE_LEN) if((loc == usr && usr.stat == 0)) name = "[(n_name ? text("[n_name]") : initial(name))]" if(name != "paper") diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm index e7ccdf2bf90..f821871069c 100644 --- a/code/modules/paperwork/paper_bundle.dm +++ b/code/modules/paperwork/paper_bundle.dm @@ -189,9 +189,9 @@ set category = "Object" set src in usr - var/n_name = copytext(sanitize(input(usr, "What would you like to label the bundle?", "Bundle Labelling", null) as text), 1, MAX_MESSAGE_LEN) + var/n_name = copytext(sanitize(input(usr, "What would you like to label the bundle?", "Bundle Labelling", name) as text), 1, MAX_MESSAGE_LEN) if((loc == usr && usr.stat == 0)) - name = "[(n_name ? text("[n_name]") : "paper")]" + name = "[(n_name ? text("[n_name]") : "paper bundle")]" add_fingerprint(usr) return diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index 15e2e844f21..479d2510605 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -90,7 +90,7 @@ set category = "Object" set src in usr - var/n_name = copytext(sanitize(input(usr, "What would you like to label the photo?", "Photo Labelling", null) as text), 1, MAX_MESSAGE_LEN) + var/n_name = copytext(sanitize(input(usr, "What would you like to label the photo?", "Photo Labelling", name) as text), 1, MAX_MESSAGE_LEN) //loc.loc check is for making possible renaming photos in clipboards if(( (loc == usr || (loc.loc && loc.loc == usr)) && usr.stat == 0)) name = "[(n_name ? text("[n_name]") : "photo")]" @@ -311,6 +311,7 @@ var/datum/picture/P = new() P.fields["name"] = "photo" + P.fields["author"] = user P.fields["icon"] = ic P.fields["tiny"] = pc P.fields["img"] = photoimage @@ -401,4 +402,4 @@ if(get_dist(src, M) <= canhear_range) talk_into(M, msg) for(var/mob/living/carbon/human/H in watcherslist) - H.show_message(text("\blue (Newscaster) [] says, '[]'",M,msg), 1) \ No newline at end of file + H.show_message(text("\blue (Newscaster) [] says, '[]'",M,msg), 1) diff --git a/code/modules/paperwork/stamps.dm b/code/modules/paperwork/stamps.dm index 04320d51d16..243762eefb6 100644 --- a/code/modules/paperwork/stamps.dm +++ b/code/modules/paperwork/stamps.dm @@ -1,5 +1,5 @@ /obj/item/weapon/stamp - name = "\improper GRANTED rubber stamp" + name = "\improper rubber stamp" desc = "A rubber stamp for stamping important documents." icon = 'icons/obj/bureaucracy.dmi' icon_state = "stamp-ok" @@ -53,6 +53,11 @@ icon_state = "stamp-cmo" _color = "cmo" +/obj/item/weapon/stamp/granted + name = "\improper GRANTED rubber stamp" + icon_state = "stamp-ok" + _color = "qm" + /obj/item/weapon/stamp/denied name = "\improper DENIED rubber stamp" icon_state = "stamp-deny" diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 6de3d9cea23..2e09cd993a9 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -458,23 +458,6 @@ update_icon() else user << "\red Access denied." - else if (istype(W, /obj/item/weapon/card/emag) && !(emagged || malfhack)) // trying to unlock with an emag card - if(opened) - user << "You must close the cover to swipe an ID card." - else if(wiresexposed) - user << "You must close the panel first" - else if(stat & (BROKEN|MAINT)) - user << "Nothing happens." - else - flick("apc-spark", src) - if (do_after(user,6)) - if(prob(50)) - emagged = 1 - locked = 0 - user << "You emag the APC interface." - update_icon() - else - user << "You fail to [ locked ? "unlock" : "lock"] the APC interface." else if (istype(W, /obj/item/stack/cable_coil) && !terminal && opened && has_electronics!=2) if (src.loc:intact) user << "\red You must remove the floor plating in front of the APC first." @@ -598,8 +581,26 @@ "\red You hit the [src.name] with your [W.name]!", \ "You hear bang") +/obj/machinery/power/apc/emag_act(user as mob) + if (!(emagged || malfhack)) // trying to unlock with an emag card + if(opened) + user << "You must close the cover to swipe an ID card." + else if(wiresexposed) + user << "You must close the panel first" + else if(stat & (BROKEN|MAINT)) + user << "Nothing happens." + else + flick("apc-spark", src) + if (do_after(user,6)) + if(prob(50)) + emagged = 1 + locked = 0 + user << "You emag the APC interface." + update_icon() + else + user << "You fail to [ locked ? "unlock" : "lock"] the APC interface." + // attack with hand - remove cell (if cover open) or interact with the APC - /obj/machinery/power/apc/attack_hand(mob/user) // if (!can_use(user)) This already gets called in interact() and in topic() // return @@ -941,7 +942,7 @@ malfai.malfhacking = 0 locked = 1 if (ticker.mode.config_tag == "malfunction") - if (src.z == 1) //if (is_type_in_list(get_area(src), the_station_areas)) + if ((src.z in config.station_levels)) //if (is_type_in_list(get_area(src), the_station_areas)) ticker.mode:apcs++ if(usr:parent) src.malfai = usr:parent @@ -973,7 +974,7 @@ if(malfai) if (ticker.mode.config_tag == "malfunction") - if (src.z == 1) //if (is_type_in_list(get_area(src), the_station_areas)) + if ((src.z in config.station_levels)) //if (is_type_in_list(get_area(src), the_station_areas)) operating ? ticker.mode:apcs++ : ticker.mode:apcs-- src.update() @@ -988,7 +989,7 @@ if(!malf.can_shunt) malf << "You cannot shunt." return - if(src.z != 1) + if(!(src.z in config.station_levels)) return src.occupant = new /mob/living/silicon/ai(src,malf.laws,null,1) src.occupant.adjustOxyLoss(malf.getOxyLoss()) @@ -1037,7 +1038,7 @@ /obj/machinery/power/apc/proc/ion_act() //intended to be exactly the same as an AI malf attack - if(!src.malfhack && src.z == 1) + if(!src.malfhack && (src.z in config.station_levels)) if(prob(3)) src.locked = 1 if (src.cell.charge > 0) @@ -1306,7 +1307,7 @@ obj/machinery/power/apc/proc/autoset(var/val, var/on) /obj/machinery/power/apc/proc/set_broken() if(malfai && operating) if (ticker.mode.config_tag == "malfunction") - if (src.z == 1) //if (is_type_in_list(get_area(src), the_station_areas)) + if ((src.z in config.station_levels)) //if (is_type_in_list(get_area(src), the_station_areas)) ticker.mode:apcs-- stat |= BROKEN operating = 0 @@ -1332,7 +1333,7 @@ obj/machinery/power/apc/proc/autoset(var/val, var/on) /obj/machinery/power/apc/Destroy() if(malfai && operating) if (ticker.mode.config_tag == "malfunction") - if (src.z == 1) //if (is_type_in_list(get_area(src), the_station_areas)) + if ((src.z in config.station_levels)) //if (is_type_in_list(get_area(src), the_station_areas)) ticker.mode:apcs-- area.power_light = 0 area.power_equip = 0 diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index d16e13b8a96..54741e0245d 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -270,7 +270,7 @@ if(src.amount <= 14) usr << "\red You need at least 15 lengths to make restraints!" return - var/obj/item/weapon/handcuffs/cable/B = new /obj/item/weapon/handcuffs/cable(usr.loc) + var/obj/item/weapon/restraints/handcuffs/cable/B = new /obj/item/weapon/restraints/handcuffs/cable(usr.loc) B.icon_state = "cuff_[_color]" usr << "\blue You wind some cable together to make some restraints." src.use(15) diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index df04bacdc70..c9ac32da530 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -123,7 +123,7 @@ var/const/GRAV_NEEDS_WRENCH = 3 O.main_part = null qdel(O) for(var/area/A in world) - if (A.z != 1) continue + if (!(A.z in config.station_levels)) continue A.gravitychange(0,A) shake_everyone() ..() @@ -294,7 +294,7 @@ var/const/GRAV_NEEDS_WRENCH = 3 investigate_log("was brought online and is now producing gravity for this level.", "gravity") message_admins("The gravity generator was brought online. ([area.name])") for(var/area/A in world) - if (A.z != 1) continue + if (!(A.z in config.station_levels)) continue A.gravitychange(1,A) else if(gravity_in_level() == 1) @@ -302,7 +302,7 @@ var/const/GRAV_NEEDS_WRENCH = 3 investigate_log("was brought offline and there is now no gravity for this level.", "gravity") message_admins("The gravity generator was brought offline with no backup generator. ([area.name])") for(var/area/A in world) - if (A.z != 1) continue + if (!(A.z in config.station_levels)) continue A.gravitychange(0,A) update_icon() diff --git a/code/modules/power/pacman2.dm b/code/modules/power/pacman2.dm index 89d65a6ae21..9402a4c234f 100644 --- a/code/modules/power/pacman2.dm +++ b/code/modules/power/pacman2.dm @@ -81,14 +81,6 @@ user.drop_item() O.loc = src user << "\blue You add the plasma tank to the generator." - else if (istype(O, /obj/item/weapon/card/emag)) - var/obj/item/weapon/card/emag/E = O - if(E.uses) - E.uses-- - else - return - emagged = 1 - emp_act(1) else if(!active) if(istype(O, /obj/item/weapon/wrench)) anchored = !anchored @@ -114,6 +106,11 @@ new_frame.state = 2 new_frame.icon_state = "box_1" del(src) + + emag_act(user as mob) + if(!emagged) + emagged = 1 + emp_act(1) attack_hand(mob/user as mob) ..() diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index a334782cce1..d918ec86711 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -211,9 +211,6 @@ display round(lastgen) and plasmatank amount addstack.use(amount) updateUsrDialog() return - else if (istype(O, /obj/item/weapon/card/emag)) - emagged = 1 - emp_act(1) else if(!active) if(istype(O, /obj/item/weapon/wrench)) if(!anchored && !isinspace()) @@ -239,6 +236,10 @@ display round(lastgen) and plasmatank amount else if(istype(O, /obj/item/weapon/crowbar) && panel_open) default_deconstruction_crowbar(O) +/obj/machinery/power/port_gen/pacman/emag_act(user as mob) + emagged = 1 + emp_act(1) + /obj/machinery/power/port_gen/pacman/attack_hand(mob/user as mob) ..() if (!anchored) diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 601d7191f7b..8e9e16c9943 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -222,12 +222,14 @@ user << "\red Access denied." return - - if(istype(W, /obj/item/weapon/card/emag) && !emagged) + ..() + return + +/obj/machinery/power/emitter/emag_act(user as mob) + if(!emagged) + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user locked = 0 emagged = 1 - user.visible_message("[user.name] emags the [src.name].","\red You short out the lock.") - return - - ..() - return \ No newline at end of file + H.visible_message("[H.name] emags the [src.name].","\red You short out the lock.") diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index a3065ce3bb4..3fe245d34dd 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -421,7 +421,7 @@ /obj/machinery/power/smes/proc/ion_act() - if(src.z == 1) + if((src.z in config.station_levels)) if(prob(1)) //explosion world << "\red SMES explosion in [src.loc.loc]" for(var/mob/M in viewers(src)) diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index 9c622e47ca9..b8356cacc34 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -1,20 +1,8 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33 - #define SOLAR_MAX_DIST 40 #define SOLARGENRATE 1500 var/list/solars_list = list() -// This will choose whether to get the solar list from the powernet or the powernet nodes, -// depending on the size of the nodes. -/obj/machinery/power/proc/get_solars_powernet() - if(!powernet) - return list() - if(solars_list.len < powernet.nodes) - return solars_list - else - return powernet.nodes - /obj/machinery/power/solar name = "solar panel" desc = "A solar electrical generator." @@ -22,7 +10,6 @@ var/list/solars_list = list() icon_state = "sp_base" anchored = 1 density = 1 - directwired = 1 use_power = 0 idle_power_usage = 0 active_power_usage = 0 @@ -30,26 +17,33 @@ var/list/solars_list = list() var/health = 10 var/obscured = 0 var/sunfrac = 0 - var/adir = SOUTH - var/ndir = SOUTH + var/adir = SOUTH // actual dir + var/ndir = SOUTH // target dir var/turn_angle = 0 var/obj/machinery/power/solar_control/control = null -/obj/machinery/power/solar/New(var/turf/loc, var/obj/item/solar_assembly/S, var/process = 1) +/obj/machinery/power/solar/New(var/turf/loc, var/obj/item/solar_assembly/S) ..(loc) Make(S) - connect_to_network(process) + connect_to_network() - -/obj/machinery/power/solar/disconnect_from_network() +/obj/machinery/power/solar/Destroy() + unset_control() //remove from control computer ..() - solars_list.Remove(src) -/obj/machinery/power/solar/connect_to_network(var/process) - ..() - if(process) - solars_list.Add(src) +//set the control of the panel to a given computer if closer than SOLAR_MAX_DIST +/obj/machinery/power/solar/proc/set_control(var/obj/machinery/power/solar_control/SC) + if(!SC || (get_dist(src, SC) > SOLAR_MAX_DIST)) + return 0 + control = SC + SC.connected_panels |= src + return 1 +//set the control of the panel to null and removes it from the control list of the previous control computer if needed +/obj/machinery/power/solar/proc/unset_control() + if(control) + control.connected_panels.Remove(src) + control = null /obj/machinery/power/solar/proc/Make(var/obj/item/solar_assembly/S) if(!S) @@ -57,22 +51,25 @@ var/list/solars_list = list() S.glass_type = /obj/item/stack/sheet/glass S.anchored = 1 S.loc = src + if(S.glass_type == /obj/item/stack/sheet/rglass) //if the panel is in reinforced glass + health *= 2 //this need to be placed here, because panels already on the map don't have an assembly linked to update_icon() /obj/machinery/power/solar/attackby(obj/item/weapon/W, mob/user) - if(iscrowbar(W)) - playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) + if(istype(W, /obj/item/weapon/crowbar)) + playsound(src.loc, 'sound/machines/click.ogg', 50, 1) + user.visible_message("[user] begins to take the glass off the solar panel.") if(do_after(user, 50)) var/obj/item/solar_assembly/S = locate() in src if(S) S.loc = src.loc S.give_glass() - playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) + playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) user.visible_message("[user] takes the glass off the solar panel.") - del(src) + qdel(src) return else if (W) src.add_fingerprint(user) @@ -92,9 +89,9 @@ var/list/solars_list = list() if(!(stat & BROKEN)) broken() else - getFromPool(/obj/item/weapon/shard, loc) - getFromPool(/obj/item/weapon/shard, loc) - del(src) + new /obj/item/weapon/shard(src.loc) + new /obj/item/weapon/shard(src.loc) + qdel(src) return return @@ -109,70 +106,58 @@ var/list/solars_list = list() src.dir = angle2dir(adir) return - +//calculates the fraction of the sunlight that the panel recieves /obj/machinery/power/solar/proc/update_solar_exposure() if(!sun) return if(obscured) sunfrac = 0 return - var/p_angle = abs((360+adir)%360 - (360+sun.angle)%360) + + //find the smaller angle between the direction the panel is facing and the direction of the sun (the sign is not important here) + var/p_angle = min(abs(adir - sun.angle), 360 - abs(adir - sun.angle)) + if(p_angle > 90) // if facing more than 90deg from sun, zero output sunfrac = 0 return - sunfrac = cos(p_angle) ** 2 + sunfrac = cos(p_angle) ** 2 + //isn't the power recieved from the incoming light proportionnal to cos(p_angle) (Lambert's cosine law) rather than cos(p_angle)^2 ? /obj/machinery/power/solar/process()//TODO: remove/add this from machines to save on processing as needed ~Carn PRIORITY - if(stat & BROKEN) return - if(!control) return + if(stat & BROKEN) + return + if(!sun || !control) //if there's no sun or the panel is not linked to a solar control computer, no need to proceed + return - if(adir != ndir) - adir = (360+adir+dd_range(-10,10,ndir-adir))%360 - update_icon() - update_solar_exposure() - - if(obscured) return - - var/sgen = SOLARGENRATE * sunfrac - add_avail(sgen) - if(powernet && control) - if(powernet.nodes[control]) + if(powernet) + if(powernet == control.powernet)//check if the panel is still connected to the computer + if(obscured) //get no light from the sun, so don't generate power + return + var/sgen = SOLARGENRATE * sunfrac + add_avail(sgen) control.gen += sgen - + else //if we're no longer on the same powernet, remove from control computer + unset_control() /obj/machinery/power/solar/proc/broken() + . = (!(stat & BROKEN)) stat |= BROKEN + unset_control() update_icon() return -/obj/machinery/power/solar/meteorhit() - if(stat & !BROKEN) - broken() - else - del(src) - - -/obj/machinery/power/solar/ex_act(severity) - switch(severity) - if(1.0) - qdel(src) - if(prob(15)) - getFromPool(/obj/item/weapon/shard, loc) - return - if(2.0) - if (prob(25)) - getFromPool(/obj/item/weapon/shard, loc) - qdel(src) - return - if (prob(50)) - broken() - if(3.0) - if (prob(25)) - broken() - return - +/obj/machinery/power/solar/ex_act(severity, target) + ..() + if(!gc_destroyed) + switch(severity) + if(2) + if(prob(50) && broken()) + new /obj/item/weapon/shard(src.loc) + if(3) + if(prob(25) && broken()) + new /obj/item/weapon/shard(src.loc) /obj/machinery/power/solar/blob_act() if(prob(75)) @@ -187,6 +172,29 @@ var/list/solars_list = list() . = PROCESS_KILL return +//trace towards sun to see if we're in shadow +/obj/machinery/power/solar/proc/occlusion() + + var/ax = x // start at the solar panel + var/ay = y + var/turf/T = null + + for(var/i = 1 to 20) // 20 steps is enough + ax += sun.dx // do step + ay += sun.dy + + T = locate( round(ax,0.5),round(ay,0.5),z) + + if(T.x == 1 || T.x==world.maxx || T.y==1 || T.y==world.maxy) // not obscured if we reach the edge + break + + if(T.density) // if we hit a solid turf, panel is obscured + obscured = 1 + return + + obscured = 0 // if hit the edge or stepped 20 times, not obscured + update_solar_exposure() + // // Solar Assembly - For construction of solar arrays. @@ -218,40 +226,42 @@ var/list/solars_list = list() /obj/item/solar_assembly/attackby(var/obj/item/weapon/W, var/mob/user) if(!anchored && isturf(loc)) - if(iswrench(W)) + if(istype(W, /obj/item/weapon/wrench)) anchored = 1 user.visible_message("[user] wrenches the solar assembly into place.") - playsound(get_turf(src), 'sound/items/Ratchet.ogg', 75, 1) + playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) return 1 else - if(iswrench(W)) + if(istype(W, /obj/item/weapon/wrench)) anchored = 0 user.visible_message("[user] unwrenches the solar assembly from it's place.") - playsound(get_turf(src), 'sound/items/Ratchet.ogg', 75, 1) + playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) return 1 if(istype(W, /obj/item/stack/sheet/glass) || istype(W, /obj/item/stack/sheet/rglass)) var/obj/item/stack/sheet/S = W - if(S.amount >= 2) + if(S.use(2)) glass_type = W.type - S.use(2) - playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) + playsound(src.loc, 'sound/machines/click.ogg', 50, 1) user.visible_message("[user] places the glass on the solar assembly.") if(tracker) new /obj/machinery/power/tracker(get_turf(src), src) else new /obj/machinery/power/solar(get_turf(src), src) + else + user << "You need two sheets of glass to put them into a solar panel." + return return 1 if(!tracker) if(istype(W, /obj/item/weapon/tracker_electronics)) tracker = 1 user.drop_item() - del(W) + qdel(W) user.visible_message("[user] inserts the electronics into the solar assembly.") return 1 else - if(iscrowbar(W)) + if(istype(W, /obj/item/weapon/crowbar)) new /obj/item/weapon/tracker_electronics(src.loc) tracker = 0 user.visible_message("[user] takes out the electronics from the solar assembly.") @@ -269,18 +279,18 @@ var/list/solars_list = list() icon_state = "solar" anchored = 1 density = 1 - directwired = 1 use_power = 1 - idle_power_usage = 5 - active_power_usage = 20 + idle_power_usage = 250 var/id = 0 var/cdir = 0 + var/targetdir = 0 // target angle in manual tracking (since it updates every game minute) var/gen = 0 var/lastgen = 0 - var/track = 0 // 0=off 1=manual 2=automatic - var/trackrate = 60 // Measured in tenths of degree per minute (i.e. defaults to 6.0 deg/min) - var/trackdir = 1 // -1=CCW, 1=CW - var/nexttime = 0 // Next clock time that manual tracking will move the array + var/track = 0 // 0= off 1=timed 2=auto (tracker) + var/trackrate = 600 // 300-900 seconds + var/nexttime = 0 // time for a panel to rotate of 1� in manual tracking + var/obj/machinery/power/tracker/connected_tracker = null + var/list/connected_panels = list() /obj/machinery/power/solar_control/New() @@ -289,14 +299,53 @@ var/list/solars_list = list() initialize() connect_to_network() +/obj/machinery/power/solar_control/Destroy() + for(var/obj/machinery/power/solar/M in connected_panels) + M.unset_control() + if(connected_tracker) + connected_tracker.unset_control() + ..() + /obj/machinery/power/solar_control/disconnect_from_network() ..() solars_list.Remove(src) /obj/machinery/power/solar_control/connect_to_network() - ..() + var/to_return = ..() + if(powernet) //if connected and not already in solar_list... + solars_list |= src //... add it + return to_return + +//search for unconnected panels and trackers in the computer powernet and connect them +/obj/machinery/power/solar_control/proc/search_for_connected() if(powernet) - solars_list.Add(src) + for(var/obj/machinery/power/M in powernet.nodes) + if(istype(M, /obj/machinery/power/solar)) + var/obj/machinery/power/solar/S = M + if(!S.control) //i.e unconnected + S.set_control(src) + else if(istype(M, /obj/machinery/power/tracker)) + if(!connected_tracker) //if there's already a tracker connected to the computer don't add another + var/obj/machinery/power/tracker/T = M + if(!T.control) //i.e unconnected + T.set_control(src) + +//called by the sun controller, update the facing angle (either manually or via tracking) and rotates the panels accordingly +/obj/machinery/power/solar_control/proc/update() + if(stat & (NOPOWER | BROKEN)) + return + + switch(track) + if(1) + if(trackrate) //we're manual tracking. If we set a rotation speed... + cdir = targetdir //...the current direction is the targetted one (and rotates panels to it) + if(2) // auto-tracking + if(connected_tracker) + connected_tracker.set_angle(sun.angle) + + set_panels(cdir) + updateDialog() + /obj/machinery/power/solar_control/initialize() ..() @@ -314,32 +363,47 @@ var/list/solars_list = list() return icon_state = "solar" overlays.Cut() - if(cdir > 0) + if(cdir > -1) overlays += image('icons/obj/computer.dmi', "solcon-o", FLY_LAYER, angle2dir(cdir)) return - -/obj/machinery/power/solar_control/attack_ai(mob/user) - src.add_hiddenprint(user) - add_fingerprint(user) - if(stat & (BROKEN | NOPOWER)) return - interact(user) - - /obj/machinery/power/solar_control/attack_hand(mob/user) - add_fingerprint(user) - if(stat & (BROKEN | NOPOWER)) return - interact(user) + if(!..()) + ui_interact(user) +/obj/machinery/power/solar_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + + var/data = list() + + data["generated"] = round(lastgen) + data["angle"] = cdir + data["direction"] = angle2text(cdir) + + data["tracking_state"] = track + data["tracking_rate"] = trackrate + data["rotating_way"] = (trackrate<0 ? "CCW" : "CW") + + data["connected_panels"] = connected_panels.len + data["connected_tracker"] = (connected_tracker ? 1 : 0) + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "solar_control.tmpl", name, 490, 420) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + else + ui.push_data(data) + return /obj/machinery/power/solar_control/attackby(I as obj, user as mob) if(istype(I, /obj/item/weapon/screwdriver)) - playsound(get_turf(src), 'sound/items/Screwdriver.ogg', 50, 1) + playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) if(do_after(user, 20)) if (src.stat & BROKEN) - user << "\blue The broken glass falls out." + user << "The broken glass falls out." var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) - getFromPool(/obj/item/weapon/shard, loc) + new /obj/item/weapon/shard( src.loc ) var/obj/item/weapon/circuitboard/solar_control/M = new /obj/item/weapon/circuitboard/solar_control( A ) for (var/obj/C in src) C.loc = src.loc @@ -347,9 +411,9 @@ var/list/solars_list = list() A.state = 3 A.icon_state = "3" A.anchored = 1 - del(src) + qdel(src) else - user << "\blue You disconnect the monitor." + user << "You disconnect the monitor." var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) var/obj/item/weapon/circuitboard/solar_control/M = new /obj/item/weapon/circuitboard/solar_control( A ) for (var/obj/C in src) @@ -358,12 +422,11 @@ var/list/solars_list = list() A.state = 4 A.icon_state = "4" A.anchored = 1 - del(src) + qdel(src) else src.attack_hand(user) return - /obj/machinery/power/solar_control/process() lastgen = gen gen = 0 @@ -371,139 +434,64 @@ var/list/solars_list = list() if(stat & (NOPOWER | BROKEN)) return - use_power(250) - if(track==1 && nexttime < world.time && trackdir*trackrate) - // Increments nexttime using itself and not world.time to prevent drift - nexttime = nexttime + 6000/trackrate - // Nudges array 1 degree in desired direction - cdir = (cdir+trackdir+360)%360 - set_panels(cdir) - update_icon() - - src.updateDialog() - - -// called by solar tracker when sun position changes -/obj/machinery/power/solar_control/proc/tracker_update(var/angle) - if(track != 2 || stat & (NOPOWER | BROKEN)) - return - cdir = angle - set_panels(cdir) - update_icon() - src.updateDialog() - - -/obj/machinery/power/solar_control/interact(mob/user) - if(stat & (BROKEN | NOPOWER)) return - if ( (get_dist(src, user) > 1 )) - if (!istype(user, /mob/living/silicon/ai)) - user.unset_machine() - user << browse(null, "window=solcon") - return - - add_fingerprint(user) - user.set_machine(src) - - - // AUTOFIXED BY fix_string_idiocy.py - // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\power\solar.dm:407: var/t = "Solar Generator Control
"
-	var/t = {"Solar Generator Control
-Generated power : [round(lastgen)] W
-Station Rotational Period: [60/abs(sun.rate)] minutes
-Station Rotational Direction: [sun.rate<0 ? "CCW" : "CW"]
-Star Orientation: [sun.angle]° ([angle2text(sun.angle)])
-Array Orientation: [rate_control(src,"cdir","[cdir]°",1,10,60)] ([angle2text(cdir)])
-


-Tracking:"} - // END AUTOFIX - switch(track) - if(0) - t += "Off Manual Automatic
" - if(1) - t += "Off Manual Automatic
" - if(2) - t += "Off Manual Automatic
" - - - // AUTOFIXED BY fix_string_idiocy.py - // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\power\solar.dm:423: t += "Manual Tracking Rate: [rate_control(src,"tdir","[trackrate/10]°/min ([trackdir<0 ? "CCW" : "CW"])",1,10)]
" - t += {"Manual Tracking Rate: [rate_control(src,"tdir","[trackrate/10]°/min ([trackdir<0 ? "CCW" : "CW"])",1,10)]
-Manual Tracking Direction:"} - // END AUTOFIX - switch(trackdir) - if(-1) - t += "CW CCW
" - if(1) - t += "CW CCW
" - t += "Close
" - user << browse(t, "window=solcon") - onclose(user, "solcon") - return + if(connected_tracker) //NOTE : handled here so that we don't add trackers to the processing list + if(connected_tracker.powernet != powernet) + connected_tracker.unset_control() + if(track==1 && trackrate) //manual tracking and set a rotation speed + if(nexttime <= world.time) //every time we need to increase/decrease the angle by 1�... + targetdir = (targetdir + trackrate/abs(trackrate) + 360) % 360 //... do it + nexttime += 36000/abs(trackrate) //reset the counter for the next 1� /obj/machinery/power/solar_control/Topic(href, href_list) if(..()) - usr << browse(null, "window=solcon") - usr.unset_machine() return - if(href_list["close"] ) - usr << browse(null, "window=solcon") - usr.unset_machine() - return - - if(href_list["dir"]) - cdir = text2num(href_list["dir"]) - set_panels(cdir) - update_icon() - - if(href_list["rate control"]) + + if(href_list["rate_control"]) if(href_list["cdir"]) src.cdir = dd_range(0,359,(360+src.cdir+text2num(href_list["cdir"]))%360) + src.targetdir = src.cdir + if(track == 2) //manual update, so losing auto-tracking + track = 0 spawn(1) set_panels(cdir) - update_icon() if(href_list["tdir"]) - src.trackrate = dd_range(0,360,src.trackrate+text2num(href_list["tdir"])) - if(src.trackrate) nexttime = world.time + 6000/trackrate + src.trackrate = dd_range(-7200,7200,src.trackrate+text2num(href_list["tdir"])) + if(src.trackrate) nexttime = world.time + 36000/abs(trackrate) if(href_list["track"]) - if(src.trackrate) nexttime = world.time + 6000/trackrate track = text2num(href_list["track"]) - if(powernet && (track == 2)) - if(!solars_list.Find(src,1,0) || !(locate(src) in solars_list) || !(src in solars_list)) - solars_list.Add(src) - for(var/obj/machinery/power/tracker/T in get_solars_powernet()) - if(powernet.nodes[T]) - cdir = T.sun_angle - break + if(track == 2) + if(connected_tracker) + connected_tracker.set_angle(sun.angle) + set_panels(cdir) + else if (track == 1) //begin manual tracking + src.targetdir = src.cdir + if(src.trackrate) nexttime = world.time + 36000/abs(trackrate) + set_panels(targetdir) - if(href_list["trackdir"]) - trackdir = text2num(href_list["trackdir"]) + if(href_list["search_connected"]) + search_for_connected() + if(connected_tracker && track == 2) + connected_tracker.set_angle(sun.angle) + set_panels(cdir) - set_panels(cdir) - update_icon() - src.updateUsrDialog() return - +//rotates the panel to the passed angle /obj/machinery/power/solar_control/proc/set_panels(var/cdir) - if(!powernet) return - for(var/obj/machinery/power/solar/S in get_solars_powernet()) - if(powernet.nodes[S]) - if(get_dist(S, src) < SOLAR_MAX_DIST) - if(!S.control) - S.control = src - S.ndir = cdir + + for(var/obj/machinery/power/solar/S in connected_panels) + S.adir = cdir //instantly rotates the panel + S.occlusion()//and + S.update_icon() //update it + + update_icon() /obj/machinery/power/solar_control/power_change() - if(powered()) - stat &= ~NOPOWER - update_icon() - else - spawn(rand(0, 15)) - stat |= NOPOWER - update_icon() + ..() + update_icon() /obj/machinery/power/solar_control/proc/broken() @@ -511,25 +499,16 @@ Manual Tracking Direction:"} update_icon() -/obj/machinery/power/solar_control/meteorhit() - broken() - return - - -/obj/machinery/power/solar_control/ex_act(severity) - switch(severity) - if(1.0) - //SN src = null - qdel(src) - return - if(2.0) - if (prob(50)) - broken() - if(3.0) - if (prob(25)) - broken() - return - +/obj/machinery/power/solar_control/ex_act(severity, target) + ..() + if(!gc_destroyed) + switch(severity) + if(2) + if(prob(50)) + broken() + if(3) + if(prob(25)) + broken() /obj/machinery/power/solar_control/blob_act() if (prob(75)) @@ -543,4 +522,4 @@ Manual Tracking Direction:"} /obj/item/weapon/paper/solar name = "paper- 'Going green! Setup your own solar array instructions.'" - info = "

Welcome

At greencorps we love the environment, and space. With this package you are able to help mother nature and produce energy without any usage of fossil fuel or plasma! Singularity energy is dangerous while solar energy is safe, which is why it's better. Now here is how you setup your own solar array.

You can make a solar panel by wrenching the solar assembly onto a cable node. Adding a glass panel, reinforced or regular glass will do, will finish the construction of your solar panel. It is that easy!.

Now after setting up 19 more of these solar panels you will want to create a solar tracker to keep track of our mother nature's gift, the sun. These are the same steps as before except you insert the tracker equipment circuit into the assembly before performing the final step of adding the glass. You now have a tracker! Now the last step is to add a computer to calculate the sun's movements and to send commands to the solar panels to change direction with the sun. Setting up the solar computer is the same as setting up any computer, so you should have no trouble in doing that. You do need to put a wire node under the computer, and the wire needs to be connected to the tracker.

Congratulations, you should have a working solar array. If you are having trouble, here are some tips. Make sure all solar equipment are on a cable node, even the computer. You can always deconstruct your creations if you make a mistake.

That's all to it, be safe, be green!

" + info = "

Welcome

At greencorps we love the environment, and space. With this package you are able to help mother nature and produce energy without any usage of fossil fuel or plasma! Singularity energy is dangerous while solar energy is safe, which is why it's better. Now here is how you setup your own solar array.

You can make a solar panel by wrenching the solar assembly onto a cable node. Adding a glass panel, reinforced or regular glass will do, will finish the construction of your solar panel. It is that easy!

Now after setting up 19 more of these solar panels you will want to create a solar tracker to keep track of our mother nature's gift, the sun. These are the same steps as before except you insert the tracker equipment circuit into the assembly before performing the final step of adding the glass. You now have a tracker! Now the last step is to add a computer to calculate the sun's movements and to send commands to the solar panels to change direction with the sun. Setting up the solar computer is the same as setting up any computer, so you should have no trouble in doing that. You do need to put a wire node under the computer, and the wire needs to be connected to the tracker.

Congratulations, you should have a working solar array. If you are having trouble, here are some tips. Make sure all solar equipment are on a cable node, even the computer. You can always deconstruct your creations if you make a mistake.

That's all to it, be safe, be green!

" \ No newline at end of file diff --git a/code/modules/power/tracker.dm b/code/modules/power/tracker.dm index d35cf81ed45..5cf341f9fbb 100644 --- a/code/modules/power/tracker.dm +++ b/code/modules/power/tracker.dm @@ -10,78 +10,70 @@ icon_state = "tracker" anchored = 1 density = 1 - directwired = 1 use_power = 0 + var/id = 0 var/sun_angle = 0 // sun angle as set by sun datum + var/obj/machinery/power/solar_control/control = null /obj/machinery/power/tracker/New(var/turf/loc, var/obj/item/solar_assembly/S) ..(loc) + Make(S) + connect_to_network() + +/obj/machinery/power/tracker/Destroy() + unset_control() //remove from control computer + ..() + +//set the control of the tracker to a given computer if closer than SOLAR_MAX_DIST +/obj/machinery/power/tracker/proc/set_control(var/obj/machinery/power/solar_control/SC) + if(!SC || (get_dist(src, SC) > SOLAR_MAX_DIST)) + return 0 + control = SC + SC.connected_tracker = src + return 1 + +//set the control of the tracker to null and removes it from the previous control computer if needed +/obj/machinery/power/tracker/proc/unset_control() + if(control) + control.connected_tracker = null + control = null + +/obj/machinery/power/tracker/proc/Make(var/obj/item/solar_assembly/S) if(!S) S = new /obj/item/solar_assembly(src) S.glass_type = /obj/item/stack/sheet/glass S.tracker = 1 S.anchored = 1 S.loc = src - connect_to_network() + update_icon() -/obj/machinery/power/tracker/disconnect_from_network() - ..() - solars_list.Remove(src) - -/obj/machinery/power/tracker/connect_to_network() - ..() - solars_list.Add(src) - -// called by datum/sun/calc_position() as sun's angle changes +//updates the tracker icon and the facing angle for the control computer /obj/machinery/power/tracker/proc/set_angle(var/angle) sun_angle = angle //set icon dir to show sun illumination dir = turn(NORTH, -angle - 22.5) // 22.5 deg bias ensures, e.g. 67.5-112.5 is EAST - // check we can draw power - if(stat & NOPOWER) - return - - // find all solar controls and update them - // currently, just update all controllers in world - // ***TODO: better communication system using network - if(powernet) - for(var/obj/machinery/power/solar_control/C in get_solars_powernet()) - if(powernet.nodes[C]) - if(get_dist(C, src) < SOLAR_MAX_DIST) - C.tracker_update(angle) - + if(powernet && (powernet == control.powernet)) //update if we're still in the same powernet + control.cdir = angle /obj/machinery/power/tracker/attackby(var/obj/item/weapon/W, var/mob/user) - if(iscrowbar(W)) - playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) + if(istype(W, /obj/item/weapon/crowbar)) + playsound(src.loc, 'sound/machines/click.ogg', 50, 1) + user.visible_message("[user] begins to take the glass off the solar tracker.") if(do_after(user, 50)) var/obj/item/solar_assembly/S = locate() in src if(S) S.loc = src.loc S.give_glass() - playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) + playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) user.visible_message("[user] takes the glass off the tracker.") - del(src) + qdel(src) return ..() -// timed process -// make sure we can draw power from the powernet -/obj/machinery/power/tracker/process() - - var/avail = surplus() - - if(avail > 500) - add_load(500) - stat &= ~NOPOWER - else - stat |= NOPOWER - - // Tracker Electronic /obj/item/weapon/tracker_electronics diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index d8a4ef3f1bf..b030faa14d6 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -26,6 +26,7 @@ var/list/broken_requirements = list() var/broken_on_spawn = 0 var/recharge_delay = 15 + var/image/icon_beaker = null //cached overlay /obj/machinery/chem_dispenser/proc/recharge() @@ -59,6 +60,7 @@ dispensable_reagents = sortList(dispensable_reagents) if(broken_on_spawn) + overlays.Cut() var/amount = pick(3,3,4) var/list/options = list() options[/obj/item/weapon/stock_parts/capacitor/adv] = "Add an advanced capacitor to fix it." @@ -181,8 +183,7 @@ var/obj/item/weapon/reagent_containers/glass/B = beaker B.loc = loc beaker = null - if(!panel_open) - icon_state = initial(icon_state) + overlays.Cut() add_fingerprint(usr) return 1 // update UIs attached to this object @@ -211,7 +212,10 @@ B.loc = src user << "You set [B] on the machine." nanomanager.update_uis(src) // update all UIs attached to src - icon_state = "[initial(icon_state)]2" + if(!icon_beaker) + icon_beaker = image('icons/obj/chemical.dmi', src, "disp_beaker") //randomize beaker overlay position. + icon_beaker.pixel_x = rand(-10,5) + overlays += icon_beaker return /obj/machinery/chem_dispenser/attackby(var/obj/item/weapon/B as obj, var/mob/user as mob) diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index 23ae6ce02b1..afe56a4f731 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -67,14 +67,14 @@ var/datum/reagents/R = reagent_list[reagent_list.len] R.add_reagent(reagent, 30) -/obj/item/weapon/reagent_containers/borghypo/attack(mob/M as mob, mob/user as mob) +/obj/item/weapon/reagent_containers/borghypo/attack(mob/living/M as mob, mob/user as mob) var/datum/reagents/R = reagent_list[mode] if(!R.total_volume) user << "\red The injector is empty." return - if (!( istype(M, /mob) )) + if (!(istype(M))) return - if (R.total_volume) + if (R.total_volume && M.can_inject(user,1)) user << "\blue You inject [M] with the injector." M << "\red You feel a tiny prick!" diff --git a/code/modules/reagents/reagent_containers/food/snacks/meat.dm b/code/modules/reagents/reagent_containers/food/snacks/meat.dm index d0c0e707c36..8809ddc6468 100644 --- a/code/modules/reagents/reagent_containers/food/snacks/meat.dm +++ b/code/modules/reagents/reagent_containers/food/snacks/meat.dm @@ -35,3 +35,7 @@ /obj/item/weapon/reagent_containers/food/snacks/meat/corgi name = "Corgi meat" desc = "Tastes like... well you know..." + +/obj/item/weapon/reagent_containers/food/snacks/meat/pug + name = "Pug meat" + desc = "Tastes like... well you know..." \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 4f1b8140531..ee8b39ce66b 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -226,7 +226,7 @@ name = "large beaker" desc = "A large beaker. Can hold up to 100 units." icon_state = "beakerlarge" - g_amt = 5000 + g_amt = 2500 volume = 100 amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,25,30,50,100) diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index a129dde7472..cd3acea26fe 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -230,7 +230,7 @@ name = "Metal" id = "metal" build_type = AUTOLATHE - materials = list("$metal" = MINERAL_MATERIAL_AMOUNT) + materials = list("$metal" = 3750) build_path = /obj/item/stack/sheet/metal category = list("initial","Construction") @@ -254,7 +254,7 @@ name = "Reinforced Glass" id = "rglass" build_type = AUTOLATHE - materials = list("$metal" = 1000, "$glass" = MINERAL_MATERIAL_AMOUNT) + materials = list("$metal" = 1875, "$glass" = MINERAL_MATERIAL_AMOUNT) build_path = /obj/item/stack/sheet/rglass category = list("initial","Construction") @@ -262,7 +262,7 @@ name = "Metal Rod" id = "rods" build_type = AUTOLATHE - materials = list("$metal" = 1000) + materials = list("$metal" = 1875) build_path = /obj/item/stack/rods category = list("initial","Construction") @@ -440,7 +440,7 @@ id = "handcuffs" build_type = AUTOLATHE materials = list("$metal" = 500) - build_path = /obj/item/weapon/handcuffs + build_path = /obj/item/weapon/restraints/handcuffs category = list("hacked", "Security") /datum/design/incendiary_slug diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 3c4469f1859..d22d31ceeae 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -52,7 +52,7 @@ req_tech = list("programming" = 2, "biotech" = 2, "magnets" = 2) build_type = PROTOLATHE materials = list("$metal" = 30, "$glass" = 20) - reliability_base = 74 + reliability_base = 76 build_path = /obj/item/device/robotanalyzer category = list("Medical") @@ -77,6 +77,17 @@ build_path = /obj/item/weapon/implantcase/freedom category = list("Medical") +/datum/design/sensor_device + name = "Handheld Crew Monitor" + desc = "A device for tracking crew members on the station." + id = "sensor_device" + req_tech = list("biotech" = 4, "magnets" = 3, "materials" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 30, "$glass" = 20) + reliability_base = 76 + build_path = /obj/item/device/sensor_device + category = list("Medical") + /datum/design/implanter name = "Implanter" desc = "A basic implanter for injecting implants" diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 90e7ff47ace..94db17abdc4 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -130,8 +130,8 @@ won't update every console in existence) but it's more of a hassle to do. Also, files.known_tech=files.possible_tech for(var/datum/tech/KT in files.known_tech) if(KT.level < KT.max_level) - KT.level=KT.max_level - + KT.level=KT.max_level + /obj/machinery/computer/rdconsole/New() ..() files = new /datum/research(src) //Setup the research data holder. @@ -165,16 +165,17 @@ won't update every console in existence) but it's more of a hassle to do. Also, user.drop_item() D.loc = src user << " You add the disk to the machine!" - else if(istype(D,/obj/item/weapon/card/emag)) - if(!emagged) - playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) - emagged = 1 - user << "You you disable the security protocols" else ..() src.updateUsrDialog() return +/obj/machinery/computer/rdconsole/emag_act(user as mob) + if(!emagged) + playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) + emagged = 1 + user << "You disable the security protocols" + /obj/machinery/computer/rdconsole/Topic(href, href_list) if(..()) return @@ -207,7 +208,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, t_disk = null screen = 1.0 - else if(href_list["copy_tech"]) //Copys some technology data from the research holder to the disk. + else if(href_list["copy_tech"]) //Copy some technology data from the research holder to the disk. for(var/datum/tech/T in files.known_tech) if(href_list["copy_tech_ID"] == T.id) t_disk.stored = T @@ -249,11 +250,12 @@ won't update every console in existence) but it's more of a hassle to do. Also, linked_destroy.loaded_item = null linked_destroy.icon_state = "d_analyzer" screen = 2.1 - + else if(href_list["maxresearch"]) //Eject the item inside the destructive analyzer. if(!usr.client.holder) return + if(usr.client.holder & R_MENTOR) return screen = 0.0 - if(alert("Are you sure you want to maximize research levels?","Confirmation","Yes","No")=="No") + if(alert("Are you sure you want to maximize research levels?","Confirmation","Yes","No")=="No") return log_admin("[key_name(usr)] has maximized the research levels.") message_admins("[key_name_admin(usr)] has maximized the research levels.") @@ -261,7 +263,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, Maximize() screen = 1.0 updateUsrDialog() - griefProtection() //Update centcomm too + griefProtection() //Update centcomm too else if(href_list["deconstruct"]) //Deconstruct the item in the destructive analyzer and update the research holder. if(linked_destroy) @@ -371,6 +373,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, if(being_built) var/power = 2000 var/amount=text2num(href_list["amount"]) + var/old_screen = screen amount = max(1, min(10, amount)) for(var/M in being_built.materials) power += round(being_built.materials[M] * amount / 5) @@ -436,7 +439,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, else new_item.loc = linked_lathe.loc linked_lathe.busy = 0 - screen = 3.15 + screen = old_screen updateUsrDialog() else if(href_list["imprint"]) //Causes the Circuit Imprinter to build something. @@ -450,6 +453,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, break if(being_built) var/power = 2000 + var/old_screen = screen for(var/M in being_built.materials) power += round(being_built.materials[M] / 5) power = max(2000, power) @@ -488,7 +492,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, new_item.reliability = R new_item.loc = linked_imprinter.loc linked_imprinter.busy = 0 - screen = 4.1 + screen = old_screen updateUsrDialog() else if(href_list["disposeI"] && linked_imprinter) //Causes the circuit imprinter to dispose of a single reagent (all of it) @@ -590,7 +594,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, spawn(20) screen = 1.6 updateUsrDialog() - + else if(href_list["search"]) //Search for designs with name matching pattern var/compare @@ -608,7 +612,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, continue if(findtext(D.name,href_list["to_search"])) matching_designs.Add(D) - + updateUsrDialog() return @@ -870,7 +874,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, dat += " | LOCKED" dat += "
" dat += "
" - + if(3.17) //Display search result dat += "Main Menu" dat += "Protolathe Menu" @@ -978,7 +982,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, dat += "

Circuit Imprinter Menu:


" dat += "Material Amount: [linked_imprinter.TotalMaterials()]
" dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]
" - + dat += "
\ \ \ @@ -1016,7 +1020,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, if(D.locked) dat += " | LOCKED" dat += "
" - + if(4.17) dat += "Main Menu" dat += "Circuit Imprinter Menu" diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index 109ab110d71..f6e00bc69b4 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -319,14 +319,12 @@ onclose(user, "server_control") return -/obj/machinery/computer/rdservercontrol/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob) - if(istype(D, /obj/item/weapon/card/emag) && !emagged) +/obj/machinery/computer/rdservercontrol/emag_act(user as mob) + if(!emagged) playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) emagged = 1 user << "\blue You you disable the security protocols" src.updateUsrDialog() - return ..() - /obj/machinery/r_n_d/server/robotics name = "Robotics R&D Server" diff --git a/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm b/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm index d770c0def1d..566e2382947 100644 --- a/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm +++ b/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm @@ -51,7 +51,7 @@ /obj/item/weapon/stock_parts/cell,\ /obj/item/weapon/circular_saw,\ /obj/item/weapon/hatchet,\ - /obj/item/weapon/handcuffs,\ + /obj/item/weapon/restraints/handcuffs,\ /obj/item/weapon/hemostat,\ /obj/item/weapon/kitchenknife,\ /obj/item/weapon/lighter,\ diff --git a/code/modules/research/xenoarchaeology/finds/finds.dm b/code/modules/research/xenoarchaeology/finds/finds.dm index e2b4215128b..6b07fbb16a9 100644 --- a/code/modules/research/xenoarchaeology/finds/finds.dm +++ b/code/modules/research/xenoarchaeology/finds/finds.dm @@ -183,12 +183,12 @@ apply_image_decorations = 1 if(8) item_type = "handcuffs" - new_item = new /obj/item/weapon/handcuffs(src.loc) + new_item = new /obj/item/weapon/restraints/handcuffs(src.loc) additional_desc = "[pick("They appear to be for securing two things together","Looks kinky","Doesn't seem like a children's toy")]." if(9) item_type = "[pick("wicked","evil","byzantine","dangerous")] looking [pick("device","contraption","thing","trap")]" apply_prefix = 0 - new_item = new /obj/item/weapon/legcuffs/beartrap(src.loc) + new_item = new /obj/item/weapon/restraints/legcuffs/beartrap(src.loc) additional_desc = "[pick("It looks like it could take a limb off",\ "Could be some kind of animal trap",\ "There appear to be [pick("dark red","dark purple","dark green","dark blue")] stains along part of it")]." diff --git a/code/modules/research/xenoarchaeology/tools/tools_pickaxe.dm b/code/modules/research/xenoarchaeology/tools/tools_pickaxe.dm index 62bd9009603..48a5e0514d4 100644 --- a/code/modules/research/xenoarchaeology/tools/tools_pickaxe.dm +++ b/code/modules/research/xenoarchaeology/tools/tools_pickaxe.dm @@ -10,7 +10,7 @@ digspeed = 20 desc = "Thick metallic wires for clearing away dust and loose scree (1 centimetre excavation depth)." excavation_amount = 0.5 - drill_sound = 'sound/weapons/thudswoosh.ogg' + digsound = list('sound/weapons/thudswoosh.ogg') drill_verb = "brushing" w_class = 2 @@ -22,7 +22,7 @@ digspeed = 20 desc = "A miniature excavation tool for precise digging (2 centimetre excavation depth)." excavation_amount = 1 - drill_sound = 'sound/items/Screwdriver.ogg' + digsound = list('sound/items/Screwdriver.ogg') drill_verb = "delicately picking" w_class = 2 @@ -34,7 +34,7 @@ digspeed = 20 desc = "A miniature excavation tool for precise digging (4 centimetre excavation depth)." excavation_amount = 2 - drill_sound = 'sound/items/Screwdriver.ogg' + digsound = list('sound/items/Screwdriver.ogg') drill_verb = "delicately picking" w_class = 2 @@ -46,7 +46,7 @@ digspeed = 20 desc = "A miniature excavation tool for precise digging (6 centimetre excavation depth)." excavation_amount = 3 - drill_sound = 'sound/items/Screwdriver.ogg' + digsound = list('sound/items/Screwdriver.ogg') drill_verb = "delicately picking" w_class = 2 @@ -58,7 +58,7 @@ digspeed = 20 desc = "A miniature excavation tool for precise digging (8 centimetre excavation depth)." excavation_amount = 4 - drill_sound = 'sound/items/Screwdriver.ogg' + digsound = list('sound/items/Screwdriver.ogg') drill_verb = "delicately picking" w_class = 2 @@ -70,7 +70,7 @@ digspeed = 20 desc = "A miniature excavation tool for precise digging (10 centimetre excavation depth)." excavation_amount = 5 - drill_sound = 'sound/items/Screwdriver.ogg' + digsound = list('sound/items/Screwdriver.ogg') drill_verb = "delicately picking" w_class = 2 @@ -82,7 +82,7 @@ digspeed = 20 desc = "A miniature excavation tool for precise digging (12 centimetre excavation depth)." excavation_amount = 6 - drill_sound = 'sound/items/Screwdriver.ogg' + digsound = list('sound/items/Screwdriver.ogg') drill_verb = "delicately picking" w_class = 2 @@ -94,7 +94,7 @@ digspeed = 30 desc = "A smaller, more precise version of the pickaxe (30 centimetre excavation depth)." excavation_amount = 15 - drill_sound = 'sound/items/Crowbar.ogg' + digsound = list('sound/items/Crowbar.ogg') drill_verb = "clearing" w_class = 3 diff --git a/code/modules/security levels/security levels.dm b/code/modules/security levels/security levels.dm index b85d9589209..5ac35d1188e 100644 --- a/code/modules/security levels/security levels.dm +++ b/code/modules/security levels/security levels.dm @@ -7,6 +7,8 @@ //5 = code delta //config.alert_desc_blue_downto +/var/datum/announcement/priority/security/security_announcement_up = new(do_log = 0, do_newscast = 1, new_sound = sound('sound/misc/notice1.ogg')) +/var/datum/announcement/priority/security/security_announcement_down = new(do_log = 0, do_newscast = 1) /proc/set_security_level(var/level) switch(level) @@ -27,40 +29,35 @@ if(level >= SEC_LEVEL_GREEN && level <= SEC_LEVEL_DELTA && level != security_level) switch(level) if(SEC_LEVEL_GREEN) - world << "Attention! Security level lowered to green." - world << "All threats to the station have passed. All weapons need to be holstered and privacy laws are once again fully enforced." + security_announcement_down.Announce("All threats to the station have passed. All weapons need to be holstered and privacy laws are once again fully enforced.","Attention! Security level lowered to green.") security_level = SEC_LEVEL_GREEN for(var/obj/machinery/firealarm/FA in world) - if(FA.z == 1 || FA.z == 5) + if((FA.z in config.contact_levels)) FA.overlays = list() FA.overlays += image('icons/obj/monitors.dmi', "overlay_green") if(SEC_LEVEL_BLUE) if(security_level < SEC_LEVEL_BLUE) - world << "Attention! Security level elevated to blue." - world << "The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible and random searches are permitted." + security_announcement_up.Announce("The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible and random searches are permitted.","Attention! Security level elevated to blue.") else - world << "Attention! Security level lowered to blue." - world << "The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed." + security_announcement_down.Announce("The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed.","Attention! Security level lowered to blue.") security_level = SEC_LEVEL_BLUE for(var/obj/machinery/firealarm/FA in world) - if(FA.z == 1 || FA.z == 5) + if((FA.z in config.contact_levels)) FA.overlays = list() FA.overlays += image('icons/obj/monitors.dmi', "overlay_blue") if(SEC_LEVEL_RED) if(security_level < SEC_LEVEL_RED) - world << "Attention! Code Red!" - world << "There is an immediate and serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised. The station's secure armory has been unlocked and is ready for use." + security_announcement_up.Announce("There is an immediate and serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised.","Attention! Code Red!") else - world << "Attention! Code Red!" - world << "The station's self-destruct mechanism has been deactivated, but there is still an immediate and serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised." + security_announcement_down.Announce("The station's self-destruct mechanism has been deactivated, but there is still an immediate and serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised.","Attention! Code Red!") security_level = SEC_LEVEL_RED var/obj/machinery/door/airlock/highsecurity/red/R = locate(/obj/machinery/door/airlock/highsecurity/red) in world - if(R && R.z == 1) + if(R && (R.z in config.station_levels)) R.locked = 0 R.update_icon() @@ -69,25 +66,24 @@ CC.post_status("alert", "redalert") for(var/obj/machinery/firealarm/FA in world) - if(FA.z == 1 || FA.z == 5) + if((FA.z in config.contact_levels)) FA.overlays = list() FA.overlays += image('icons/obj/monitors.dmi', "overlay_red") if(SEC_LEVEL_GAMMA) - world << "Attention! Gamma security level activated!" - world << "Central Command has ordered the Gamma security level on the station. Security is to have weapons equipped at all times, and all civilians are to immediately seek their nearest head for transportation to a secure location. The station's Gamma armory has been unlocked and is ready for use." + security_announcement_up.Announce("Central Command has ordered the Gamma security level on the station. Security is to have weapons equipped at all times, and all civilians are to immediately seek their nearest head for transportation to a secure location. The station's Gamma armory has been unlocked and is ready for use.","Attention! Gamma security level activated!") security_level = SEC_LEVEL_GAMMA move_gamma_ship() if(security_level < SEC_LEVEL_RED) for(var/obj/machinery/door/airlock/highsecurity/red/R in world) - if(R.z == 1) + if((R.z in config.station_levels)) R.locked = 0 R.update_icon() for(var/obj/machinery/door/airlock/hatch/gamma/H in world) - if(H.z == 1) + if((H.z in config.station_levels)) H.locked = 0 H.update_icon() @@ -96,14 +92,13 @@ CC.post_status("alert", "redalert") for(var/obj/machinery/firealarm/FA in world) - if(FA.z == 1 || FA.z == 5) + if((FA.z in config.contact_levels)) FA.overlays = list() FA.overlays += image('icons/obj/monitors.dmi', "overlay_gamma") FA.update_icon() if(SEC_LEVEL_EPSILON) - world << "Attention! Epsilon security level activated!" - world << "Central Command has ordered the Epsilon security level on the station. Consider all contracts terminated." + security_announcement_up.Announce("Central Command has ordered the Epsilon security level on the station. Consider all contracts terminated.","Attention! Epsilon security level activated!") security_level = SEC_LEVEL_EPSILON var/obj/machinery/computer/communications/CC = locate(/obj/machinery/computer/communications,world) @@ -111,13 +106,12 @@ CC.post_status("alert", "redalert") for(var/obj/machinery/firealarm/FA in world) - if(FA.z == 1 || FA.z == 5) + if((FA.z in config.contact_levels)) FA.overlays = list() FA.overlays += image('icons/obj/monitors.dmi', "overlay_epsilon") if(SEC_LEVEL_DELTA) - world << "Attention! Delta security level reached!" - world << "The station's self-destruct mechanism has been engaged. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill." + security_announcement_up.Announce("The station's self-destruct mechanism has been engaged. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill.","Attention! Delta security level reached!") security_level = SEC_LEVEL_DELTA var/obj/machinery/computer/communications/CC = locate(/obj/machinery/computer/communications,world) @@ -125,7 +119,7 @@ CC.post_status("alert", "redalert") for(var/obj/machinery/firealarm/FA in world) - if(FA.z == 1 || FA.z == 5) + if((FA.z in config.contact_levels)) FA.overlays = list() FA.overlays += image('icons/obj/monitors.dmi', "overlay_delta") diff --git a/code/modules/shuttles/escape_pods.dm b/code/modules/shuttles/escape_pods.dm index 0261997a9d3..17a97b79fe7 100644 --- a/code/modules/shuttles/escape_pods.dm +++ b/code/modules/shuttles/escape_pods.dm @@ -89,19 +89,14 @@ ui.open() ui.set_auto_update(1) -/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/card/emag) && !emagged) +/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/emag_act(user as mob) + if (!emagged) user << "\blue You emag the [src], arming the escape pod!" emagged = 1 if (istype(docking_program, /datum/computer/file/embedded_program/docking/simple/escape_pod)) var/datum/computer/file/embedded_program/docking/simple/escape_pod/P = docking_program if (!P.armed) P.arm() - return - - ..() - - //A docking controller program for a simple door based docking port /datum/computer/file/embedded_program/docking/simple/escape_pod diff --git a/code/modules/shuttles/shuttle_console.dm b/code/modules/shuttles/shuttle_console.dm index f1ca624e73b..e6e7a8d4112 100644 --- a/code/modules/shuttles/shuttle_console.dm +++ b/code/modules/shuttles/shuttle_console.dm @@ -97,15 +97,11 @@ return shuttle.cancel_launch(user) -/obj/machinery/computer/shuttle_control/attackby(obj/item/weapon/W as obj, mob/user as mob) - - if (istype(W, /obj/item/weapon/card/emag)) - src.req_access = list() - src.req_one_access = list() - hacked = 1 - usr << "You short out the console's ID checking system. It's now available to everyone!" - else - ..() +/obj/machinery/computer/shuttle_control/emag_act(user as mob) + src.req_access = list() + src.req_one_access = list() + hacked = 1 + usr << "You short out the console's ID checking system. It's now available to everyone!" /obj/machinery/computer/shuttle_control/bullet_act(var/obj/item/projectile/Proj) visible_message("[Proj] ricochets off [src]!") diff --git a/code/modules/shuttles/shuttle_emergency.dm b/code/modules/shuttles/shuttle_emergency.dm index b5268fd2ca5..398bc9f9259 100644 --- a/code/modules/shuttles/shuttle_emergency.dm +++ b/code/modules/shuttles/shuttle_emergency.dm @@ -26,9 +26,9 @@ emergency_shuttle.departed = 1 if (emergency_shuttle.evac) - captain_announce("The Emergency Shuttle has left the station. Estimate [round(emergency_shuttle.estimate_arrival_time()/60,1)] minutes until the shuttle docks at Central Command.") + priority_announcement.Announce("The Emergency Shuttle has left the station. Estimate [round(emergency_shuttle.estimate_arrival_time()/60,1)] minutes until the shuttle docks at Central Command.") else - captain_announce("The Crew Transfer Shuttle has left the station. Estimate [round(emergency_shuttle.estimate_arrival_time()/60,1)] minutes until the shuttle docks at Central Command.") + priority_announcement.Announce("The Crew Transfer Shuttle has left the station. Estimate [round(emergency_shuttle.estimate_arrival_time()/60,1)] minutes until the shuttle docks at Central Command.") ..(origin, destination) @@ -153,14 +153,15 @@ /obj/machinery/computer/shuttle_control/emergency/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/card/emag) && !emagged) + read_authorization(W) + ..() + +/obj/machinery/computer/shuttle_control/emergency/emag_act(user as mob) + if (!emagged) user << "\blue You short out the [src]'s authorization protocols." emagged = 1 return - read_authorization(W) - ..() - /obj/machinery/computer/shuttle_control/emergency/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) var/data[0] var/datum/shuttle/ferry/emergency/shuttle = shuttle_controller.shuttles[shuttle_tag] diff --git a/code/modules/shuttles/shuttles_multi.dm b/code/modules/shuttles/shuttles_multi.dm index 3a73cafb58f..bac0384a4d3 100644 --- a/code/modules/shuttles/shuttles_multi.dm +++ b/code/modules/shuttles/shuttles_multi.dm @@ -33,14 +33,14 @@ if(cloaked || isnull(departure_message)) return - command_alert(departure_message,(announcer ? announcer : "Central Command")) + command_announcement.Announce(departure_message,(announcer ? announcer : "Central Command")) /datum/shuttle/multi_shuttle/proc/announce_arrival() if(cloaked || isnull(arrival_message)) return - command_alert(arrival_message,(announcer ? announcer : "Central Command")) + command_announcement.Announce(arrival_message,(announcer ? announcer : "Central Command")) /obj/machinery/computer/shuttle_control/multi icon_state = "syndishuttle" diff --git a/code/modules/store/store.dm b/code/modules/store/store.dm index 02a50c1b31a..41df9937fab 100644 --- a/code/modules/store/store.dm +++ b/code/modules/store/store.dm @@ -48,7 +48,7 @@ var/global/datum/store/centcomm_store=new /datum/store/proc/reconnect_database() for(var/obj/machinery/account_database/DB in world) - if(DB.z == 1) + if((DB.z in config.station_levels)) linked_db = DB break diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 07d5f7df40a..991e1714587 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -90,7 +90,8 @@ proc/do_surgery(mob/living/M, mob/living/user, obj/item/tool) if( prob(S.tool_quality(tool)) && do_mob(user, M, rand(S.min_duration, S.max_duration))) S.end_step(user, M, user.zone_sel.selecting, tool) //finish successfully else //or - S.fail_step(user, M, user.zone_sel.selecting, tool) //malpractice~ + if(!isrobot(user)) + S.fail_step(user, M, user.zone_sel.selecting, tool) //malpractice~ return 1 //don't want to do weapony things after surgery return 0 diff --git a/code/modules/telesci/telepad.dm b/code/modules/telesci/telepad.dm index 21283526863..42ee7f3786f 100644 --- a/code/modules/telesci/telepad.dm +++ b/code/modules/telesci/telepad.dm @@ -147,11 +147,12 @@ playsound(src.loc, 'sound/effects/pop.ogg', 50, 0) user << " You calibrate the telepad locator." -/obj/item/weapon/rcs/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/weapon/card/emag) && emagged == 0) +/obj/item/weapon/rcs/emag_act(user as mob) + if(!emagged) emagged = 1 var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(5, 1, src) s.start() user << " You emag the RCS. Click on it to toggle between modes." - return \ No newline at end of file + return + \ No newline at end of file diff --git a/code/modules/telesci/telesci_computer.dm b/code/modules/telesci/telesci_computer.dm index a5eb05096fc..9e82bef312a 100644 --- a/code/modules/telesci/telesci_computer.dm +++ b/code/modules/telesci/telesci_computer.dm @@ -55,12 +55,6 @@ return /obj/machinery/computer/telescience/attackby(obj/item/W, mob/user) - if(istype(W,/obj/item/weapon/card/emag)) - if (emagged == 0) - user << "\blue You scramble the Telescience authentication key to an unknown signal. You should be able to teleport to more places now!" - emagged = 1 - else - user << "\red The machine seems unaffected by the card swipe..." if(istype(W, /obj/item/bluespace_crystal)) if(crystals.len >= max_crystals) user << "There are not enough crystal slots." @@ -86,6 +80,13 @@ updateUsrDialog() else ..() + +/obj/machinery/computer/telescience/emag_act(user as mob) + if (!emagged) + user << "\blue You scramble the Telescience authentication key to an unknown signal. You should be able to teleport to more places now!" + emagged = 1 + else + user << "\red The machine seems unaffected by the card swipe..." /obj/machinery/computer/telescience/attack_ai(mob/user) src.attack_hand(user) diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm index c2250225e05..3af09357ca5 100644 --- a/code/modules/vehicles/vehicle.dm +++ b/code/modules/vehicles/vehicle.dm @@ -87,8 +87,6 @@ user << "[src] does not need a repair." else user << "Unable to repair while [src] is off." - else if(istype(W, /obj/item/weapon/card/emag) && !emagged) - Emag(user) else if(hasvar(W,"force") && hasvar(W,"damtype")) switch(W.damtype) if("fire") @@ -99,6 +97,10 @@ healthcheck() else ..() + +/obj/vehicle/emag_act(user as mob) + if(!emagged) + Emag(user) /obj/vehicle/attack_animal(var/mob/living/simple_animal/M as mob) if(M.melee_damage_upper == 0) return diff --git a/code/setup.dm b/code/setup.dm index ead10cd6bba..35052478851 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -695,8 +695,9 @@ var/list/TAGGERLOCATIONS = list("Disposals", #define R_SOUNDS 2048 #define R_SPAWN 4096 #define R_MOD 8192 +#define R_MENTOR 16384 -#define R_MAXPERMISSION 8192 //This holds the maximum value for a permission. It is used in iteration, so keep it updated. +#define R_MAXPERMISSION 16384 //This holds the maximum value for a permission. It is used in iteration, so keep it updated. #define R_HOST 65535 @@ -804,7 +805,7 @@ var/list/restricted_camera_networks = list( //Those networks can only be accesse "NukeOps", "Thunderdome", "UO45", - "UO45R", + "UO45R", "Xeno" ) @@ -949,3 +950,9 @@ var/list/hit_appends = list("-OOF", "-ACK", "-UGH", "-HRNK", "-HURGH", "-GLORF") #define SUIT_SENSOR_BINARY 1 #define SUIT_SENSOR_VITAL 2 #define SUIT_SENSOR_TRACKING 3 + +// NanoUI flags +#define STATUS_INTERACTIVE 2 // GREEN Visability +#define STATUS_UPDATE 1 // ORANGE Visability +#define STATUS_DISABLED 0 // RED Visability +#define STATUS_CLOSE -1 // Close the interface diff --git a/config/example/config.txt b/config/example/config.txt index 1a53041a540..a26aa4575d6 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -246,6 +246,18 @@ GHOST_INTERACTION ## Default is "python" on Windows, "/usr/bin/env python2" on UNIX. #PYTHON_PATH pythonw +## Defines which Z-levels the station exists on. +STATION_LEVELS 1 + +## Defines which Z-levels are used for admin functionality, such as Central Command and the Syndicate Shuttle +ADMIN_LEVELS 2 + +## Defines which Z-levels which, for example, a Code Red announcement may affect +CONTACT_LEVELS 1;5 + +## Defines all Z-levels a character can typically reach +PLAYER_LEVELS 1;3;4;5;6 + ## Expected round length in minutes EXPECTED_ROUND_LENGTH 120 diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index f3d08f645c3..0e83c2a3e63 100644 Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index eb984038398..7c7101edd5b 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/custom-synthetic.dmi b/icons/mob/custom-synthetic.dmi index 77cef2656fb..1c61475e89e 100644 Binary files a/icons/mob/custom-synthetic.dmi and b/icons/mob/custom-synthetic.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index f9244eace02..b111df54f9d 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 3f158f68f3f..a3bab9d2eda 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi index 83b8c49d86a..e0e70b2736a 100644 Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index c8a10b1c4da..943095ad7b0 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 574b1817f97..1afe63ffb70 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index a83f398a1b3..d226cf46949 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index 9d85238456b..b85721bcc27 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/maps/RandomZLevels/blackmarketpackers.dmm b/maps/RandomZLevels/blackmarketpackers.dmm index defb234b95b..be1160e8830 100644 --- a/maps/RandomZLevels/blackmarketpackers.dmm +++ b/maps/RandomZLevels/blackmarketpackers.dmm @@ -32,7 +32,7 @@ "aF" = (/turf/simulated/shuttle/wall,/area/awaymission/BMPship/Aft) "aG" = (/obj/structure/stool/bed/roller,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) "aH" = (/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) -"aI" = (/obj/item/weapon/handcuffs,/obj/structure/closet/crate,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) +"aI" = (/obj/item/weapon/restraints/handcuffs,/obj/structure/closet/crate,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) "aJ" = (/obj/item/weapon/scalpel,/obj/structure/closet/crate,/obj/item/weapon/tank/anesthetic,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) "aK" = (/obj/item/bodybag,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) "aL" = (/obj/item/weapon/storage/box/syringes,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) diff --git a/maps/RandomZLevels/centcomAway.dmm b/maps/RandomZLevels/centcomAway.dmm index bc0a122da9f..48080199277 100644 --- a/maps/RandomZLevels/centcomAway.dmm +++ b/maps/RandomZLevels/centcomAway.dmm @@ -155,7 +155,7 @@ "cY" = (/obj/machinery/computer/secure_data,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/awaymission/centcomAway/hangar) "cZ" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/awaymission/centcomAway/hangar) "da" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/awaymission/centcomAway/hangar) -"db" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/obj/item/weapon/stamp,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/awaymission/centcomAway/hangar) +"db" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/obj/item/weapon/stamp/granted,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/awaymission/centcomAway/hangar) "dc" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/window/northright,/turf/simulated/floor{tag = "icon-redfull"; icon_state = "redfull"},/area/awaymission/centcomAway/cafe) "dd" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/awaymission/centcomAway/maint) "de" = (/obj/structure/table,/obj/item/device/flash,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/awaymission/centcomAway/hangar) @@ -516,7 +516,7 @@ "jV" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin,/turf/simulated/floor{icon_state = "dark"},/area/awaymission/centcomAway/general) "jW" = (/obj/machinery/computer/secure_data,/turf/simulated/floor{icon_state = "dark"},/area/awaymission/centcomAway/general) "jX" = (/obj/machinery/computer/card,/turf/simulated/floor{icon_state = "dark"},/area/awaymission/centcomAway/general) -"jY" = (/obj/item/weapon/stamp,/obj/structure/table/reinforced,/turf/simulated/floor{tag = "icon-vault (EAST)"; icon_state = "vault"; dir = 4},/area/awaymission/centcomAway/general) +"jY" = (/obj/item/weapon/stamp/granted,/obj/structure/table/reinforced,/turf/simulated/floor{tag = "icon-vault (EAST)"; icon_state = "vault"; dir = 4},/area/awaymission/centcomAway/general) "jZ" = (/obj/structure/table,/obj/item/weapon/firstaid_arm_assembly,/turf/simulated/floor{tag = "icon-vault"; icon_state = "vault"},/area/awaymission/centcomAway/hangar) "ka" = (/obj/structure/table,/obj/item/device/flash,/obj/item/device/flash,/turf/simulated/floor{tag = "icon-vault"; icon_state = "vault"},/area/awaymission/centcomAway/hangar) "kb" = (/obj/structure/table,/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/turf/simulated/floor{tag = "icon-vault"; icon_state = "vault"},/area/awaymission/centcomAway/hangar) @@ -583,14 +583,14 @@ "lk" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor{icon_state = "floor"},/area/awaymission/centcomAway/general) "ll" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor{icon_state = "floor"},/area/awaymission/centcomAway/general) "lm" = (/obj/machinery/photocopier,/turf/simulated/floor{tag = "icon-vault (EAST)"; icon_state = "vault"; dir = 4},/area/awaymission/centcomAway/general) -"ln" = (/obj/item/weapon/clipboard,/obj/structure/table,/obj/item/device/taperecorder,/obj/item/weapon/stamp,/turf/simulated/floor{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/awaymission/centcomAway/general) +"ln" = (/obj/item/weapon/clipboard,/obj/structure/table,/obj/item/device/taperecorder,/obj/item/weapon/stamp/granted,/turf/simulated/floor{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/awaymission/centcomAway/general) "lo" = (/obj/machinery/door/window/northright{icon_state = "right"; dir = 2},/turf/simulated/floor{icon_state = "floor"},/area/awaymission/centcomAway/general) "lp" = (/obj/structure/table/reinforced,/obj/machinery/door_control{id = "XCCsec2"; name = "XCC Shutter 2 Control"},/turf/simulated/floor{icon_state = "dark"},/area/awaymission/centcomAway/general) "lq" = (/turf/simulated/floor{dir = 8; icon_state = "red"},/area/awaymission/centcomAway/general) "lr" = (/turf/simulated/floor{icon_state = "red"; dir = 10},/area/awaymission/centcomAway/general) "ls" = (/turf/simulated/floor{icon_state = "red"; dir = 2},/area/awaymission/centcomAway/general) "lt" = (/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/awaymission/centcomAway/general) -"lu" = (/obj/structure/table,/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/stamp,/turf/simulated/floor{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/awaymission/centcomAway/general) +"lu" = (/obj/structure/table,/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/stamp/granted,/turf/simulated/floor{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/awaymission/centcomAway/general) "lv" = (/obj/machinery/door/airlock/external,/turf/simulated/floor{icon_state = "red"; dir = 10},/area/awaymission/centcomAway/general) "lw" = (/obj/machinery/door/airlock/external,/turf/simulated/floor{icon_state = "green"; dir = 6},/area/awaymission/centcomAway/general) "lx" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/awaymission/centcomAway/general) @@ -629,7 +629,7 @@ "me" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/awaymission/centcomAway/thunderdome) "mf" = (/obj/structure/stool/bed/chair,/turf/simulated/floor{tag = "icon-redbluefull (WEST)"; icon_state = "redbluefull"; dir = 8},/area/awaymission/centcomAway/thunderdome) "mg" = (/turf/simulated/floor{dir = 8; icon_state = "red"},/area/awaymission/centcomAway/thunderdome) -"mh" = (/obj/structure/rack,/obj/item/weapon/legcuffs/beartrap,/obj/item/weapon/twohanded/fireaxe,/turf/simulated/floor{icon_state = "dark"},/area/awaymission/centcomAway/thunderdome) +"mh" = (/obj/structure/rack,/obj/item/weapon/restraints/legcuffs/beartrap,/obj/item/weapon/twohanded/fireaxe,/turf/simulated/floor{icon_state = "dark"},/area/awaymission/centcomAway/thunderdome) "mi" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/awaymission/centcomAway/thunderdome) "mj" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/awaymission/centcomAway/thunderdome) "mk" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/awaymission/centcomAway/thunderdome) diff --git a/maps/RandomZLevels/challenge.dmm b/maps/RandomZLevels/challenge.dmm index 2804fcfe6a8..697f5f877eb 100644 --- a/maps/RandomZLevels/challenge.dmm +++ b/maps/RandomZLevels/challenge.dmm @@ -119,7 +119,7 @@ "co" = (/turf/simulated/floor/bluegrid,/area/awaymission/challenge/end) "cp" = (/turf/simulated/floor{tag = "icon-vault (WEST)"; icon_state = "vault"; dir = 8},/area/awaymission/challenge/end) "cq" = (/obj/structure/window/reinforced{dir = 8},/turf/space,/area) -"cr" = (/obj/structure/table/woodentable,/obj/item/weapon/melee/chainofcommand,/obj/item/weapon/stamp,/turf/simulated/floor/carpet,/area/awaymission/challenge/end) +"cr" = (/obj/structure/table/woodentable,/obj/item/weapon/melee/chainofcommand,/obj/item/weapon/stamp/granted,/turf/simulated/floor/carpet,/area/awaymission/challenge/end) "cs" = (/obj/structure/table/woodentable,/obj/item/weapon/paper{info = "Congratulations,

Your station has been selected to carry out the Gateway Project.

The equipment will be shipped to you at the start of the next quarter.
You are to prepare a secure location to house the equipment as outlined in the attached documents.

--Nanotrasen Blue Space Research"; name = "Confidential Correspondence, Pg 1"; pixel_x = 0; pixel_y = 0},/obj/item/weapon/folder/blue,/turf/simulated/floor/carpet,/area/awaymission/challenge/end) "ct" = (/obj/structure/table/woodentable,/obj/machinery/light/small/lamp/green{pixel_x = 1; pixel_y = 5},/turf/simulated/floor/carpet,/area/awaymission/challenge/end) "cu" = (/obj/structure/rack,/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced,/turf/simulated/floor/wood,/area/awaymission/challenge/end) diff --git a/maps/RandomZLevels/fileList.txt b/maps/RandomZLevels/fileList.txt index 566dc613557..3c3785c3beb 100644 --- a/maps/RandomZLevels/fileList.txt +++ b/maps/RandomZLevels/fileList.txt @@ -9,7 +9,7 @@ #maps/RandomZLevels/academy.dmm maps/RandomZLevels/beach.dmm -maps/RandomZLevels/blackmarketpackers.dmm +#maps/RandomZLevels/blackmarketpackers.dmm maps/RandomZLevels/challenge.dmm #maps/RandomZLevels/centcomAway.dmm #maps/RandomZLevels/clownplanet.dmm diff --git a/maps/RandomZLevels/spacehotel.dmm b/maps/RandomZLevels/spacehotel.dmm index ebcd1b49470..78fe2b7b35d 100644 --- a/maps/RandomZLevels/spacehotel.dmm +++ b/maps/RandomZLevels/spacehotel.dmm @@ -227,7 +227,7 @@ "es" = (/obj/structure/rack,/obj/item/key,/obj/item/key,/obj/item/key,/obj/item/key,/obj/item/key,/turf/simulated/floor/carpet,/area/awaymission) "et" = (/obj/structure/stool/bed/chair/comfy,/obj/effect/decal/cleanable/flour{desc = "Probably."},/obj/effect/decal/cleanable/pie_smudge,/turf/simulated/floor/carpet,/area/awaymission) "eu" = (/obj/structure/stool/bed/chair/comfy,/obj/effect/decal/cleanable/flour{desc = "Probably."},/obj/effect/decal/cleanable/flour{desc = "Probably."},/obj/effect/decal/cleanable/pie_smudge,/turf/simulated/floor/carpet,/area/awaymission) -"ev" = (/obj/item/weapon/legcuffs,/turf/simulated/floor/engine/cult,/area/awaymission) +"ev" = (/obj/item/weapon/restraints/legcuffs,/turf/simulated/floor/engine/cult,/area/awaymission) "ew" = (/obj/machinery/space_heater,/turf/simulated/floor/carpet,/area/awaymission) "ex" = (/obj/structure/table/woodentable,/turf/simulated/floor/carpet,/area/awaymission) "ey" = (/obj/structure/table,/obj/machinery/computer/security/telescreen{desc = "Not used to spy on hotel rooms."; dir = 1; network = "Hotel"; use_power = 0},/turf/simulated/floor/carpet,/area/awaymission) diff --git a/maps/RandomZLevels/undergroundoutpost45.dmm b/maps/RandomZLevels/undergroundoutpost45.dmm index ac64937fec2..53165c7d8a9 100644 --- a/maps/RandomZLevels/undergroundoutpost45.dmm +++ b/maps/RandomZLevels/undergroundoutpost45.dmm @@ -787,7 +787,7 @@ "pg" = (/obj/item/weapon/storage/secure/safe{pixel_x = 5; pixel_y = -27},/turf/simulated/floor{dir = 5; heat_capacity = 1e+006; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "ph" = (/obj/structure/filingcabinet,/turf/simulated/floor{dir = 10; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "pi" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door_control{desc = "A remote control-switch whichs locks the research division down in the event of a biohazard leak or contamination."; id = "UO45_biohazard"; name = "Biohazard Door Control"; pixel_x = 0; pixel_y = -24; req_access_txt = "201"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) -"pj" = (/obj/structure/closet/secure_closet{icon_broken = "secbroken"; icon_closed = "sec"; icon_locked = "sec1"; icon_off = "secoff"; icon_opened = "secopen"; icon_state = "sec1"; locked = 1; name = "security officer's locker"; req_access_txt = "201"},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 2; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/item/weapon/handcuffs,/obj/item/device/flash,/obj/item/weapon/reagent_containers/spray/pepper,/turf/simulated/floor{dir = 6; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) +"pj" = (/obj/structure/closet/secure_closet{icon_broken = "secbroken"; icon_closed = "sec"; icon_locked = "sec1"; icon_off = "secoff"; icon_opened = "secopen"; icon_state = "sec1"; locked = 1; name = "security officer's locker"; req_access_txt = "201"},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 2; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/item/weapon/restraints/handcuffs,/obj/item/device/flash,/obj/item/weapon/reagent_containers/spray/pepper,/turf/simulated/floor{dir = 6; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "pk" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{broken = 1; heat_capacity = 1e+006; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "pl" = (/obj/structure/flora/kirbyplants{layer = 5},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{dir = 10; heat_capacity = 1e+006; icon_state = "neutral"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) "pm" = (/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "neutralcorner"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) diff --git a/maps/cyberiad.dmm b/maps/cyberiad.dmm index 8d56da4d315..75a770d8900 100644 --- a/maps/cyberiad.dmm +++ b/maps/cyberiad.dmm @@ -560,7 +560,7 @@ "akN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/security/main) "akO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor,/area/security/main) "akP" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable,/turf/simulated/floor/plating,/area/security/main) -"akQ" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table/reinforced,/obj/item/weapon/handcuffs,/obj/item/device/flash,/obj/machinery/light{dir = 8},/obj/structure/disposalpipe/segment,/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/main) +"akQ" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table/reinforced,/obj/item/weapon/restraints/handcuffs,/obj/item/device/flash,/obj/machinery/light{dir = 8},/obj/structure/disposalpipe/segment,/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/main) "akR" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/main) "akS" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor,/area/security/main) "akT" = (/obj/structure/closet/secure_closet/security,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor,/area/security/main) @@ -605,7 +605,7 @@ "alG" = (/turf/simulated/shuttle/wall{icon_state = "swall3"; dir = 2},/area/shuttle/siberia/station) "alH" = (/obj/machinery/computer/shuttle_control/labor_camp,/obj/machinery/embedded_controller/radio/simple_docking_controller{id_tag = "labor_shuttle"; pixel_x = -25; pixel_y = 0; req_one_access_txt = "13"; tag_door = "labor_shuttle_hatch"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/siberia/station) "alI" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/siberia/station) -"alJ" = (/obj/structure/table,/obj/item/weapon/folder/red,/obj/item/weapon/handcuffs,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/siberia/station) +"alJ" = (/obj/structure/table,/obj/item/weapon/folder/red,/obj/item/weapon/restraints/handcuffs,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/siberia/station) "alK" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/security/prisonershuttle) "alL" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/prisonershuttle) "alM" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/security/prisonershuttle) @@ -900,7 +900,7 @@ "arp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/security/prison/cell_block/C) "arq" = (/obj/item/weapon/storage/secure/safe{pixel_x = -23},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) "arr" = (/obj/structure/stool,/turf/simulated/floor/carpet,/area/security/detectives_office) -"ars" = (/obj/structure/table/woodentable,/obj/structure/noticeboard{pixel_x = 30; pixel_y = 0},/obj/item/weapon/book/manual/security_space_law,/obj/item/weapon/handcuffs,/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) +"ars" = (/obj/structure/table/woodentable,/obj/structure/noticeboard{pixel_x = 30; pixel_y = 0},/obj/item/weapon/book/manual/security_space_law,/obj/item/weapon/restraints/handcuffs,/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) "art" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/maintenance/fsmaint) "aru" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/stool,/turf/simulated/floor/plating,/area/maintenance/fsmaint) "arv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/table,/turf/simulated/floor/plating,/area/maintenance/fsmaint) @@ -1308,7 +1308,7 @@ "azh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/carpet,/area/magistrateoffice) "azi" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/structure/stool/bed/chair/comfy/black,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/carpet,/area/magistrateoffice) "azj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/table/reinforced,/obj/item/device/megaphone,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/carpet,/area/magistrateoffice) -"azk" = (/obj/structure/table/reinforced,/obj/machinery/photocopier/faxmachine{department = "Internal Affairs"},/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) +"azk" = (/obj/structure/table/reinforced,/obj/machinery/photocopier/faxmachine{department = "Internal Affairs Office"},/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) "azl" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) "azm" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/effect/landmark/start{name = "Internal Affairs Agent"},/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) "azn" = (/obj/structure/table/reinforced,/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) @@ -3656,8 +3656,8 @@ "bsp" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/port) "bsq" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/port) "bsr" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/port) -"bss" = (/obj/structure/table,/obj/item/clothing/head/soft,/obj/item/weapon/stamp{pixel_x = -3; pixel_y = 3},/obj/item/clothing/head/soft,/turf/simulated/floor,/area/quartermaster/storage) -"bst" = (/obj/structure/table,/obj/item/weapon/hand_labeler,/obj/machinery/requests_console{department = "Cargo Bay"; departmentType = 2; pixel_x = 0; pixel_y = 30},/obj/item/weapon/stamp{pixel_x = -3; pixel_y = 3},/obj/item/weapon/hand_labeler,/turf/simulated/floor,/area/quartermaster/storage) +"bss" = (/obj/structure/table,/obj/item/clothing/head/soft,/obj/item/weapon/stamp/granted{pixel_x = -3; pixel_y = 3},/obj/item/clothing/head/soft,/turf/simulated/floor,/area/quartermaster/storage) +"bst" = (/obj/structure/table,/obj/item/weapon/hand_labeler,/obj/machinery/requests_console{department = "Cargo Bay"; departmentType = 2; pixel_x = 0; pixel_y = 30},/obj/item/weapon/stamp/granted{pixel_x = -3; pixel_y = 3},/obj/item/weapon/hand_labeler,/turf/simulated/floor,/area/quartermaster/storage) "bsu" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/floor,/area/quartermaster/storage) "bsv" = (/obj/machinery/camera{c_tag = "Cargo Bay North"},/obj/structure/closet/secure_closet/cargotech,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor,/area/quartermaster/storage) "bsw" = (/obj/structure/closet/secure_closet/cargotech,/turf/simulated/floor,/area/quartermaster/storage) @@ -3930,7 +3930,7 @@ "bxD" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/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 = "brown"},/area/quartermaster/office) "bxE" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/quartermaster/office) "bxF" = (/obj/structure/disposalpipe/segment{name = "Sorting Office"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor,/area/quartermaster/office) -"bxG" = (/obj/item/weapon/stamp{pixel_x = -3; pixel_y = 3},/obj/item/weapon/stamp/denied{pixel_x = 4; pixel_y = -2},/obj/structure/table,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/floor,/area/quartermaster/office) +"bxG" = (/obj/item/weapon/stamp/granted{pixel_x = -3; pixel_y = 3},/obj/item/weapon/stamp/denied{pixel_x = 4; pixel_y = -2},/obj/structure/table,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/floor,/area/quartermaster/office) "bxH" = (/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/clipboard,/obj/item/weapon/pen/red{pixel_x = 2; pixel_y = 6},/obj/structure/table,/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1},/turf/simulated/floor,/area/quartermaster/office) "bxI" = (/obj/machinery/computer/ordercomp,/obj/item/device/radio/intercom{broadcasting = 0; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/floor,/area/quartermaster/office) "bxJ" = (/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor,/area/quartermaster/office) @@ -4148,7 +4148,7 @@ "bBN" = (/obj/structure/table,/obj/structure/window/reinforced/tinted{dir = 4; icon_state = "twindow"; tag = ""},/obj/item/device/mmi/posibrain,/obj/item/device/robotanalyzer,/turf/simulated/floor{dir = 8; icon_state = "whitecorner"},/area/assembly/robotics) "bBO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "bBP" = (/obj/machinery/door_control{id = "robotics2"; name = "Robotics Lab Shutters Control"; pixel_x = 24; pixel_y = -24; req_access_txt = "29"},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) -"bBQ" = (/obj/structure/table/reinforced,/obj/item/weapon/folder/white,/obj/item/weapon/pen,/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "robotics2"; name = "Robotics Lab Shutters"; opacity = 0},/obj/machinery/door/window/eastright{base_state = "left"; dir = 8; icon_state = "left"; name = "Robotics Desk"; req_access_txt = "47"},/turf/simulated/floor/plating,/area/assembly/robotics) +"bBQ" = (/obj/structure/table/reinforced,/obj/item/weapon/folder/white,/obj/item/weapon/pen,/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "robotics2"; name = "Robotics Lab Shutters"; opacity = 0},/obj/machinery/door/window/eastright{base_state = "left"; dir = 8; icon_state = "left"; name = "Robotics Desk"; req_access_txt = "47"},/turf/simulated/floor/plating,/area/assembly/robotics) "bBR" = (/obj/machinery/light{dir = 8},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{dir = 2; icon_state = "whitecorner"},/area/medical/research{name = "Research Division"}) "bBS" = (/obj/effect/landmark{name = "lightsout"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "whitehall"; dir = 2},/area/medical/research{name = "Research Division"}) "bBT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{dir = 8; icon_state = "whitecorner"},/area/medical/research{name = "Research Division"}) @@ -4637,7 +4637,7 @@ "bLi" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/quartermaster/qm) "bLj" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/device/megaphone,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/quartermaster/qm) "bLk" = (/obj/structure/table,/obj/item/weapon/folder/yellow,/obj/item/weapon/pen{pixel_x = 4; pixel_y = 4},/obj/item/weapon/pen/red{pixel_x = 2; pixel_y = 6},/turf/simulated/floor,/area/quartermaster/qm) -"bLl" = (/obj/structure/table,/obj/item/weapon/clipboard,/obj/item/weapon/stamp{name = "Quartermaster's stamp"; pixel_x = 0; pixel_y = 0},/turf/simulated/floor,/area/quartermaster/qm) +"bLl" = (/obj/structure/table,/obj/item/weapon/clipboard,/obj/item/weapon/stamp/granted{name = "Quartermaster's stamp"; pixel_x = 0; pixel_y = 0},/turf/simulated/floor,/area/quartermaster/qm) "bLm" = (/obj/structure/disposalpipe/segment,/obj/machinery/camera{c_tag = "Quartermaster's Office"; dir = 8},/turf/simulated/floor,/area/quartermaster/qm) "bLn" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=AIW"; location = "QM"},/turf/simulated/floor,/area/hallway/primary/central/sw) "bLo" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/hallway/primary/central/sw) @@ -4792,7 +4792,7 @@ "bOh" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/quartermaster/qm) "bOi" = (/obj/machinery/vending/cigarette{pixel_x = 0; pixel_y = 0},/turf/simulated/floor,/area/hallway/primary/central/sw) "bOj" = (/turf/simulated/wall,/area/maintenance/apmaint) -"bOk" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/aft) +"bOk" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/apmaint) "bOl" = (/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},/obj/structure/cable,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "blueshield"; name = "Privacy Shutters"; opacity = 0},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/blueshield) "bOm" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/command{name = "Blueshield's Office"; req_access_txt = "67"},/turf/simulated/floor/wood,/area/blueshield) "bOn" = (/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},/obj/structure/cable,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "blueshield"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/blueshield) @@ -4857,7 +4857,7 @@ "bPu" = (/obj/structure/closet/secure_closet/quartermaster,/turf/simulated/floor,/area/quartermaster/qm) "bPv" = (/obj/structure/table,/obj/item/weapon/coin/silver,/turf/simulated/floor,/area/quartermaster/qm) "bPw" = (/obj/structure/table,/obj/item/weapon/cartridge/quartermaster{pixel_x = 6; pixel_y = 5},/obj/item/weapon/cartridge/quartermaster,/obj/item/weapon/cartridge/quartermaster{pixel_x = -4; pixel_y = 7},/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor,/area/quartermaster/qm) -"bPx" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/aft) +"bPx" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/apmaint) "bPy" = (/obj/machinery/light{dir = 1},/obj/structure/flora/kirbyplants,/obj/machinery/newscaster/security_unit{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/blueshield) "bPz" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/wood,/area/blueshield) "bPA" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/wood,/area/blueshield) @@ -4946,7 +4946,7 @@ "bRf" = (/obj/structure/disposalpipe/segment,/obj/effect/landmark/start{name = "Shaft Miner"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/quartermaster/miningdock) "bRg" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/quartermaster/miningdock) "bRh" = (/obj/item/weapon/beach_ball/holoball,/turf/simulated/floor/plating,/area/maintenance/apmaint) -"bRi" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plating,/area/maintenance/aft) +"bRi" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plating,/area/maintenance/apmaint) "bRj" = (/obj/machinery/photocopier,/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/obj/machinery/light_switch{pixel_x = -25},/turf/simulated/floor/wood,/area/blueshield) "bRk" = (/turf/simulated/floor{icon_state = "bcarpet05"},/area/blueshield) "bRl" = (/turf/simulated/floor/wood,/area/blueshield) @@ -5023,7 +5023,7 @@ "bSE" = (/obj/structure/table,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/machinery/requests_console{department = "Janitorial"; departmentType = 1; pixel_y = -29},/obj/item/weapon/reagent_containers/spray/cleaner,/turf/simulated/floor,/area/janitor) "bSF" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor,/area/janitor) "bSG" = (/obj/machinery/light,/obj/structure/janitorialcart,/turf/simulated/floor,/area/janitor) -"bSH" = (/obj/item/weapon/legcuffs/beartrap,/obj/item/weapon/legcuffs/beartrap,/obj/item/weapon/storage/box/mousetraps,/obj/item/weapon/storage/box/mousetraps,/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor,/area/janitor) +"bSH" = (/obj/item/weapon/restraints/legcuffs/beartrap,/obj/item/weapon/restraints/legcuffs/beartrap,/obj/item/weapon/storage/box/mousetraps,/obj/item/weapon/storage/box/mousetraps,/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor,/area/janitor) "bSI" = (/turf/simulated/floor,/area/janitor) "bSJ" = (/obj/structure/reagent_dispensers/watertank,/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/machinery/light_switch{pixel_y = -23},/turf/simulated/floor,/area/janitor) "bSK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/maintenance/asmaint) @@ -5085,7 +5085,7 @@ "bTO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/apmaint) "bTP" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/apmaint) "bTQ" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/closet/crate,/turf/simulated/floor/plating,/area/maintenance/aft) -"bTR" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/aft) +"bTR" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/apmaint) "bTS" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/wood,/area/blueshield) "bTT" = (/obj/structure/stool/bed/chair/office/dark,/turf/simulated/floor/carpet,/area/ntrep) "bTU" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/wood,/area/ntrep) @@ -5163,11 +5163,11 @@ "bVo" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/miningdock) "bVp" = (/obj/structure/reagent_dispensers/fueltank,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/apmaint) "bVq" = (/obj/structure/reagent_dispensers/watertank,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/apmaint) -"bVr" = (/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating,/area/maintenance/apmaint) +"bVr" = (/obj/machinery/power/apc{dir = 2; name = "Cargo Maintenance APC"; pixel_y = -24},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating,/area/maintenance/apmaint) "bVs" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/apmaint) "bVt" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/maintenance/aft) "bVu" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/sortjunction{dir = 8; icon_state = "pipe-j1s"; name = "HoP Office"; sortType = 15},/turf/simulated/floor/plating,/area/maintenance/aft) -"bVv" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/maintenance/aft) +"bVv" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/maintenance/apmaint) "bVw" = (/obj/machinery/keycard_auth{pixel_x = -24; pixel_y = 0},/obj/machinery/door/window{dir = 1; name = "Desk Door"; req_access_txt = "67"},/turf/simulated/floor/wood,/area/blueshield) "bVx" = (/obj/structure/table/woodentable,/obj/item/ashtray/glass{pixel_x = -4; pixel_y = -4},/obj/item/weapon/lighter/zippo/fluff/li_matsuda_1{pixel_x = 7; pixel_y = 4},/turf/simulated/floor{icon_state = "bcarpet05"},/area/blueshield) "bVy" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin,/obj/item/weapon/pen/blue,/obj/item/weapon/folder/blue{pixel_x = 4; pixel_y = 6},/obj/item/weapon/paper/blueshield,/turf/simulated/floor{icon_state = "bcarpet05"},/area/blueshield) @@ -5193,7 +5193,7 @@ "bVS" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/medical/sleeper) "bVT" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/medical/sleeper) "bVU" = (/obj/machinery/door_control{id = "scanhide"; name = "Scanning Room Privacy Shutters Control"; pixel_x = 6; pixel_y = 25},/obj/machinery/camera{c_tag = "Medbay Scanning"; network = list("SS13")},/obj/machinery/atmospherics/unary/cold_sink/freezer{dir = 8; icon_state = "freezer_0"; tag = ""},/obj/machinery/door_control{id = "scansep"; name = "Scanning Room Separation Shutters Control"; pixel_x = -6; pixel_y = 25},/turf/simulated/floor{dir = 5; icon_state = "blue"},/area/medical/sleeper) -"bVV" = (/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},/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "scanhide"; name = "Scanning Room Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"bVV" = (/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},/obj/machinery/door/poddoor/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "scanhide"; name = "Scanning Room Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) "bVW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay2) "bVX" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/cable,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/disposalpipe/segment,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) "bVY" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) @@ -5244,7 +5244,7 @@ "bWR" = (/turf/simulated/floor/airless{dir = 8; icon_state = "warning"},/area/toxins/test_area) "bWS" = (/turf/simulated/wall/r_wall,/area/maintenance/apmaint) "bWT" = (/obj/machinery/door/airlock/maintenance{name = "Firefighting equipment"; req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/apmaint) -"bWU" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/aft) +"bWU" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/apmaint) "bWV" = (/obj/machinery/requests_console{announcementConsole = 1; department = "Blueshield"; departmentType = 5; name = "Blueshield Requests Console"; pixel_x = -30},/turf/simulated/floor/wood,/area/blueshield) "bWW" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/effect/landmark/start{name = "Blueshield"},/turf/simulated/floor{icon_state = "bcarpet05"},/area/blueshield) "bWX" = (/obj/structure/table/woodentable,/obj/machinery/computer/skills{req_one_access = null},/turf/simulated/floor{icon_state = "bcarpet05"},/area/blueshield) @@ -5320,7 +5320,7 @@ "bYp" = (/obj/machinery/light/small{dir = 1},/obj/structure/stool,/turf/simulated/floor/plating,/area/maintenance/aft) "bYq" = (/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor/plating,/area/maintenance/aft) "bYr" = (/turf/simulated/floor/plating,/area/maintenance/aft) -"bYs" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/aft) +"bYs" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/apmaint) "bYt" = (/obj/structure/closet/secure_closet/blueshield,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/wood,/area/blueshield) "bYu" = (/obj/machinery/door_control{id = "blueshield"; name = "Privacy Shutters Control"; pixel_x = 0; pixel_y = -24; req_access_txt = "67"},/obj/machinery/computer/crew,/turf/simulated/floor/wood,/area/blueshield) "bYv" = (/obj/structure/table/woodentable,/obj/machinery/light/small/lamp,/obj/machinery/camera{c_tag = "Blueshield's Office"; dir = 1; network = list("SS13")},/turf/simulated/floor/wood,/area/blueshield) @@ -5567,7 +5567,7 @@ "cdc" = (/obj/machinery/atmospherics/pipe/tank/toxins{volume = 3200},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cdd" = (/obj/machinery/atmospherics/pipe/tank/oxygen{volume = 3200},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cde" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) -"cdf" = (/obj/structure/rack{dir = 1},/obj/item/device/flashlight,/obj/item/clothing/glasses/sunglasses,/turf/simulated/floor/plating,/area/maintenance/aft) +"cdf" = (/obj/structure/rack{dir = 1},/obj/item/device/flashlight,/obj/item/clothing/glasses/sunglasses,/turf/simulated/floor/plating,/area/maintenance/apmaint) "cdg" = (/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area) "cdh" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/circuitboard/borgupload{pixel_x = -1; pixel_y = 1},/obj/item/weapon/circuitboard/aiupload{pixel_x = 2; pixel_y = -2},/turf/simulated/floor,/area/storage/tech) "cdi" = (/obj/machinery/camera{c_tag = "Secure Tech Storage"; dir = 2},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/storage/tech) @@ -5636,7 +5636,7 @@ "cet" = (/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "ceu" = (/obj/machinery/atmospherics/binary/pump,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cev" = (/obj/machinery/power/apc{dir = 4; name = "Incinerator APC"; pixel_x = 24; pixel_y = 0},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) -"cew" = (/obj/machinery/light/small{dir = 8},/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/aft) +"cew" = (/obj/machinery/light/small{dir = 8},/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/apmaint) "cex" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/circuitboard/crew{pixel_x = -1; pixel_y = 1},/obj/item/weapon/circuitboard/card{pixel_x = 2; pixel_y = -2},/obj/item/weapon/circuitboard/communications{pixel_x = 5; pixel_y = -5},/obj/machinery/light/small{dir = 8},/turf/simulated/floor,/area/storage/tech) "cey" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/storage/tech) "cez" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/highsecurity{name = "Secure Tech Storage"; req_access_txt = "19;23"},/turf/simulated/floor/plating,/area/storage/tech) @@ -5763,9 +5763,9 @@ "cgQ" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cgR" = (/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/obj/machinery/hologram/holopad,/mob/living/simple_animal/mouse,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cgS" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) -"cgT" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/maintenance{name = "Incinerator Access"; req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/asmaint) -"cgU" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/maintenance/aft) -"cgV" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/aft) +"cgT" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/apmaint) +"cgU" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/maintenance/apmaint) +"cgV" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/maintenance{name = "Incinerator Access"; req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/apmaint) "cgW" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area) "cgX" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area) "cgY" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/grille,/obj/structure/cable,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area) @@ -5828,7 +5828,7 @@ "cid" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cie" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=1-Storage"; location = "7-Sleeper"},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"},/area/mine/laborcamp) "cif" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) -"cig" = (/obj/machinery/power/apc{dir = 4; name = "Engineering Maintenance APC"; pixel_x = 27; pixel_y = 2},/obj/structure/disposalpipe/segment,/obj/structure/cable,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area/maintenance/aft) +"cig" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/apmaint) "cih" = (/obj/structure/table,/obj/machinery/cell_charger{pixel_y = 5},/obj/machinery/status_display{layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plating,/area/storage/tech) "cii" = (/obj/machinery/light/small,/turf/simulated/floor/plating,/area/storage/tech) "cij" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = -1},/obj/item/clothing/gloves/yellow,/obj/item/device/t_scanner,/obj/item/clothing/glasses/meson,/obj/item/device/multitool,/turf/simulated/floor/plating,/area/storage/tech) @@ -5879,8 +5879,8 @@ "cjc" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area) "cjd" = (/obj/item/clothing/mask/cigarette,/turf/simulated/floor/plating/airless,/area/toxins/test_area) "cje" = (/obj/machinery/light/small,/turf/simulated/floor/plating/airless,/area/toxins/test_area) -"cjf" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/aft) -"cjg" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/aft) +"cjf" = (/turf/simulated/floor/plating,/area/maintenance/apmaint) +"cjg" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/apmaint) "cjh" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/turf/simulated/floor{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/aft) "cji" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/pump,/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor{icon_state = "arrival"; dir = 8},/area/hallway/primary/aft) "cjj" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 9; level = 2},/turf/simulated/wall/r_wall,/area) @@ -5964,8 +5964,8 @@ "ckJ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; external_pressure_bound = 101; on = 1; pressure_checks = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "ckK" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "ckL" = (/obj/machinery/iv_drip,/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) -"ckM" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/maintenance,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/asmaint) -"ckN" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/maintenance,/turf/simulated/floor/plating,/area/maintenance/asmaint) +"ckM" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/asmaint) +"ckN" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/asmaint) "ckO" = (/obj/machinery/door/window/eastright{base_state = "right"; dir = 1; icon_state = "right"; name = "Xenoflora Containment"; req_access_txt = "47"},/turf/simulated/floor,/area/toxins/xenobiology/xenoflora_storage) "ckP" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor,/area/toxins/xenobiology/xenoflora_storage) "ckQ" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "xeno_airlock_control"; name = "Xenobiology Access Button"; pixel_x = -24; pixel_y = 0; req_access_txt = "55"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/research{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "xeno_airlock_exterior"; locked = 1; name = "Xenobiology External Airlock"; req_access_txt = "55"},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) @@ -8199,7 +8199,7 @@ "dbI" = (/turf/space/transit/north/shuttlespace_ns8,/area/shuttle/escape_pod2/transit) "dbJ" = (/obj/structure/AIcore,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "dbK" = (/obj/item/weapon/spacecash/c200,/obj/item/weapon/spacecash/c50,/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"dbL" = (/obj/structure/jungle_plant,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) +"dbL" = (/obj/item/weapon/storage/box/zipties,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "dbM" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"},/area/syndicate_mothership) "dbN" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/syndicate_station/start) "dbO" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/syndicate_station/start) @@ -8245,7 +8245,7 @@ "dcC" = (/obj/machinery/door/airlock/centcom{name = "Study"; opacity = 1; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "dcD" = (/turf/unsimulated/floor{icon_state = "grimy"},/area/syndicate_mothership) "dcE" = (/obj/structure/table,/obj/item/stack/cable_coil,/obj/item/weapon/crowbar/red,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) -"dcF" = (/obj/structure/table,/obj/item/weapon/storage/box/handcuffs,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) +"dcF" = (/obj/structure/table,/obj/item/weapon/storage/box/zipties,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) "dcG" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/unsimulated/floor{tag = "icon-gravsnow_surround (WEST)"; icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_surround"; dir = 8},/area/syndicate_mothership) "dcH" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/unsimulated/floor{tag = "icon-gravsnow_corner (SOUTHEAST)"; icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"; dir = 6},/area/syndicate_mothership) "dcI" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/cans/beer{pixel_x = -2; pixel_y = 5},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) @@ -8795,7 +8795,7 @@ "dng" = (/obj/machinery/computer/card,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/centcom/evac) "dnh" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/centcom/evac) "dni" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/centcom/evac) -"dnj" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/obj/item/weapon/stamp,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/centcom/evac) +"dnj" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/obj/item/weapon/stamp/granted,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/centcom/evac) "dnk" = (/obj/structure/closet/secure_closet/bar{req_access_txt = "25"},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/evac) "dnl" = (/obj/structure/table,/obj/item/weapon/lighter/zippo,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/evac) "dnm" = (/obj/machinery/door/airlock/centcom{name = "Rest Area"; opacity = 1; req_access_txt = "0"},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/evac) @@ -9092,7 +9092,7 @@ "dsR" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/syndicate,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) "dsS" = (/obj/structure/table,/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/storage/pill_bottle/random_drug_bottle,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) "dsT" = (/obj/structure/table,/obj/item/weapon/scalpel,/obj/item/weapon/bonesetter,/obj/item/weapon/bonegel,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) -"dsU" = (/obj/structure/table,/obj/item/weapon/kitchen/utensil/fork,/obj/item/weapon/lighter,/obj/item/weapon/handcuffs/cable/red,/obj/item/weapon/storage/box/mousetraps,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/pen,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"dsU" = (/obj/structure/table,/obj/item/weapon/kitchen/utensil/fork,/obj/item/weapon/lighter,/obj/item/weapon/restraints/handcuffs/cable/red,/obj/item/weapon/storage/box/mousetraps,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/pen,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "dsV" = (/obj/structure/table,/obj/item/weapon/tank/plasma,/obj/item/device/multitool,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "dsW" = (/obj/structure/table,/obj/random/toolbox,/obj/random/bomb_supply,/obj/item/weapon/storage/fancy/cigarettes,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "dsX" = (/obj/machinery/recharger/wallcharger{pixel_x = 30},/obj/structure/rack,/obj/item/weapon/gun/energy/pulse_rifle/M1911,/obj/item/weapon/gun/energy/pulse_rifle/M1911{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) @@ -10336,7 +10336,7 @@ "dQN" = (/obj/effect/decal/remains/xeno,/turf/simulated/floor/airless{icon_state = "damaged2"},/area/mine/abandoned) "dQO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway) "dQP" = (/obj/structure/table,/obj/item/weapon/folder,/turf/simulated/floor/wood,/area/research_outpost/hallway) -"dQQ" = (/obj/structure/table,/obj/item/device/camera,/obj/item/weapon/stamp,/turf/simulated/floor/wood,/area/research_outpost/hallway) +"dQQ" = (/obj/structure/table,/obj/item/device/camera,/obj/item/weapon/stamp/granted,/turf/simulated/floor/wood,/area/research_outpost/hallway) "dQR" = (/turf/simulated/floor/wood,/area/research_outpost/hallway) "dQS" = (/obj/machinery/vending/snack,/obj/machinery/light{dir = 4},/turf/simulated/floor/wood,/area/research_outpost/hallway) "dQT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/door/firedoor/border_only{dir = 4; layer = 2.6; name = "Firelock"},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) @@ -11683,7 +11683,7 @@ "eqI" = (/obj/machinery/door/airlock/glass,/turf/simulated/floor,/area/derelict/bridge/access) "eqJ" = (/turf/simulated/wall/r_wall,/area/derelict/singularity_engine) "eqK" = (/obj/structure/window/reinforced,/turf/simulated/floor,/area/derelict/bridge/access) -"eqL" = (/obj/machinery/door/window,/turf/simulated/floor,/area/derelict/bridge/access) +"eqL" = (/obj/machinery/door/window{dir = 2},/turf/simulated/floor,/area/derelict/bridge/access) "eqM" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/cable,/obj/structure/window/reinforced,/turf/simulated/floor,/area/derelict/bridge/access) "eqN" = (/turf/simulated/wall,/area/derelict/bridge) "eqO" = (/obj/structure/sign/electricshock,/turf/simulated/wall/r_wall,/area/derelict/singularity_engine) @@ -11767,7 +11767,7 @@ "eso" = (/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) "esp" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) "esq" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) -"esr" = (/obj/machinery/door/window,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/derelict/bridge/access) +"esr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/window{dir = 2},/turf/simulated/floor,/area/derelict/bridge/access) "ess" = (/turf/simulated/wall/r_wall,/area/derelict/bridge) "est" = (/obj/machinery/door/window{dir = 2; name = "Captain's Quarters"; req_access_txt = "20"},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/derelict/bridge) "esu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) @@ -11833,7 +11833,7 @@ "etC" = (/turf/simulated/floor/airless{icon_state = "floorscorched2"},/area) "etD" = (/turf/simulated/floor/airless{icon_state = "damaged2"},/area) "etE" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) -"etF" = (/obj/machinery/door/window,/turf/simulated/floor/plating/airless,/area/derelict/hallway/primary) +"etF" = (/obj/machinery/door/window{dir = 2},/turf/simulated/floor/plating/airless,/area/derelict/hallway/primary) "etG" = (/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area) "etH" = (/obj/item/weapon/shard{icon_state = "medium"},/turf/simulated/floor/airless{icon_state = "damaged2"},/area/derelict/singularity_engine) "etI" = (/obj/structure/grille{density = 0; icon_state = "brokengrille"},/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) @@ -11962,7 +11962,7 @@ "ewb" = (/obj/structure/table,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "chapel"},/area/derelict/medical/chapel) "ewc" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor{dir = 4; icon_state = "chapel"},/area/derelict/medical/chapel) "ewd" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "chapel"},/area/derelict/medical/chapel) -"ewe" = (/obj/machinery/door/window,/turf/simulated/floor/airless,/area/derelict/medical/chapel) +"ewe" = (/obj/machinery/door/window{dir = 2},/turf/simulated/floor/airless,/area/derelict/medical/chapel) "ewf" = (/obj/machinery/door/window/southleft,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/airless{icon_state = "white"},/area/derelict/medical) "ewg" = (/obj/machinery/door/window/southright,/turf/simulated/floor/airless{icon_state = "white"},/area/derelict/medical) "ewh" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/airless,/area/derelict/hallway/primary) @@ -12001,7 +12001,7 @@ "ewO" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/airless,/area/derelict/hallway/primary) "ewP" = (/obj/structure/girder,/turf/simulated/floor/airless,/area/derelict/hallway/primary) "ewQ" = (/obj/machinery/portable_atmospherics/pump,/turf/simulated/floor,/area/derelict/arrival) -"ewR" = (/obj/machinery/door/window,/turf/simulated/floor/airless,/area/derelict/hallway/primary) +"ewR" = (/obj/machinery/door/window{dir = 2},/turf/simulated/floor/airless,/area/derelict/hallway/primary) "ewS" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/airless,/area/derelict/hallway/primary) "ewT" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/turf/simulated/floor/airless,/area/derelict/hallway/primary) "ewU" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/airless,/area/derelict/hallway/primary) @@ -12121,7 +12121,7 @@ "eze" = (/obj/item/weapon/paper/russiantraitorobj,/turf/simulated/floor/airless{icon_state = "damaged2"},/area/derelict/bridge/ai_upload) "ezf" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating/airless,/area/AIsattele) "ezg" = (/obj/item/stack/rods,/turf/simulated/floor/plating/airless,/area/derelict/hallway/secondary) -"ezh" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"},/turf/simulated/floor/airless,/area) +"ezh" = (/obj/machinery/door/window{dir = 8},/turf/simulated/floor/airless,/area/derelict/bridge/ai_upload) "ezi" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/light/small,/turf/simulated/floor/airless,/area/derelict/bridge/ai_upload) "ezj" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"},/turf/simulated/floor/airless,/area/derelict/bridge/ai_upload) "ezk" = (/obj/structure/closet/crate,/obj/item/device/aicard,/obj/item/device/multitool,/obj/item/weapon/weldingtool,/obj/item/weapon/wrench,/obj/item/weapon/circuitboard/teleporter,/turf/simulated/floor/plating/airless,/area/AIsattele) @@ -12552,6 +12552,7 @@ "eHt" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/effect/landmark{name = "JoinLateCryo"},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/sleep) "eHu" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad2"},/turf/simulated/floor,/area/quartermaster/storage) "eHv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/conveyor{dir = 4; id = "QMLoad2"},/turf/simulated/floor,/area/quartermaster/storage) +"eHw" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/apmaint) (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -12712,10 +12713,10 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacbVaaaaabaabaaiaaiaaiaaiaaiaaiaaiaaiaaqbWUcbWaaacbXcbYcbZccaccbcccccdcceccfccgabZcchcciccjcckcclccmccnccoccpccqabmccrccsccsccscctaaibDgbDgaaqaaqaaqaaqaaJaaqccuccuccvaaqaaqaosaaqaNtccwccxccyccxachcczccAccBachbrebreachccCccDccEaaiccFccGbVQaaiaaiabmaaiccHaaiccIccJaaiccKccLccMbDgccNaaiabmccOafaaaibsacaBccPbsaccQccRccSccTbsabsabsabsabsabsaccUccVbIgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaibQXbQXbQXbQXbQXbQXbYnbQXcbUbQXbQXbQXbQXbQXaaiaaiaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaccXccYccYccYccZcfAcdacdbcdccddcdeaaqcdfbWUaEFaaacdgcdhcdicdjcdkccccdlcdmcdncdoaaqcdpbYCbTWcbfcdqbZTcdrbZTcdscdtcducdvcdwcdwcdwcdxaaibDgbDgaaqcdycdzcdAcdBcdCcdDcdDcdEcdFcdGcdHcdIcdJabZcdKbXJbXJacFcdLcdMcdNaaiaaaaaaaaicdOcdPcdQachcdRcdScdTcdUcdUcdVbBDcdWcdXcdYcdZcdXcdXcdXceacdXcdXcebceccedceecefcegcehceibQOcejbQObQObQObQObQOcekcelbQObQOcembsacenaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaaibWRbQXbQXbQXbQXbQXbQXbQXbQXbQXbQXbQXaaiaaiaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceocepcepcepcepceqcercescetceuceucevaaqcewbYsaEFaaacdgcexceycezceAceBceCceDceAceAceEceFceGceHacFacFceIceJbZTceKceLceMcdwcdwcdwcdwceNaaibDgbDgaaqceOcePceQceRceSceTceTceUceVceWceXceYceZaaqcfabXFcfbaaicfccdMcfdaaiaaaaaaaaicfecffcfgaaibDhcfhcficficficficficficfjcfkcflcfmachachcfncfoachachcfpcfqcfraaqaaicfscftcfuaaiaaiaaiaaicfvcfwcfuaaiaaibsacfxbsabJuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabTHaaiaaibZHbZHbQXbQXbQXbQXbQXbQXbQXbQXaaiaaiaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacfycfzcfCcfBcfCcfEcfDcgQcfFcfFcfGaaqcfHbWUaEFaaacdgcfIcfJaiVcfKccccfLcfMcfNcfOaaqcdpbYCbYDcfPaaicfQaaqcfRcfScfTcfUcfVcdwcdwcfWcfXaaibDgcfYaaqcfZcgacgbcgccgccgccgdcgecgccgccgfcgbcggaaicghbXFcgiaaicgjcdMcgkaaiaaaaaaaaicglcgmcgnaaicgobDgcfYaaiaaiaaiaaiaaiaoHaoIaoJaaiaaicgpcgqcgrcgsaaicgtcguamdaaicgvcgwcgwcgwcgxcgycgzcgAcgBcgCcgDcgEaaicgFcgGcgHcgIcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgKcgLaaibSiaaibQXbQXbQXbQXbQXbQXbQXaaiaaiaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaacfycgMcgNcgOcgPcetchYcetcgRcetcgScgTcgUcgVcgWaaacgXcbYcgYccacgZccccccchachbchcabJchdchechfchgaaichhchichjchkchlabmchmcdwcdwcdwchnaaibDgbDgaaqaaqaaJchochpchqchraaqchschtchuchvbUgaaJaaicfabXFcfbaaichwcdMcdNaaiaaaaaaaaichxchychzaaibDgbDgbDgaaiaabaaaaaaaabaaaaabaaaaaaaaichAchBchCchDchEchFchGchHchIchJchKchLchLchMchNchNchOchPchQchQchRaaiaaichSaamaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaichTchUchVaaiaaibQXbQXchWbQXbQXaaiaaiaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacfychXcfCchZcfCciacibcidciccgQcifaaqbYrcigaaiaaaaaaaaaaaaaaicihciicijcijcikcilaaqcimbYCbTWcinciocipciqcircircirciscitcdwciucdwcivaaibDgbDgaaqciwcixciycizciAciBaaqciAciBcizciCciDciEaaicghciFcgiaaichwcdMciGaaiaaiaaiaaiaaiaaiaaiaaiciHbDgbDgaaiaabaaaaaaaaaaabaabaabaaaaaiciIciJciJciKciLciMciNciOciPciQciRciSciTciUciVciWchNchNchNciXciYaaiciZcjacjbaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjccjdcjebSjaaqaaiaaibQXbQYbQXaaiaaiaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOabAaaiaaiaaiaaiaaiaaiaaiaaiaJkaJkaJkaJkaJkaaiaaqaaqaaqaaqaaqaaqcjfcjgaaiaaiaaiaaiaaiaaiaaqaaqaaqaaqaaqaaqaaqcjhbYCbTWcjicjjcjkcjlcjmcjncjocjpcjqcjrcjscjtcjuaaibDgbDgaaqcjvcjwciycizcizcjxaaqcjycizcizciCciycjzaaiaaiaaiaaiccIcjAcdMcjBaaicjCbDgbDgbDgbDgcjDbDgbDgbDgbDgaaiaaaaaaaaaaaaaaaaabaabaaaaaicjEcjFcjFcjGcjHcjIcjJcjKcjLcjMcjNchNchNchNcjOcjPchNcjQchNciXcjRaaicjScjTcjUaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjVbBZbBZbCaaaqaaqaaiaaiaaiaaibPhaabaabaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacfycfzcfCcfBcfCcfEcfDcgQcfFcfFcfGaaqcgTbWUaEFaaacdgcfIcfJaiVcfKccccfLcfMcfNcfOaaqcdpbYCbYDcfPaaicfQaaqcfRcfScfTcfUcfVcdwcdwcfWcfXaaibDgcfYaaqcfZcgacgbcgccgccgccgdcgecgccgccgfcgbcggaaicghbXFcgiaaicgjcdMcgkaaiaaaaaaaaicglcgmcgnaaicgobDgcfYaaiaaiaaiaaiaaiaoHaoIaoJaaiaaicgpcgqcgrcgsaaicgtcguamdaaicgvcgwcgwcgwcgxcgycgzcgAcgBcgCcgDcgEaaicgFcgGcgHcgIcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgKcgLaaibSiaaibQXbQXbQXbQXbQXbQXbQXaaiaaiaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaacfycgMcgNcgOcgPcetchYcetcgRcetcgScgVcgUcigcgWaaacgXcbYcgYccacgZccccccchachbchcabJchdchechfchgaaichhchichjchkchlabmchmcdwcdwcdwchnaaibDgbDgaaqaaqaaJchochpchqchraaqchschtchuchvbUgaaJaaicfabXFcfbaaichwcdMcdNaaiaaaaaaaaichxchychzaaibDgbDgbDgaaiaabaaaaaaaabaaaaabaaaaaaaaichAchBchCchDchEchFchGchHchIchJchKchLchLchMchNchNchOchPchQchQchRaaiaaichSaamaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaichTchUchVaaiaaibQXbQXchWbQXbQXaaiaaiaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacfychXcfCchZcfCciacibcidciccgQcifaaqcjfbWUaaiaaaaaaaaaaaaaaicihciicijcijcikcilaaqcimbYCbTWcinciocipciqcircircirciscitcdwciucdwcivaaibDgbDgaaqciwcixciycizciAciBaaqciAciBcizciCciDciEaaicghciFcgiaaichwcdMciGaaiaaiaaiaaiaaiaaiaaiaaiciHbDgbDgaaiaabaaaaaaaaaaabaabaabaaaaaiciIciJciJciKciLciMciNciOciPciQciRciSciTciUciVciWchNchNchNciXciYaaiciZcjacjbaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjccjdcjebSjaaqaaiaaibQXbQYbQXaaiaaiaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOabAaaiaaiaaiaaiaaiaaiaaiaaiaJkaJkaJkaJkaJkaaiaaqaaqaaqaaqaaqaaqcjgeHwaaiaaiaaiaaiaaiaaiaaqaaqaaqaaqaaqaaqaaqcjhbYCbTWcjicjjcjkcjlcjmcjncjocjpcjqcjrcjscjtcjuaaibDgbDgaaqcjvcjwciycizcizcjxaaqcjycizcizciCciycjzaaiaaiaaiaaiccIcjAcdMcjBaaicjCbDgbDgbDgbDgcjDbDgbDgbDgbDgaaiaaaaaaaaaaaaaaaaabaabaaaaaicjEcjFcjFcjGcjHcjIcjJcjKcjLcjMcjNchNchNchNcjOcjPchNcjQchNciXcjRaaicjScjTcjUaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjVbBZbBZbCaaaqaaqaaiaaiaaiaaibPhaabaabaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjWcjXcjYcjZckackackbckcckdckeckfckgckhckickjckjckjckkcklckmckncknckockpckqckrcksckrckrckrckqckrckrcktckuckvckwbYCbTWckxckyckzafaaaicfUacFaujckAckBacFatEcblaaibDgbDgaaqckCckDckEckFckGckHaaqckIckGckJckKckEckLaaibDgbDgbDgckMchwcdMchwckNbDgbDgbDgbDgbDgbDgbDgbDgbDgbDgaaiaaaaaaaaaaaaaaaaabaabaabaaickOckPckPckPcbAaaickQafacbAckRckSckTckTckUcjMcjMckVckTckWckXckYaaickZclaclbaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjWcjXclccldclecldclfclgclhclicljclkcllclmclnclnclnclnbYCbTXbTXbTXclncloclnclnclnclnclnclnclnclnclnclnclpclqclrclscltcluclvclwclxaaiclyclzclAclBclCclDclEclFachcficlGabJclHclIclJclKcizclLaaqclLcizclKclMciyclNaaiclOachachbmWclPclQclRaaibNtaoIaoIbNuaaiaaiaaiaoHaoIaoJaaiaaaaaaaaaaaaaaaaaaaabaabaaiclSclTclUclVaaiclWclXclYaaiclZcmacmacmacmbcmccmdcmecmacmacmacmfaaiaDpcmgcmhaFRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjWcmicldcmjcmkcmlcmmcmncmocmpcmqcmrcmscmtcmucmvcmwcmwcmxabJcmyabJcmucmzcmucmucmucmucmucmucmucmucmucmucmAclncmBcmCcmDcmEcmFcmGcmHcmIcmJcmKcmLcmMcmNcmOcmPcmQacFbXlcmRcmScmTcizciycizcizcmUabZcmVcizcizciCciycmWaaicmXaaiaaaafaaaicmYaaiaaiaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaaiaaiaaiaaiaaiaaiaaiaaicmZcnacnbaaiaaicnccndcneaaiaaiaaiaaicnccndcneaaiaaiaEFcnfaEFaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -13980,7 +13981,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaceyHeyVeyHeyWeyXeyYeyYexNeyUexNeyUexNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaacaaceyHeyZezaeyWeyYezbeyYexNeyUexNeyUexNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabexoaacetNeyHezceyHezdeyYezeeHpexNezgexNeyUexNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaacetNezheyYeziezjeyYeHoezleyYexNeyUexNeyUexNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaacetNdEjezheziezjeyYeHoezleyYexNeyUexNeyUexNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaacdEjdEjeyHezmeyHeyYeyYezaeyYexNeyUexNezgexNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaaiaaiaaaeyHeyHezmeyHeyHeyHeyHeyHexNeyUexNezgexNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadyqaaaaaaaaaaaaaaaeznaaaaaaaaaaaaaaadyqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/nano/debug.html b/nano/debug.html index 969956bacb2..58b2be3df1a 100644 --- a/nano/debug.html +++ b/nano/debug.html @@ -16,7 +16,7 @@ - +