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.
Log 2: Damn thing is acting up again. Three days no contact this time. I thought I heard clanking noises from it yesterday. Jim is going on about the NT base or some shit. We've been over this before – They don't know we're here, that engineer was too drunk to recognise his suit, especially since I had it painted orange. He's starting to get annoying. We're safe.
Log 3: Gateway synced itself up automatically today. I opened it for an instant to spy through it, got a glimpse of the inside of a transport container. Either HQ's redecorating or something, or there's more than two of these things."; name = "Personal Log"},/turf/simulated/floor/plasteel{dir = 6; icon_state = "warning"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bt" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/machinery/recharger{pixel_y = 4},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{ icon_state = "warning"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bu" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/weapon/storage/firstaid/regular,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 10; icon_state = "warning"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bv" = (/obj/machinery/door/airlock{name = "Unisex Restrooms"; req_access_txt = "0"},/turf/simulated/floor/plasteel{ icon_state = "freezerfloor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bw" = (/obj/structure/sink{pixel_y = 28},/obj/machinery/light/small{dir = 8},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{ icon_state = "freezerfloor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bx" = (/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"by" = (/obj/structure/table,/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 32; pixel_y = 0},/obj/item/trash/plate,/obj/item/weapon/cigbutt,/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bz" = (/obj/structure/stool,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bm" = (/obj/item/weapon/cigbutt,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bn" = (/obj/machinery/light/small{dir = 8},/obj/structure/sign/poster{icon_state = "poster17"; pixel_x = -32; pixel_y = 0; serial_number = 17; subtype = 0},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bo" = (/obj/structure/table,/obj/machinery/microwave{pixel_x = -3; pixel_y = 6},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bp" = (/obj/machinery/alarm/monitor{frequency = 1439; locked = 1; pixel_y = 23; req_access = "150"},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bq" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/device/radio/off{pixel_x = -4; pixel_y = 4},/obj/item/device/radio/off{pixel_x = 2},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"br" = (/obj/machinery/door/window{dir = 1; name = "Gateway Access"; req_access_txt = "150"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bs" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/obj/item/weapon/paper{info = "Log 1: We got our promised supply drop today. We were only meant to get it, what, a week ago? This bloody gateway keeps desyncing itself, and that means subsisting off recycled water and carb packs. No clue where the damn thing connects to on its off days, and HQ say we are 'not to touch it if it isn't linking to command.' We dumped off the assload of crates Jim filled, got our boxes of oxygen, food and drink, and closed the portal.
Log 2: Damn thing is acting up again. Three days no contact this time. I thought I heard clanking noises from it yesterday. Jim is going on about the NT base or some shit. We've been over this before – They don't know we're here, that engineer was too drunk to recognise his suit, especially since I had it painted orange. He's starting to get annoying. We're safe.
Log 3: Gateway synced itself up automatically today. I opened it for an instant to spy through it, got a glimpse of the inside of a transport container. Either HQ's redecorating or something, or there's more than two of these things."; name = "Personal Log"},/turf/simulated/floor/plasteel{dir = 6; icon_state = "warning"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bt" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/machinery/recharger{pixel_y = 4},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "warning"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bu" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/weapon/storage/firstaid/regular,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 10; icon_state = "warning"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bv" = (/obj/machinery/door/airlock{name = "Unisex Restrooms"; req_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bw" = (/obj/structure/sink{pixel_y = 28},/obj/machinery/light/small{dir = 8},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bx" = (/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"by" = (/obj/structure/table,/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 32; pixel_y = 0},/obj/item/trash/plate,/obj/item/weapon/cigbutt,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bz" = (/obj/structure/stool,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"bA" = (/obj/machinery/light{dir = 8},/obj/structure/stool,/turf/simulated/floor/plasteel,/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bB" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bB" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"bC" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel,/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bD" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/alarm/monitor{dir = 8; frequency = 1439; locked = 1; pixel_x = 23; pixel_y = 0; req_access = "150"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bD" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/alarm/monitor{dir = 8; frequency = 1439; locked = 1; pixel_x = 23; pixel_y = 0; req_access = "150"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"bE" = (/turf/simulated/floor/plasteel,/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bF" = (/obj/structure/toilet{dir = 1},/turf/simulated/floor/plasteel{ icon_state = "freezerfloor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bG" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bH" = (/obj/structure/closet/crate/bin,/obj/item/trash/syndi_cakes,/obj/item/trash/sosjerky,/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bI" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets,/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bJ" = (/obj/structure/stool,/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bK" = (/turf/simulated/floor/plasteel{ icon_state = "red"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bL" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{ icon_state = "red"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bM" = (/obj/structure/closet/l3closet/general,/turf/simulated/floor/plasteel{ icon_state = "red"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bN" = (/obj/structure/closet/emcloset,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plasteel{ icon_state = "red"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bF" = (/obj/structure/toilet{dir = 1},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bG" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bH" = (/obj/structure/closet/crate/bin,/obj/item/trash/syndi_cakes,/obj/item/trash/sosjerky,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bI" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bJ" = (/obj/structure/stool,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bK" = (/turf/simulated/floor/plasteel{icon_state = "red"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bL" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "red"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bM" = (/obj/structure/closet/l3closet/general,/turf/simulated/floor/plasteel{icon_state = "red"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bN" = (/obj/structure/closet/emcloset,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plasteel{icon_state = "red"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"bO" = (/obj/machinery/door/airlock/glass{name = "Break Room"},/turf/simulated/floor/plasteel,/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"bP" = (/obj/structure/grille,/obj/structure/window/full/basic,/turf/simulated/floor/plating,/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"bQ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/door/airlock/highsecurity{icon_state = "door_locked"; locked = 1; name = "Gateway"; req_access_txt = "150"},/turf/simulated/floor/plasteel,/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bR" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/item/clothing/gloves/color/yellow,/obj/item/device/multitool,/turf/simulated/floor/plating{dir = 9; icon_state = "warnplate"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bS" = (/obj/machinery/power/smes{charge = 0; input_level = 10000; inputting = 0; output_level = 15000; outputting = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bT" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/computer/monitor,/turf/simulated/floor/plating{dir = 5; icon_state = "warnplate"; tag = "icon-warnplate (NORTHEAST)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bU" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating{dir = 5; icon_state = "warnplate"; tag = "icon-warnplate (NORTHEAST)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"bV" = (/obj/machinery/portable_atmospherics/canister/air,/obj/machinery/alarm/monitor{frequency = 1439; locked = 1; pixel_y = 23; req_access = "150"},/turf/simulated/floor/plating{dir = 9; icon_state = "warnplate"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bR" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/item/clothing/gloves/color/yellow,/obj/item/device/multitool,/turf/simulated/floor/plating{dir = 9; icon_state = "warnplate"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bS" = (/obj/machinery/power/smes{charge = 0; input_level = 10000; inputting = 0; output_level = 15000; outputting = 0},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bT" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/computer/monitor,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating{dir = 5; icon_state = "warnplate"; tag = "icon-warnplate (NORTHEAST)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bU" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating{dir = 5; icon_state = "warnplate"; tag = "icon-warnplate (NORTHEAST)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"bV" = (/obj/machinery/portable_atmospherics/canister/air,/obj/machinery/alarm/monitor{frequency = 1439; locked = 1; pixel_y = 23; req_access = "150"},/turf/simulated/floor/plating{dir = 9; icon_state = "warnplate"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"bW" = (/obj/structure/alien/weeds/node,/mob/living/simple_animal/hostile/alien,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
"bX" = (/obj/machinery/mineral/unloading_machine{dir = 1; icon_state = "unloader-corner"; input_dir = 4; output_dir = 8},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plating/airless{name = "plating"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"bY" = (/obj/machinery/conveyor{dir = 2; id = "awaysyndie"},/turf/simulated/floor/plating/airless{dir = 4; icon_state = "warnplate"; name = "plating"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
@@ -110,15 +110,15 @@
"cf" = (/obj/structure/sign/biohazard{pixel_y = 32},/obj/structure/alien/weeds/node,/turf/simulated/floor/plasteel/airless{dir = 8; icon_state = "warningcorner"; name = "floor"; tag = "icon-warningcorner (NORTH)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"cg" = (/obj/machinery/light/small{active_power_usage = 0; dir = 4; icon_state = "bulb-broken"; status = 2},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel/airless{dir = 4; icon_state = "red"; name = "floor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"ch" = (/obj/structure/sign/securearea{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel/airless{dir = 4; icon_state = "warningcorner"; name = "floor"; tag = "icon-warningcorner (NORTH)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"ci" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/table,/obj/machinery/cell_charger,/obj/machinery/light/small{dir = 8},/obj/item/weapon/stock_parts/cell/high,/obj/item/weapon/paper{info = "Alright, listen up. If you're reading this, I'm either taking a shit or I've been recalled back to Command. Either way, you'll need to know how to restore power. We've stolen this stuff from Nanotrasen, so all the equipment is jury-rigged. We have generators that work on both plasma and uranium, about 50 sheets should power the outpost for quite a while. If the generators aren't working, which is very likely, take the power cell on the desk and put it into the APC in the hallway. That should get the place running, at least for a little while."; name = "Engineering Instructions"},/turf/simulated/floor/plating{dir = 8; icon_state = "warnplate"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"cj" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplate"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"ck" = (/obj/structure/stool,/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"cl" = (/obj/machinery/light/small{dir = 4},/obj/structure/sign/poster{icon_state = "poster10"; pixel_x = 32; pixel_y = 0; serial_number = 10; subtype = 0},/turf/simulated/floor/plating{dir = 4; icon_state = "warnplate"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"cm" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"; tag = "icon-warnplatecorner (EAST)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"ci" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/table,/obj/machinery/cell_charger,/obj/machinery/light/small{dir = 8},/obj/item/weapon/stock_parts/cell/high,/obj/item/weapon/paper{info = "Alright, listen up. If you're reading this, I'm either taking a shit or I've been recalled back to Command. Either way, you'll need to know how to restore power. We've stolen this stuff from Nanotrasen, so all the equipment is jury-rigged. We have generators that work on both plasma and uranium, about 50 sheets should power the outpost for quite a while. If the generators aren't working, which is very likely, take the power cell on the desk and put it into the APC in the hallway. That should get the place running, at least for a little while."; name = "Engineering Instructions"},/turf/simulated/floor/plating{dir = 8; icon_state = "warnplate"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"cj" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplate"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"ck" = (/obj/structure/stool,/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"cl" = (/obj/machinery/light/small{dir = 4},/obj/structure/sign/poster{icon_state = "poster10"; pixel_x = 32; pixel_y = 0; serial_number = 10; subtype = 0},/turf/simulated/floor/plating{dir = 4; icon_state = "warnplate"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"cm" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"; tag = "icon-warnplatecorner (EAST)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"cn" = (/obj/structure/grille,/obj/structure/window/full/reinforced,/turf/simulated/floor/plating,/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"co" = (/turf/simulated/floor/plasteel/airless{name = "floor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"cp" = (/turf/simulated/floor/plasteel/airless{dir = 8; icon_state = "warning"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"cq" = (/obj/machinery/door/airlock/glass{density = 0; emagged = 1; icon_state = "door_open"; locked = 1; name = "Dormitories"},/obj/item/stack/rods,/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/plasteel{carbon_dioxide = 0; nitrogen = 0; oxygen = 0; temperature = 2.7},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"cq" = (/obj/machinery/door/airlock/glass{density = 0; emagged = 1; icon_state = "door_open"; locked = 1; name = "Dormitories"},/obj/item/stack/rods,/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/plasteel{carbon_dioxide = 0; nitrogen = 0; oxygen = 0; temperature = 2.7},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"cr" = (/turf/simulated/floor/plasteel/airless{dir = 4; icon_state = "red"; name = "floor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"cs" = (/turf/simulated/floor/plasteel/airless{dir = 8; icon_state = "red"; name = "floor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"ct" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel/airless{name = "floor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
@@ -128,22 +128,22 @@
"cx" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/airlock/engineering{name = "Power Maintenance"; req_access_txt = "150"},/turf/simulated/floor/plating,/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"cy" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"cz" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating,/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"cA" = (/obj/machinery/space_heater,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{dir = 4; icon_state = "warnplate"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"cB" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating{burnt = 1; icon_state = "panelscorched"; tag = "icon-panelscorched"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"cA" = (/obj/machinery/space_heater,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{dir = 4; icon_state = "warnplate"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"cB" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating{burnt = 1; icon_state = "panelscorched"; tag = "icon-panelscorched"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"cC" = (/obj/machinery/mineral/processing_unit{dir = 1; output_dir = 2},/turf/simulated/floor/plating/airless{dir = 4; icon_state = "warnplate"; name = "plating"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"cD" = (/obj/machinery/mineral/processing_unit_console{machinedir = 8},/turf/simulated/wall,/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"cE" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel/airless{dir = 8; icon_state = "warning"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"cF" = (/obj/structure/grille{density = 0; destroyed = 1; icon_state = "brokengrille"},/obj/item/stack/rods,/obj/item/stack/rods,/obj/item/weapon/shard,/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plating/airless{name = "plating"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"cF" = (/obj/structure/grille/broken,/obj/item/stack/rods,/obj/item/stack/rods,/obj/item/weapon/shard,/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plating/airless{name = "plating"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"cG" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel/airless{dir = 4; icon_state = "red"; name = "floor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"cH" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel/airless{dir = 2; icon_state = "red"; name = "floor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"cI" = (/turf/simulated/floor/plasteel/airless{dir = 10; icon_state = "red"; name = "floor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"cJ" = (/obj/structure/cable,/obj/machinery/power/apc/noalarm{cell_type = 15000; dir = 2; locked = 1; name = "Worn-out APC"; pixel_x = 0; pixel_y = -25; req_access = "150"; start_charge = 0},/turf/simulated/floor/plasteel/airless{dir = 2; icon_state = "red"; name = "floor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"cK" = (/turf/simulated/floor/plasteel/airless{dir = 2; icon_state = "red"; name = "floor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"cL" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel/airless{dir = 6; icon_state = "red"; name = "floor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"cM" = (/obj/item/weapon/storage/box/lights/mixed,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{dir = 10; icon_state = "warnplate"; tag = "icon-warnplate (SOUTHWEST)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"cN" = (/obj/structure/cable,/obj/effect/decal/cleanable/dirt,/obj/machinery/power/port_gen/pacman/super{desc = "A portable generator for emergency backup power."; name = "S.U.P.E.R.P.A.C.M.A.N.-type portable generator"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"cO" = (/obj/structure/cable,/obj/machinery/power/port_gen/pacman{desc = "A portable generator for emergency backup power."; name = "P.A.C.M.A.N.-type portable generator"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"cP" = (/obj/machinery/portable_atmospherics/scrubber,/turf/simulated/floor/plating{dir = 6; icon_state = "warnplate"; tag = "icon-warnplate (SOUTHEAST)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"cM" = (/obj/item/weapon/storage/box/lights/mixed,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{dir = 10; icon_state = "warnplate"; tag = "icon-warnplate (SOUTHWEST)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"cN" = (/obj/structure/cable,/obj/effect/decal/cleanable/dirt,/obj/machinery/power/port_gen/pacman/super{desc = "A portable generator for emergency backup power."; name = "S.U.P.E.R.P.A.C.M.A.N.-type portable generator"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"cO" = (/obj/structure/cable,/obj/machinery/power/port_gen/pacman{desc = "A portable generator for emergency backup power."; name = "P.A.C.M.A.N.-type portable generator"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"cP" = (/obj/machinery/portable_atmospherics/scrubber,/turf/simulated/floor/plating{dir = 6; icon_state = "warnplate"; tag = "icon-warnplate (SOUTHEAST)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"cQ" = (/turf/simulated/floor/plasteel/airless{icon_state = "damaged4"; name = "floor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"cR" = (/obj/machinery/conveyor_switch/oneway{id = "awaysyndie"; layer = 3.1; name = "mining conveyor"},/turf/simulated/floor/plasteel/airless{dir = 8; icon_state = "warning"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"cS" = (/obj/machinery/alarm/monitor{dir = 8; frequency = 1439; locked = 1; pixel_x = 23; pixel_y = 0; req_access = "150"},/obj/machinery/light{active_power_usage = 0; dir = 4; icon_state = "tube-broken"; status = 2},/turf/simulated/floor/plasteel/airless{dir = 4; icon_state = "red"; name = "floor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
@@ -172,7 +172,7 @@
"dp" = (/turf/simulated/floor/plasteel/airless{icon_state = "damaged1"; name = "floor"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"dq" = (/obj/structure/table/woodentable,/obj/structure/sign/poster{icon_state = "poster24"; pixel_x = 0; pixel_y = -32; serial_number = 24; subtype = 0},/obj/item/weapon/pen,/obj/item/weapon/paper{info = "Log 1: While mining today I noticed the NT station was finished with its renovations. They placed some huge reinforced tumor on the station – looks so ugly. I wouldn't be surprised if those pigs decided to turn that little astronomy outpost into a prison with that thing, it'd be pretty typical of them.
Log 2: Really dumb of me, but I just waved at an engineer in the outpost, and he waved back. I hope to god he was too dumb or drunk to recognize the suit, because if he isn't, then we might have to pull out before they come looking for us.
Log 3: That huge reinforced tumor in their science section has been making a lot of noise lately. I've been hearing some banging and scratching from the other side and I'm kind of glad now that they reinforced this thing so much. I'll be sleeping with my gun under my pillow from now on."; name = "Personal Log"},/turf/simulated/floor/plasteel/airless{dir = 8; icon_state = "wood"; name = "floor"; tag = "icon-warningcorner (NORTH)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"dr" = (/obj/structure/closet/secure_closet{desc = "It's a secure locker for personnel. The first card swiped gains control."; icon_broken = "cabinetdetective_broken"; icon_closed = "cabinetdetective"; icon_locked = "cabinetdetective_locked"; icon_off = "cabinetdetective_broken"; icon_opened = "cabinetdetective_open"; icon_state = "cabinetdetective_locked"; locked = 1; name = "personal closet"; req_access_txt = "150"},/obj/item/ammo_box/magazine/m10mm,/obj/item/ammo_box/magazine/m10mm,/obj/item/weapon/suppressor,/turf/simulated/floor/plasteel/airless{dir = 8; icon_state = "wood"; name = "floor"; tag = "icon-warningcorner (NORTH)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"ds" = (/obj/structure/closet/secure_closet{desc = "It's a secure locker for personnel. The first card swiped gains control."; icon_broken = "cabinetdetective_broken"; icon_closed = "cabinetdetective"; icon_locked = "cabinetdetective_locked"; icon_off = "cabinetdetective_broken"; icon_opened = "cabinetdetective_open"; icon_state = "cabinetdetective"; locked = 0; name = "personal closet"; req_access_txt = "150"},/obj/item/weapon/spacecash/c50,/turf/simulated/floor/wood,/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
+"ds" = (/obj/structure/closet/secure_closet{desc = "It's a secure locker for personnel. The first card swiped gains control."; icon_broken = "cabinetdetective_broken"; icon_closed = "cabinetdetective"; icon_locked = "cabinetdetective_locked"; icon_off = "cabinetdetective_broken"; icon_opened = "cabinetdetective_open"; icon_state = "cabinetdetective"; locked = 0; name = "personal closet"; req_access_txt = "150"},/obj/item/stack/spacecash/c50,/turf/simulated/floor/wood,/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"dt" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/syndie,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood,/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"du" = (/obj/machinery/door/airlock/external,/turf/simulated/floor/plating/airless{name = "plating"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"dv" = (/obj/item/weapon/ore/iron,/obj/item/weapon/ore/iron{pixel_x = -7; pixel_y = -4},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
@@ -207,15 +207,15 @@
"dY" = (/obj/machinery/light/small,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"dZ" = (/turf/simulated/wall/r_wall/rust,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"ea" = (/turf/simulated/wall/r_wall,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"eb" = (/obj/structure/grille,/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id_tag = "Awaybiohazard"; name = "Acid-Proof biohazard containment door"; unacidable = 1},/obj/machinery/door/poddoor{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id_tag = "Awaybiohazard"; layer = 2.9; name = "Acid-Proof biohazard containment door"; unacidable = 1},/obj/structure/window/full/reinforced,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"eb" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/light{dir = 8},/turf/simulated/floor/plasteel/airless{dir = 8; icon_state = "warning"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"ec" = (/obj/structure/sign/biohazard,/turf/simulated/wall/r_wall,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"ed" = (/obj/machinery/vending/snack,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"ee" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"ee" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"ef" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor/plasteel,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"eg" = (/obj/machinery/atmospherics/binary/pump{dir = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"eg" = (/obj/machinery/atmospherics/binary/pump{dir = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eh" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/canister,/obj/structure/alien/weeds,/turf/simulated/floor/plasteel,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"ei" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/machinery/atmospherics/pipe/simple/visible{dir = 10},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"ej" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"ej" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"ek" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/shieldwallgen{locked = 0; req_access = null},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"el" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/stool/bed/nest,/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 9; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"em" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 4; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
@@ -227,10 +227,10 @@
"es" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/stool/bed/nest,/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 4; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"et" = (/obj/machinery/vending/coffee,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eu" = (/turf/simulated/floor/plasteel,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"ev" = (/obj/machinery/light/small{active_power_usage = 0; dir = 4; icon_state = "bulb-broken"; status = 2},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"ev" = (/obj/machinery/light/small{active_power_usage = 0; dir = 4; icon_state = "bulb-broken"; status = 2},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"ew" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/canister,/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plasteel,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"ex" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/visible{dir = 4; initialize_directions = 11; level = 2},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"ey" = (/obj/structure/table/reinforced,/obj/structure/alien/weeds,/obj/machinery/computer/security/telescreen{desc = "Used for watching the contents of the xenobiology containment pen."; dir = 8; name = "xenobiology monitor"; network = list("MO19X")},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"ey" = (/obj/structure/table/reinforced,/obj/structure/alien/weeds,/obj/machinery/computer/security/telescreen{desc = "Used for watching the contents of the xenobiology containment pen."; dir = 8; name = "xenobiology monitor"; network = list("MO19X")},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"ez" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id_tag = "Awaylab"; name = "Acid-Proof containment chamber blast door"; unacidable = 1},/obj/structure/cable,/obj/structure/grille,/obj/structure/window/full/reinforced,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eA" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"},/turf/simulated/wall/r_wall,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eB" = (/obj/structure/alien/weeds,/obj/structure/stool/bed/nest,/obj/item/clothing/mask/facehugger{icon_state = "facehugger_impregnated"; item_state = "facehugger_impregnated"; stat = 2},/obj/effect/decal/cleanable/blood/gibs{color = "red"; icon_state = "gib2_flesh"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
@@ -243,52 +243,52 @@
"eI" = (/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eJ" = (/turf/simulated/wall,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eK" = (/turf/simulated/wall/rust,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"eL" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"eM" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"eN" = (/obj/machinery/light/small{active_power_usage = 0; dir = 8; icon_state = "bulb-broken"; status = 2},/obj/machinery/camera{c_tag = "Xenobiology"; dir = 4; network = list("MO19","MO19R")},/turf/simulated/floor/plasteel{dir = 6; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"eL" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"eM" = (/obj/structure/grille,/obj/machinery/door/poddoor{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id_tag = "Awaybiohazard"; layer = 2.9; name = "Acid-Proof biohazard containment door"; unacidable = 1},/obj/structure/window/full/reinforced,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"eN" = (/obj/machinery/light/small{active_power_usage = 0; dir = 8; icon_state = "bulb-broken"; status = 2},/obj/machinery/camera{c_tag = "Xenobiology"; dir = 4; network = list("MO19","MO19R")},/turf/simulated/floor/plasteel{dir = 6; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/visible,/obj/structure/stool/bed/chair/office/light{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"eP" = (/obj/structure/table/reinforced,/obj/machinery/door_control{id = "Awaylab"; name = "Containment Chamber Blast Doors"; pixel_x = 4; pixel_y = -2; req_access_txt = "201"},/obj/machinery/ignition_switch{id = "awayxenobio"; pixel_x = 4; pixel_y = 8},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"eP" = (/obj/structure/table/reinforced,/obj/machinery/door_control{id = "Awaylab"; name = "Containment Chamber Blast Doors"; pixel_x = 4; pixel_y = -2; req_access_txt = "201"},/obj/machinery/ignition_switch{id = "awayxenobio"; pixel_x = 4; pixel_y = 8},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eQ" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eR" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/cleanable/blood{color = "red"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eS" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"eT" = (/obj/machinery/power/port_gen/pacman{desc = "A portable generator for emergency backup power."; name = "P.A.C.M.A.N.-type portable generator"},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"eU" = (/obj/machinery/space_heater,/obj/machinery/light/small{dir = 1},/obj/structure/sign/poster{icon_state = "poster5_legit"; pixel_x = 0; pixel_y = 32; serial_number = 21; subtype = 1},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"eV" = (/obj/machinery/power/port_gen/pacman/super{desc = "A portable generator for emergency backup power."; name = "S.U.P.E.R.P.A.C.M.A.N.-type portable generator"},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg2"; tag = "icon-platingdmg2"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"eW" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/power/smes{charge = 1.5e+006; input_level = 10000; inputting = 0; output_level = 15000; outputting = 1},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"eX" = (/obj/machinery/power/terminal{dir = 4},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/alarm/monitor{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"eY" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"eZ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg1"; tag = "icon-platingdmg1"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fa" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/item/weapon/newspaper,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fb" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fc" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; dir = 8; icon_state = "ltrails_1"},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fd" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; dir = 5; icon_state = "ltrails_1"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fe" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/airlock/maintenance{req_access_txt = "201"; req_one_access_txt = "0"},/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; dir = 8; icon_state = "ltrails_1"},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"ff" = (/obj/structure/sign/securearea{pixel_x = 32},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fg" = (/obj/structure/table,/obj/item/stack/sheet/mineral/plasma{layer = 2.9},/obj/machinery/light/small{active_power_usage = 0; dir = 1; icon_state = "bulb-broken"; status = 2},/obj/machinery/alarm/monitor{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fh" = (/obj/structure/table,/obj/machinery/reagentgrinder,/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fi" = (/obj/structure/closet/crate/freezer,/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/item/clothing/mask/facehugger{icon_state = "facehugger_impregnated"; item_state = "facehugger_impregnated"; stat = 2},/obj/item/xenos_claw,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"eT" = (/turf/simulated/wall,/area/awaycontent/a7)
+"eU" = (/turf/simulated/wall/rust,/area/awaycontent/a7)
+"eV" = (/turf/simulated/wall/r_wall,/area/awaycontent/a7)
+"eW" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; layer = 2.4; on = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"eX" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"eY" = (/obj/machinery/power/port_gen/pacman{desc = "A portable generator for emergency backup power."; name = "P.A.C.M.A.N.-type portable generator"},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating,/area/awaycontent/a7)
+"eZ" = (/obj/machinery/space_heater,/obj/machinery/light/small{dir = 1},/obj/structure/sign/poster{icon_state = "poster5_legit"; pixel_x = 0; pixel_y = 32; serial_number = 21; subtype = 1},/turf/simulated/floor/plating,/area/awaycontent/a7)
+"fa" = (/obj/machinery/power/port_gen/pacman/super{desc = "A portable generator for emergency backup power."; name = "S.U.P.E.R.P.A.C.M.A.N.-type portable generator"},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg2"; tag = "icon-platingdmg2"},/area/awaycontent/a7)
+"fb" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/power/smes{charge = 1.5e+006; input_level = 10000; inputting = 0; output_level = 200000; outputting = 0},/turf/simulated/floor/plating,/area/awaycontent/a7)
+"fc" = (/obj/machinery/power/terminal{dir = 4},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/alarm/monitor{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/turf/simulated/floor/plating,/area/awaycontent/a7)
+"fd" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; dir = 5; icon_state = "ltrails_1"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"fe" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating,/area/awaycontent/a7)
+"ff" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg1"; tag = "icon-platingdmg1"},/area/awaycontent/a7)
+"fg" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/item/weapon/newspaper,/turf/simulated/floor/plating,/area/awaycontent/a7)
+"fh" = (/obj/structure/table,/obj/machinery/reagentgrinder,/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"fi" = (/obj/structure/closet/crate/freezer,/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/item/clothing/mask/facehugger{icon_state = "facehugger_impregnated"; item_state = "facehugger_impregnated"; stat = 2},/obj/item/xenos_claw,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"fj" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/structure/table,/obj/item/weapon/storage/box/beakers{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/box/syringes,/obj/structure/alien/weeds,/turf/simulated/floor/plasteel,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fk" = (/obj/machinery/door/firedoor,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"fk" = (/obj/machinery/door/firedoor,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"fl" = (/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"fm" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fn" = (/obj/structure/closet/l3closet/scientist,/obj/structure/window/reinforced,/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"fn" = (/obj/structure/closet/l3closet/scientist,/obj/structure/window/reinforced,/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"fo" = (/obj/structure/cable,/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id_tag = "Awaylab"; name = "Acid-Proof containment chamber blast door"; unacidable = 1},/obj/structure/grille,/obj/structure/window/full/reinforced,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"fp" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"fq" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/stool/bed/nest,/obj/item/clothing/mask/facehugger{icon_state = "facehugger_impregnated"; item_state = "facehugger_impregnated"; stat = 2},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fr" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fs" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/generic,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"ft" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg1"; tag = "icon-platingdmg1"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fu" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fv" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fw" = (/obj/structure/extinguisher_cabinet{pixel_x = -26},/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; icon_state = "ltrails_2"},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fx" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{density = 0; emagged = 1; icon_state = "door_open"; locked = 1; name = "Xenobiology Lab"; opacity = 0; req_access_txt = "201"},/turf/simulated/floor/plasteel,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fy" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/alien/weeds,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fz" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"fr" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/awaycontent/a7)
+"fs" = (/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; dir = 8; icon_state = "ltrails_1"},/turf/simulated/floor/plating,/area/awaycontent/a7)
+"ft" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/airlock/maintenance{req_access_txt = "271"; req_one_access_txt = "0"},/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; dir = 8; icon_state = "ltrails_1"},/turf/simulated/floor/plating,/area/awaycontent/a7)
+"fu" = (/obj/structure/sign/securearea{pixel_x = 32},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"fv" = (/obj/structure/table,/obj/item/stack/sheet/mineral/plasma{amount = 20; layer = 2.9},/obj/machinery/light/small{active_power_usage = 0; dir = 1; icon_state = "bulb-broken"; status = 2},/obj/machinery/alarm/monitor{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"fw" = (/obj/structure/extinguisher_cabinet{pixel_x = -26},/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; icon_state = "ltrails_2"},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"fx" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating,/area/awaycontent/a7)
+"fy" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/generic,/turf/simulated/floor/plating,/area/awaycontent/a7)
+"fz" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"fA" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fB" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"fB" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"fC" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/alien/weeds/node,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"fD" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/visible{dir = 5},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fE" = (/obj/machinery/atmospherics/pipe/simple/visible{desc = "A one meter section of pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof Pipe"; unacidable = 1},/obj/item/stack/rods,/obj/item/stack/cable_coil{amount = 5},/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"fE" = (/obj/machinery/atmospherics/pipe/simple/visible{desc = "A one meter section of pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof Pipe"; unacidable = 1},/obj/item/stack/rods,/obj/item/stack/cable_coil{amount = 5},/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"fF" = (/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id_tag = "Awaylab"; name = "Acid-Proof containment chamber blast door"; unacidable = 1},/obj/machinery/atmospherics/pipe/simple/visible{desc = "A one meter section of pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof Pipe"; unacidable = 1},/obj/item/stack/rods,/obj/item/stack/cable_coil{amount = 5},/obj/item/weapon/shard{icon_state = "medium"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"fG" = (/obj/machinery/atmospherics/pipe/simple/visible{desc = "A one meter section of pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof Pipe"; unacidable = 1},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"fH" = (/obj/machinery/atmospherics/pipe/simple/visible{desc = "A one meter section of pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof Pipe"; unacidable = 1},/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/cleanable/blood{color = "red"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
@@ -296,328 +296,328 @@
"fJ" = (/obj/machinery/atmospherics/pipe/simple/visible{desc = "A one meter section of pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof Pipe"; unacidable = 1},/obj/structure/alien/weeds,/obj/structure/alien/resin/wall,/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"fK" = (/obj/machinery/atmospherics/unary/outlet_injector{desc = "Has a valve and pump attached to it. This one has been applied with an acid-proof coating."; dir = 8; icon_state = "on"; name = "Acid-Proof Air Injector"; on = 1; unacidable = 1},/obj/structure/alien/weeds,/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"fL" = (/obj/machinery/light{active_power_usage = 0; dir = 4; icon_state = "tube-broken"; status = 2},/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/machinery/camera{c_tag = "Xenobiology Containment East"; dir = 8; network = list("MO19X")},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fM" = (/obj/machinery/portable_atmospherics/scrubber,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fN" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fO" = (/obj/item/weapon/cigbutt,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fP" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fQ" = (/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fR" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/effect/decal/cleanable/blood/oil{color = "black"},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fS" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "0"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fT" = (/obj/structure/filingcabinet,/obj/item/weapon/paper{info = "Entry One — 27/05/2554: I just arrived, and already I hate my job. I'm stuck on this shithole of an outpost, trying to avoid these damn eggheads running all over the place preparing for god knows what. There's no crimes to stop, no syndies to kill, and I'm not even allowed to beat the fuckin' assistant senseless! They said I was transferred from Space Station 13 for 'good behavior', but this feels more like a punishment than a reward. All I know is that if I don't get some action soon, I'm going to go insane.
Entry Two — 03/06/2554: Okay, so get this: we got a fuckin' deathsquad coming in today! I thought the day I saw one of them would be the day my employment was 'terminated', if you get my drift. They're escorting some sort of weird alien creature for the eggheads to study. I heard one of the docs telling the chef that this thing killed a whole security force before it was captured. I sure as hell hope that I don't have to fight it.
Entry Three — 08/06/2554: My first real bit of 'action' today, if you could call it that. Crazy Ivan got in a fight with Kuester today about his Booze-O-Mat. Apparently one of the crewmembers had stolen a couple bottles of booze from the machine after Ivan disabled the ID lock. Tell you the truth, I don't blame the thief. Everyone is going a little stir-crazy in here, and the bartender is being damn stingy with the alcohol. Either way, once they started to pick a fight, I had to take them down. It's a damn shame that we don't have a brig, though. I had to lock Ivan in a fuckin' freezer, for god's sake. Let's hope that we can keep our sanity together, at least for a while.
Entry Four — 10/06/2554: Jesus fucking Christ riding on a motorbike. These things the scientists are studying are terrifying! Fucking great huge purple bug things as tall as the ceiling, with blades for arms and drooling at the mouth. I don't think my taser will do jack shit against these damn things, but the eggheads say that they're safely contained. If they do, I have a feeling that it's only a matter of time before we're all screwed. These bastards look like walking death.
Entry Five — 18/06/2554: Finally caught who stole the booze from Kuester. It was that fuckin' loser assistant Steve! He was in the dorms, chugging his worries away. I took one of the bottles back to the barkeep, but no one has to know about this second one. I think I'm gonna enjoy this while watching tomorrow's Thunderdome match.
Entry Six — 19/06/2554: Oh, great. The chef is still sleeping, so we get Ivan's gruel for breakfast today. I overheard Sano and Douglas saying something about the aliens being restless, so we might get some action today. As long as it happens after the big game, I'm fine with it. I still got one beer to drink before I'm ready to die."; name = "Personal Log — Kenneth Cunningham"},/turf/simulated/floor/plasteel{dir = 9; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fU" = (/obj/structure/sign/poster{icon_state = "poster21_legit"; pixel_y = 32; serial_number = 21; subtype = 1},/obj/item/device/radio/off,/obj/item/weapon/screwdriver{pixel_y = 10},/turf/simulated/floor/plasteel{dir = 5; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fV" = (/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/item/clothing/suit/armor/vest,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/grenade/flashbang,/obj/item/weapon/storage/belt/security,/obj/item/weapon/reagent_containers/food/drinks/cans/beer{pixel_x = -3; pixel_y = -2},/obj/machinery/alarm/monitor{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/turf/simulated/floor/plasteel{dir = 1; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fW" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"fM" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg1"; tag = "icon-platingdmg1"},/area/awaycontent/a7)
+"fN" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating,/area/awaycontent/a7)
+"fO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/awaycontent/a7)
+"fP" = (/turf/simulated/wall/r_wall/rust,/area/awaycontent/a7)
+"fQ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{density = 0; emagged = 1; icon_state = "door_open"; locked = 1; name = "Xenobiology Lab"; opacity = 0; req_access_txt = "271"},/turf/simulated/floor/plasteel,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"fR" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/alien/weeds,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"fS" = (/obj/structure/table,/obj/item/clothing/gloves/color/yellow,/turf/simulated/floor/plating,/area/awaycontent/a7)
+"fT" = (/obj/structure/filingcabinet,/obj/item/weapon/paper{info = "Entry One — 27/05/2554: I just arrived, and already I hate my job. I'm stuck on this shithole of an outpost, trying to avoid these damn eggheads running all over the place preparing for god knows what. There's no crimes to stop, no syndies to kill, and I'm not even allowed to beat the fuckin' assistant senseless! They said I was transferred from Space Station 13 for 'good behavior', but this feels more like a punishment than a reward. All I know is that if I don't get some action soon, I'm going to go insane.
Entry Two — 03/06/2554: Okay, so get this: we got a fuckin' deathsquad coming in today! I thought the day I saw one of them would be the day my employment was 'terminated', if you get my drift. They're escorting some sort of weird alien creature for the eggheads to study. I heard one of the docs telling the chef that this thing killed a whole security force before it was captured. I sure as hell hope that I don't have to fight it.
Entry Three — 08/06/2554: My first real bit of 'action' today, if you could call it that. Crazy Ivan got in a fight with Kuester today about his Booze-O-Mat. Apparently one of the crewmembers had stolen a couple bottles of booze from the machine after Ivan disabled the ID lock. Tell you the truth, I don't blame the thief. Everyone is going a little stir-crazy in here, and the bartender is being damn stingy with the alcohol. Either way, once they started to pick a fight, I had to take them down. It's a damn shame that we don't have a brig, though. I had to lock Ivan in a fuckin' freezer, for god's sake. Let's hope that we can keep our sanity together, at least for a while.
Entry Four — 10/06/2554: Jesus fucking Christ riding on a motorbike. These things the scientists are studying are terrifying! Fucking great huge purple bug things as tall as the ceiling, with blades for arms and drooling at the mouth. I don't think my taser will do jack shit against these damn things, but the eggheads say that they're safely contained. If they do, I have a feeling that it's only a matter of time before we're all screwed. These bastards look like walking death.
Entry Five — 18/06/2554: Finally caught who stole the booze from Kuester. It was that fuckin' loser assistant Steve! He was in the dorms, chugging his worries away. I took one of the bottles back to the barkeep, but no one has to know about this second one. I think I'm gonna enjoy this while watching tomorrow's Thunderdome match.
Entry Six — 19/06/2554: Oh, great. The chef is still sleeping, so we get Ivan's gruel for breakfast today. I overheard Sano and Douglas saying something about the aliens being restless, so we might get some action today. As long as it happens after the big game, I'm fine with it. I still got one beer to drink before I'm ready to die."; name = "Personal Log — Kenneth Cunningham"},/turf/simulated/floor/plasteel{dir = 9; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"fU" = (/obj/structure/sign/poster{icon_state = "poster21_legit"; pixel_y = 32; serial_number = 21; subtype = 1},/obj/item/device/radio/off,/obj/item/weapon/screwdriver{pixel_y = 10},/turf/simulated/floor/plasteel{dir = 5; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"fV" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/awaycontent/a7)
+"fW" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"fX" = (/obj/structure/grille,/obj/structure/window/full/reinforced,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fY" = (/obj/structure/sign/biohazard{pixel_x = 32},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fZ" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"ga" = (/obj/machinery/door/firedoor,/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = -29},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gb" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/closet/l3closet/scientist,/obj/structure/alien/weeds,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"fY" = (/obj/item/weapon/cigbutt,/turf/simulated/floor/plating,/area/awaycontent/a7)
+"fZ" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/awaycontent/a7)
+"ga" = (/turf/simulated/floor/plating,/area/awaycontent/a7)
+"gb" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/closet/l3closet/scientist,/obj/structure/alien/weeds,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"gc" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/grille,/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id_tag = "Awaylab"; name = "Acid-Proof containment chamber blast door"; unacidable = 1},/obj/item/stack/cable_coil/cut{amount = 1; icon_state = "coil_red1"; item_state = "coil_red1"},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"gd" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/cleanable/blood{color = "red"},/obj/item/stack/rods,/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"ge" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 4; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"gf" = (/obj/structure/alien/weeds,/obj/structure/stool/bed/nest,/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 4; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"gg" = (/obj/structure/alien/weeds,/obj/structure/stool/bed/nest,/obj/item/clothing/mask/facehugger{icon_state = "facehugger_impregnated"; item_state = "facehugger_impregnated"; stat = 2},/obj/effect/decal/cleanable/blood/gibs{color = "red"; icon_state = "gibdown1_flesh"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gh" = (/obj/structure/stool,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gi" = (/obj/effect/decal/cleanable/blood/oil{color = "black"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gj" = (/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gk" = (/obj/structure/reagent_dispensers/peppertank{pixel_x = -30; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gl" = (/turf/simulated/floor/plasteel{dir = 4; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gm" = (/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gn" = (/obj/machinery/door/airlock/glass_security{name = "Security Post"; req_access_txt = "201"},/turf/simulated/floor/plasteel{ icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"go" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/firealarm{dir = 4; pixel_x = 28},/obj/structure/alien/weeds,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gp" = (/obj/structure/alien/weeds/node,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gq" = (/obj/structure/table,/obj/item/weapon/scalpel{pixel_y = 12},/obj/item/weapon/circular_saw,/obj/item/weapon/razor{pixel_y = 5},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gr" = (/obj/structure/table,/obj/item/device/mmi,/obj/item/device/mmi,/obj/item/device/mmi,/obj/structure/alien/weeds,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gs" = (/turf/simulated/floor/plasteel{dir = 1; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gh" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/effect/decal/cleanable/blood/oil{color = "black"},/turf/simulated/floor/plating,/area/awaycontent/a7)
+"gi" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "0"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/awaycontent/a7)
+"gj" = (/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 = "271"},/obj/item/clothing/suit/armor/vest,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/grenade/flashbang,/obj/item/weapon/storage/belt/security,/obj/item/weapon/reagent_containers/food/drinks/cans/beer{pixel_x = -3; pixel_y = -2},/obj/machinery/alarm/monitor{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/turf/simulated/floor/plasteel{dir = 1; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gk" = (/obj/structure/reagent_dispensers/peppertank{pixel_x = -30; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gl" = (/turf/simulated/floor/plasteel{dir = 4; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gm" = (/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/wall/r_wall/rust,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"go" = (/obj/structure/sign/biohazard{pixel_x = 32},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gp" = (/obj/structure/alien/weeds/node,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gq" = (/obj/structure/table,/obj/item/weapon/scalpel{pixel_y = 12},/obj/item/weapon/circular_saw,/obj/item/weapon/razor{pixel_y = 5},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gr" = (/obj/structure/table,/obj/item/device/mmi,/obj/item/device/mmi,/obj/item/device/mmi,/obj/structure/alien/weeds,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gs" = (/turf/simulated/floor/plasteel{dir = 1; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"gt" = (/obj/structure/sink{dir = 8; icon_state = "sink"; pixel_x = -12; pixel_y = 2},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gu" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{desc = "An underfloor disposal pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof disposal pipe"; unacidable = 1},/obj/structure/alien/weeds,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gu" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{desc = "An underfloor disposal pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof disposal pipe"; unacidable = 1},/obj/structure/alien/weeds,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"gv" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/disposalpipe/segment{desc = "An underfloor disposal pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof disposal pipe"; unacidable = 1},/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id_tag = "Awaylab"; name = "Acid-Proof containment chamber blast door"; unacidable = 1},/obj/structure/cable,/obj/structure/grille,/obj/structure/window/full/reinforced,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"gw" = (/obj/structure/disposalpipe/segment{desc = "An underfloor disposal pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof disposal pipe"; unacidable = 1},/obj/structure/alien/weeds,/obj/structure/alien/resin/wall,/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"gx" = (/obj/structure/disposalpipe/segment{desc = "An underfloor disposal pipe. This one has been applied with an acid-proof coating."; dir = 2; icon_state = "pipe-c"; name = "Acid-Proof disposal pipe"; unacidable = 1},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gy" = (/obj/structure/table,/obj/effect/decal/cleanable/dirt,/obj/machinery/cell_charger,/obj/item/weapon/stock_parts/cell/high,/obj/item/device/radio/off,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gy" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"gz" = (/turf/simulated/mineral/random/labormineral,/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"gA" = (/obj/machinery/light/small,/obj/structure/closet/toolcloset,/obj/item/clothing/gloves/color/yellow,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gB" = (/obj/structure/table,/obj/item/weapon/paper{info = "Ivan Volodin Stories:
Entry Won — 28/05/2554: Hello. I am Crazy Ivan. Boss say I must write. I do good job fixing outpost. Is very good job. Much better than mines. Many nice people. I cause no trouble.
Entry Too — 05/06/2554: I am finding problem with Booze-O-Mat. Is not problem. I solve very easy. Use yellow tool to make purple light go off. I am good engineer! Bartender will be very happy.
Entry Tree — 08/06/2554: Bartender is not happy. Security man is not happy. Cannot feel legs, is very cold in freezer. Is not good. Table is jammed into door, have no tools. Is very not good. But, on bright side, found meat! Shall chew to keep spirits up.
Entry Fore — 12/06/2554: Big nasty purple bug looked at me today. Make nervous. Blue wall wire can be broken, then bad thing happens. Very very bad thing. Man in orange spacesuit wave at me today too. He seem nice. Wonder who was?
Entry Fiv — 15/06/2554: I eat cornflakes today. Is good day. Sun shine for a while. Was nice. I also take ride on disposals chute. Was fun, but tiny. Get clog out of pipes, was vodka bottle. Is empty. This make many sads.
Entry Sex: 19/06/2554: Purple bugs jumpy today. When waved, get hiss. Maybe very bad. Maybe just ill. Do not know. Is science problem, is not engineer problem. I eat sandwich. Is glorious job. Wish to never end."; name = "Personal Log — Ivan Volodin"},/obj/item/weapon/pickaxe,/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gC" = (/obj/machinery/computer/monitor,/obj/structure/cable,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gD" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gE" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/newscaster/security_unit{pixel_x = -30; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gF" = (/obj/item/stack/rods,/obj/item/weapon/shard{icon_state = "small"},/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; dir = 8; icon_state = "ltrails_1"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gB" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gD" = (/obj/machinery/door/firedoor,/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = -29},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gE" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/newscaster/security_unit{pixel_x = -30; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gF" = (/obj/item/stack/rods,/obj/item/weapon/shard{icon_state = "small"},/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; dir = 8; icon_state = "ltrails_1"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"gG" = (/obj/effect/decal/cleanable/blood/splatter{color = "red"},/turf/simulated/floor/plasteel,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gH" = (/obj/structure/grille{density = 0; destroyed = 1; icon_state = "brokengrille"},/obj/item/stack/rods,/obj/item/stack/rods,/obj/item/weapon/shard,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gI" = (/obj/structure/table,/obj/item/weapon/retractor,/obj/item/weapon/hemostat,/obj/structure/alien/weeds,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gH" = (/obj/structure/grille/broken,/obj/item/stack/rods,/obj/item/stack/rods,/obj/item/weapon/shard,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gI" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"gJ" = (/obj/structure/table,/obj/machinery/light/small{active_power_usage = 0; dir = 4; icon_state = "bulb-broken"; status = 2},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"gK" = (/obj/structure/filingcabinet/filingcabinet,/obj/machinery/light/small{active_power_usage = 0; dir = 8; icon_state = "bulb-broken"; status = 2},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano Date: 04/06/2554
Report: As expected, all that is left of the monkeys we sent in earlier is a group of xenomorph larvae. It is quite clear that the facehuggers are not selective in their hosts, and so far the gestation process has been shown to have a 100% success rate.
The larvae themselves have been behaving very differently from the lone larva we first observed, and despite shying away from humans, they are clearly comfortable with others of their kind. Our previous suspicions on larvae have been confirmed with their demonstration of playfulness: they are not nearly as aggressive nor violent when young, before molting to adulthood.
The majority of the play we observed involved a sort of hide-and-seek, and occasionally wrestling by tangling themselves and struggling out of it. While normally we would write these off as instinctual play for honing their skills when they molt, their growth period is so incredibly fast and they are still such adept killers, that it would serve no practical purpose. The only explanation for this is perhaps to create bonds and friendships with each other, if that is even possible for such an incredibly hostile race. It may be that they are much more reasonable with each other than other life forms.
It had become clear that now was the best time to extract a xenomorph for dissecting, as these were all still larvae and the queen was still attached to its ovipositor and would be immobile. With the approval of the research director, we sent in our medical robot that had been dubbed 'Head Surgeon' into the containment pen, dropping the shields for only a fraction of a second to allow it entry. The larvae were cautious, but the curiosity of one had him within grabbing range of our robot. It was brought out and quickly euthanized through lethal injection, courtesy of our mechanical doctor."; name = "Larva Xenomorph Social Interactions & Capturing Procedure"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano Date: 04/06/2554
Report: I have studied many interesting and diverse life-forms as a xenobiologist, ranging from creatures as large as cows, to specimens too small see with the naked eye. This is by far the largest alien I have ever seen. The alien we were previously studying has molted and has become an absolutely enormous creature. Standing at over 15 feet tall, and weighing in at likely two tons or more, the xenomorph queen is an absolutely breathtakingly large and cruel monster. Its behavior has changed drastically from when it was a drone, having become far more comfortable with sitting and staring at us, rather than smashing at the windows.
The queen, physiologically speaking, is fairly similar to the other xenomorphs, with a few key differences. Its enormous size demands large legs, while the back seems to be always hunched forward. The dorsal tubes on the back have changed to several large spikes, and we observed that the alien now sports a second pair of smaller arms on its chest. The purpose of these secondary arms is still unknown. Finally, the queen's crown has become incredibly large, with what seems to be a retractable slot to hide its head in. The dome appears to be extremely thick near the front, and will likely be able to resist a lot of trauma. Despite the enormous size it has grown to, it is not much slower than it used to be.
After two hours of doing relatively nothing but staring, the queen began to produce an unusually large amount of resin and weeds, quickly shaping up a large nest, that it then hid behind. It then proceeded to smash out all the lights, leaving us with very little to see with our cameras. When we looked through the back cameras, we had discovered that it had grown a large ovipositor, and was releasing large eggs onto the ground. This had us all in agreement that this stage of the life cycle was the queen.
Over the next few hours, the eggs grew to their full sizes, and we provided the subject with new monkey hosts. When they approached the eggs, they opened to release more facehuggers. It seems that we have observed the full cycle of reproduction for this species. We can expect more larvae in the next few hours."; name = "Queen Xenomorph Physiology & Behavior Observation"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano Date: 03/06/2554
Report: The other scientists and I can hardly believe our eyes. The snake-like larva has molted into a 7 foot tall insectoid nightmare in just a few hours. It's obvious now as to why such heavy duty containment was needed. It immediately tried to escape, however, by flinging itself at the window in a flurry of swipes and stabs. It seems its behavior has returned to a state that is very similar to the facehugger, though I doubt with the same intent! Thankfully, our glass and shields have shown to be more than sturdy enough for such a violent creature, and so far, any attempts at the creature escaping have been in vain.
As for its physiology, the creature has an elongated head, with what appears to be have an exoskeleton resembling an external rib-cage on the torso. The alien is also fairly skinny with a lean body. The little amount of meat on the alien appears to be entirely muscle. We assume this makes it deceptively strong, while remaining agile at the same time. One of the most interesting things we have seen is its pharyngeal jaw. It has somewhat of an inner mouth, capable of being fired externally at extremely high speeds. It has already caused many dents in the walls and a few small cracks in the window with it. The alien also has a couple of dorsal tubes on its back, their purpose unknown. Finally, this monster sports a long ridged tail, complete with a large and extremely sharp blade at the tip.
Normally I would be absolutely terrified of something like this, but I'm putting my trust in Nanotrasen with the containment. After all, they wouldn't build a cell that could fail to contain its subject – would they?"; name = "Adult Xenomorph Physiology & Behavior Observation"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano Date: 03/06/2554
Report: When the larva first emerged from the chest of the monkey, it seemed very curious. It would wander around aimlessly for awhile and then sit still. We are unable to determine the gender of the larva, or even determine if it has a gender. After some time had passed, it seemed to lose interest in its surroundings and sat mostly still while occasionally wagging its tail. We decided to throw in a live mouse to see if it would consume it. The larva quickly attacked and ate the mouse, and seemed to get larger very suddenly; this suggests that the larvae are capable of metabolizing and directing all the energy towards growth at previously-thought impossible speeds. It is a shame that we cannot observe the process more closely, as we do not currently know how dangerous or violent this creature is, or will become, as it matures fully.
It is tempting to imagine the possibilities of utilizing such a mechanism. The capability of skipping years of growth time for children, repairing bodily damage in a matter of moments, even its usage in existing cloning technology."; name = "Larva Xenomorph Physiology & Behavior Observation"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano Date: 03/06/2554
Report: The test subject we were provided with truly is alien. It is a small spider-like creature with bony legs, leading to a smooth body. It has a long tail connected to it, and it has shown extremely aggressive behavior by flinging its entire body at the glass and shields to no avail. While doing so, we noticed there was a small pink hole in the middle of the body.
When we sent in a monkey through the crude but effective disposal tube, the alien immediately jumped at its face and latched on. The monkey was quickly suffocated by its constricting tail, unable to pry off the fingers. The monkey at first seemed to be dead, but was observed to be breathing. The recently named alien 'facehugger' fell off, dead, and curled its legs up like a spider moments after it had finished with the monkey's body.
While the monkey appeared to be unharmed, we kept it in the cell for a couple more hours, until we were horrified to discover it screaming out in pain, as a snake-like creature erupted from the monkey's chest! It appears that the 'facehugger' is only the start of this life cycle. The impregnation cycle involving the creatures growing inside the chests of their hosts seems to only be the beginning."; name = "'Facehugger' Xenomorph Physiology & Behavior Observation"},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gL" = (/obj/structure/cable,/obj/machinery/power/apc/noalarm{cell_type = 15000; dir = 4; locked = 0; name = "Worn-out APC"; pixel_x = 25; req_access = null; start_charge = 100},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gM" = (/obj/structure/table/reinforced,/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/obj/item/device/radio/off,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gL" = (/obj/structure/stool,/turf/simulated/floor/plating,/area/awaycontent/a7)
+"gM" = (/obj/structure/table/reinforced,/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/obj/item/device/radio/off,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"gN" = (/obj/structure/disposalpipe/segment{desc = "An underfloor disposal pipe. This one has been applied with an acid-proof coating."; name = "Acid-Proof disposal pipe"; unacidable = 1},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"gO" = (/obj/structure/cable,/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id_tag = "Awaylab"; name = "Acid-Proof containment chamber blast door"; unacidable = 1},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/grille,/obj/structure/window/full/reinforced,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gP" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/item/stack/rods,/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gQ" = (/obj/machinery/door_control{id = "Awaybiohazard"; name = "Biohazard Shutter Control"; pixel_x = -25; pixel_y = 0; req_access_txt = "201"},/obj/machinery/light/small{dir = 8},/obj/machinery/computer/security{desc = "Used to access the various cameras on the outpost."; network = list("MO19R","MO19")},/turf/simulated/floor/plasteel{dir = 8; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gR" = (/obj/structure/table,/obj/machinery/recharger{pixel_y = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gP" = (/obj/effect/decal/cleanable/blood/oil{color = "black"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/power/apc/noalarm{cell_type = 15000; dir = 4; locked = 0; name = "Maintenance APC"; pixel_x = 25; req_access = null; start_charge = 100},/obj/structure/cable,/turf/simulated/floor/plating,/area/awaycontent/a7)
+"gQ" = (/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a7)
+"gR" = (/obj/structure/table,/obj/machinery/recharger{pixel_y = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"gS" = (/obj/structure/stool/bed/chair/office/dark,/turf/simulated/floor/plasteel,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gT" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gU" = (/obj/machinery/light{active_power_usage = 0; dir = 4; icon_state = "tube-broken"; status = 2},/obj/machinery/alarm/monitor{dir = 8; frequency = 1439; locked = 0; pixel_x = 23; pixel_y = 0; req_access = null},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gV" = (/obj/machinery/optable,/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gW" = (/obj/structure/table,/obj/item/clothing/gloves/color/latex,/obj/item/clothing/mask/surgical,/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gT" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gU" = (/obj/machinery/door/airlock/glass_security{name = "Security Post"; req_access_txt = "271"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gV" = (/obj/machinery/optable,/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gW" = (/obj/structure/table,/obj/item/clothing/gloves/color/latex,/obj/item/clothing/mask/surgical,/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"gX" = (/obj/structure/filingcabinet/filingcabinet,/obj/item/weapon/paper{info = "Researcher: Dr. Mark Douglas Date: 17/06/2554
Report: Earlier today we have observed a new phenomenon with our subjects. While feeding them our last monkey subject and throwing out the box, the aliens merely looked at us, instead of infecting the monkey right away. They looked to be collectively distressed as they would no longer be given hosts, where instead we would move to the next phase of the experiment. When I glanced at the gas tanks and piping leading to their cell, I looked back to see all of them were up against the glass, even the queen! It was as if they all understood what was going to happen, even though we knew only the queen had the cognitive capability to do so.
The only explanation for this is a form of communication between the aliens, but we have seen no such action take place anywhere in the cell until now. We also know that regular drone and hunter xenomorphs have no personality or instinct to survive by themselves. Perhaps the queen has a direct link to them? A form of a commander or overseer that controls their every move? A hivemind?"; name = "The Hivemind Hypothesis"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano Date: 08/06/2554
Report: The xenomorphs we have come to study here are a remarkable species. They are almost universally aggressive across all castes, showing no remorse or guilt or pause before or after acts of violence. They appear to be a species entirely designed to kill. Oddly enough, even their method of reproduction is a brutal two-for-one method of birthing a new xenomorph and killing its host.
The lone xenomorph we studied only five days ago showed little sign of intelligence. Only a simple drone that flung itself at the safety glass and shields repeatedly and thankfully without success. Once the drone molted into a queen, it became much more calm and calculating, merely looking at us and waiting while building its nest. As the hive grew in size and in numbers, so too did the intelligence of the common hunter and drone. We are still researching how they can communicate with one another and the relationship between the different castes and the queen. We will continue to update our research as we learn more about the species."; name = "A Preliminary Study of Alien Behavior"},/obj/item/weapon/paper{info = "Researcher: Dr. Mark Douglas Date: 06/06/2554
Report: While observing the growing number of aliens in the containment cell, we began to notice subtle differences that were consistently repeating. Like ants, these creatures clearly have different specialized variations that determine their roles in the hive. We have dubbed the three currently observed castes as Hunters, Drones, and Sentinels.
Hunters have been observed to be by far the most aggressive and agile of the three, constantly running on every surface and frequently swiping at the windows. They are also remarkably good at camouflaging themselves in darkness and on their resin structures, appearing almost invisible to the unwary observer. They are always the first to reach the monkeys we send in leading us to believe that this caste is primarily used for finding and retrieving hosts.
Drones on the other hand are much more docile and seem more shy by comparison, though not any less aggressive than the other castes. They have been observed to have a much wider head and lack dorsal tubes. They have shown to be less agile and visibly more fragile than any other caste. The drone however has never been observed to interact with the monkeys directly and instead preferring maintenance of the hive by building walls of resin and moving eggs around the nest. As far as we know, we have only ever observed a drone become a queen, and we have no way of knowing if the other castes have that capability.
Lastly, we have the Sentinels, which appear at first glance to be the guards of the hive. They have so far been only observed to remain near the queen and the eggs, frequently curled up against the walls. We have only observed one instance where they have interacted with a monkey who strayed too closely to the queen, and was pounced and held down immediately until it was applied with a facehugger. Their lack of movement makes it difficult to determine their exact purpose as guards, sentries, or other role."; name = "The Xenomorph 'Castes'"},/obj/item/weapon/paper{info = "Researcher: Dr. Mark Douglas Date: 04/06/2554
Report: After an extremely dangerous, time consuming and costly dissection, we have managed to record and identify several of the organs inside of the first stage of the xenomorph cycle: the larva. This procedure took an extensive amount of time because these creatures have incredibly, almost-comically acidic blood that can melt through almost anything in a few moments. We had to use over a dozen scalpels and retractors to complete the autopsy.
The larva seems to possess far fewer and quite different organs than that of a human. There is a stomach, with no digestive tract, a heart, which seems to lack any blood-oxygen circulation purpose, and an elongated brain, even though its as dumb as any large cat. It also lacks any liver, kidneys, or other basic organs.
We can't determine the exact nature of how these creatures grow, nor if they gain organs as they become adults. The larger breeds of xenomorph are too dangerous to kill and capture to give us an accurate answer to these questions. All that we can conclude is that being able to function with so little and yet be so deadly means that these creatures are highly evolved and likely to be extremely durable to various hazards that would otherwise be lethal to humans."; name = "Larva Xenomorph Autopsy Report"},/obj/structure/alien/weeds,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"gY" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"gZ" = (/obj/machinery/computer/operating,/obj/structure/alien/weeds,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"ha" = (/obj/effect/decal/cleanable/dirt,/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"gZ" = (/obj/machinery/computer/operating,/obj/structure/alien/weeds,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"ha" = (/obj/effect/decal/cleanable/dirt,/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"hb" = (/obj/structure/disposaloutlet{desc = "An outlet for the pneumatic disposal system. This one has been applied with an acid-proof coating."; dir = 1; name = "Acid-Proof disposal outlet"; unacidable = 1},/obj/structure/disposalpipe/trunk{desc = "An underfloor disposal pipe. This one has been applied with an acid-proof coating."; dir = 1; name = "Acid-Proof disposal pipe"; unacidable = 1},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"hc" = (/obj/machinery/light{active_power_usage = 0; dir = 2; icon_state = "tube-broken"; status = 2},/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/machinery/camera{c_tag = "Xenobiology Containment South"; dir = 1; network = list("MO19X")},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"hd" = (/obj/machinery/sparker{desc = "A wall-mounted ignition device. This one has been applied with an acid-proof coating."; id = "awayxenobio"; name = "Acid-Proof mounted igniter"; pixel_x = 0; pixel_y = -25; unacidable = 1},/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/resin/wall,/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"he" = (/obj/machinery/shieldwallgen{locked = 0; req_access = null},/obj/structure/cable,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hf" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hg" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hh" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hi" = (/obj/structure/table,/obj/item/weapon/book/manual/security_space_law,/obj/machinery/computer/security/telescreen/entertainment{pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 10; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hj" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/turf/simulated/floor/plasteel{dir = 6; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hk" = (/obj/structure/table,/obj/item/weapon/folder/red,/turf/simulated/floor/plasteel{ icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hl" = (/obj/structure/closet/secure_closet{icon_broken = "secureresbroken"; icon_closed = "secureres"; icon_locked = "secureres1"; icon_off = "secureresoff"; icon_opened = "secureresopen"; icon_state = "secureres"; locked = 0; name = "scientist's locker"; req_access_txt = "201"},/obj/item/clothing/suit/storage/labcoat,/turf/simulated/floor/plasteel,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hm" = (/turf/simulated/floor/plasteel{ icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hn" = (/obj/structure/window/reinforced,/obj/structure/closet/secure_closet{icon_broken = "secureresbroken"; icon_closed = "secureres"; icon_locked = "secureres1"; icon_off = "secureresoff"; icon_opened = "secureresopen"; icon_state = "secureres1"; locked = 1; name = "scientist's locker"; req_access_txt = "201"},/obj/item/clothing/suit/storage/labcoat,/obj/item/weapon/tank/air,/obj/item/clothing/mask/gas,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"ho" = (/obj/machinery/vending/medical{req_access_txt = "201"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hp" = (/obj/structure/closet/crate/bin,/obj/item/clothing/gloves/color/latex,/obj/item/trash/chips,/obj/effect/decal/cleanable/dirt,/obj/machinery/light/small{active_power_usage = 0; dir = 1; icon_state = "bulb-broken"; status = 2},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hq" = (/obj/structure/table,/obj/item/weapon/storage/box/gloves{pixel_x = 0; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hr" = (/obj/structure/closet/secure_closet{icon_broken = "rdsecurebroken"; icon_closed = "rdsecure"; icon_locked = "rdsecure1"; icon_off = "rdsecureoff"; icon_opened = "rdsecureopen"; icon_state = "rdsecure1"; locked = 1; name = "research director's locker"; req_access_txt = "201"},/obj/item/weapon/storage/backpack/satchel_tox,/obj/item/clothing/gloves/color/latex,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"hf" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/firealarm{dir = 4; pixel_x = 28},/obj/structure/alien/weeds,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"hg" = (/obj/structure/table,/obj/effect/decal/cleanable/dirt,/obj/machinery/cell_charger,/obj/item/weapon/stock_parts/cell/high,/obj/item/device/radio/off,/turf/simulated/floor/plating,/area/awaycontent/a7)
+"hh" = (/obj/machinery/light/small,/obj/structure/closet/toolcloset,/turf/simulated/floor/plating,/area/awaycontent/a7)
+"hi" = (/obj/structure/table,/obj/item/weapon/book/manual/security_space_law,/obj/machinery/computer/security/telescreen/entertainment{pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 10; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"hj" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/turf/simulated/floor/plasteel{dir = 6; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"hk" = (/obj/structure/table,/obj/item/weapon/folder/red,/turf/simulated/floor/plasteel{icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"hl" = (/obj/structure/table,/obj/item/weapon/paper{info = "Ivan Volodin Stories:
Entry Won — 28/05/2554: Hello. I am Crazy Ivan. Boss say I must write. I do good job fixing outpost. Is very good job. Much better than mines. Many nice people. I cause no trouble.
Entry Too — 05/06/2554: I am finding problem with Booze-O-Mat. Is not problem. I solve very easy. Use yellow tool to make purple light go off. I am good engineer! Bartender will be very happy.
Entry Tree — 08/06/2554: Bartender is not happy. Security man is not happy. Cannot feel legs, is very cold in freezer. Is not good. Table is jammed into door, have no tools. Is very not good. But, on bright side, found meat! Shall chew to keep spirits up.
Entry Fore — 12/06/2554: Big nasty purple bug looked at me today. Make nervous. Blue wall wire can be broken, then bad thing happens. Very very bad thing. Man in orange spacesuit wave at me today too. He seem nice. Wonder who was?
Entry Fiv — 15/06/2554: I eat cornflakes today. Is good day. Sun shine for a while. Was nice. I also take ride on disposals chute. Was fun, but tiny. Get clog out of pipes, was vodka bottle. Is empty. This make many sads.
Entry Sex: 19/06/2554: Purple bugs jumpy today. When waved, get hiss. Maybe very bad. Maybe just ill. Do not know. Is science problem, is not engineer problem. I eat sandwich. Is glorious job. Wish to never end."; name = "Personal Log — Ivan Volodin"},/obj/item/weapon/pickaxe,/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a7)
+"hm" = (/obj/machinery/computer/monitor,/obj/structure/cable,/turf/simulated/floor/plating,/area/awaycontent/a7)
+"hn" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/awaycontent/a7)
+"ho" = (/obj/structure/closet/crate/bin,/obj/item/clothing/gloves/color/latex,/obj/item/trash/chips,/obj/effect/decal/cleanable/dirt,/obj/machinery/light/small{active_power_usage = 0; dir = 1; icon_state = "bulb-broken"; status = 2},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"hp" = (/obj/structure/table,/obj/item/weapon/storage/box/gloves{pixel_x = 0; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"hq" = (/obj/structure/cable,/obj/machinery/power/apc/noalarm{cell_type = 15000; dir = 4; locked = 0; name = "Research APC"; pixel_x = 25; req_access = null; start_charge = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"hr" = (/obj/structure/table,/obj/item/weapon/retractor,/obj/item/weapon/hemostat,/obj/structure/alien/weeds,/obj/item/stack/cable_coil,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"hs" = (/obj/structure/table,/obj/item/weapon/cartridge/signal/toxins,/obj/item/weapon/cartridge/signal/toxins{pixel_x = -4; pixel_y = 2},/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"ht" = (/obj/structure/filingcabinet/chestdrawer,/obj/machinery/light/small{active_power_usage = 0; dir = 1; icon_state = "bulb-broken"; status = 2},/obj/machinery/alarm/monitor{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/obj/item/weapon/paper{info = "Personal Log for Research Director Gerald Rosswell
Entry One — 17/05/2554: You know, I can't believe I took this position so suddenly. I saw that corporate needed a research director for one of its outposts and thought it would be a cakewalk; there isn't going to be a lot of research to be done on a tiny outpost. Mainly just running scans on the gas giant we are orbiting or some basic RnD. However, they conveniently forgot to tell me that I and my science staff would have to pull double duty as medical staff, and that there is no one higher up on the chain of command here, so I get to pull triple duty as acting captain as well! This shit is probably allowed in some 3pt. fine print buried underneath the literally thousands of pages of contracts. Well, at least the research will be easy work.
Entry Two — 25/05/2554: Well, we all expected it at the outpost: CentComm has decided to completely change what research we are doing. They've decided that we should be researching the species known as 'xenomorphs'. They announced this change 4 days ago, and along with it, sadly, the termination of our current science staff, barring me. Not to mention the constant noise made by the construction detail they sent, to staple on a xenobiology lab, ensuring no one has been able to sleep decently ever since they announced the shift. To make matters worse, our current security guard actually died of a heart attack today. Just goes to show, that 75 year old men shouldn't be security guards. Still can't believe that they decided to do this major change less than a month after the outpost was established.
Entry Three — 27/05/2554: The new security guard arrived today. Apparently transferred here from the research station that also is orbiting the gas giant. He seems to be rather angry about his transfer. Considering the rumors I've heard about the research station, he's probably caught off guard by the fact that Steve hasn't tried to force an IED down his throat.
Entry Four — 06/06/2554: My requests for additional security and containment measures for the 'xenomorph' has been denied. Does Central Command not notice how dangerous these creatures are? The only thing keeping them in is a force field: a minor problem with the power grid and the entire hive is loose. What would stop them then, the lone security guard with a dinky little taser? Kenneth can barely handle a short-tempered engineer. We are under-equipped and under-staffed, we are inevitably going to be destroyed, unless we get the equipment and staff we need.
Entry Five — 10/06/2554: Cunningham got a good look at the xenomorph in containment. He was frightened for the rest of the day, rather amusing if it wasn't for the fact that we are all trapped on this scrap heap, with naught but a force field keeping those xenomorphs in.
Entry Six — 17/06/2554: The reactions from the specimens today have shown that they possess strange mental properties. Mark hypothesizes that they possibly have a sort of hive mind; while nothing is certain, this would explain how xenomorphs seem to have vastly increased intellect when a 'queen' is present. Of course, testing this hypothesis would require many complicated procedures which we will not be able to undertake. Although we do not know the full extend of the xenomorph mind, it may or may not be able to find a way to circumvent our containment system. I will resubmit my request for additional security measures, along with this newfound information."; name = "Personal Log — Gerald Rosswell"},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hu" = (/obj/structure/closet/crate/bin,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hv" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/effect/decal/cleanable/blood/oil{color = "black"},/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hw" = (/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"hu" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/item/stack/rods,/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a7)
+"hv" = (/obj/machinery/door_control{id = "Awaybiohazard"; name = "Biohazard Shutter Control"; pixel_x = -25; pixel_y = 0; req_access_txt = "271"},/obj/machinery/light/small{dir = 8},/obj/machinery/computer/security{desc = "Used to access the various cameras on the outpost."; network = list("MO19R","MO19")},/turf/simulated/floor/plasteel{dir = 8; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"hw" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"hx" = (/obj/structure/grille,/obj/machinery/door/poddoor{id_tag = "AwayRD"; layer = 2.9; name = "privacy shutter"},/obj/structure/window/full/reinforced,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hy" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hz" = (/obj/item/stack/rods,/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/plasteel{ icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hA" = (/obj/structure/grille{density = 0; destroyed = 1; icon_state = "brokengrille"},/obj/item/stack/rods,/obj/item/stack/rods,/obj/item/weapon/shard{icon_state = "medium"},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hB" = (/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/oil{color = "black"},/obj/item/weapon/storage/firstaid/regular{empty = 1; name = "First-Aid (empty)"},/obj/item/device/healthanalyzer{pixel_x = 6; pixel_y = -5},/obj/item/device/assembly/prox_sensor{pixel_x = -5; pixel_y = -2},/obj/item/robot_parts/l_arm,/turf/simulated/floor/plasteel{ icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"hy" = (/obj/item/stack/rods,/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"hz" = (/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/oil{color = "black"},/obj/item/weapon/storage/firstaid/regular{empty = 1; name = "First-Aid (empty)"},/obj/item/device/healthanalyzer{pixel_x = 6; pixel_y = -5},/obj/item/device/assembly/prox_sensor{pixel_x = -5; pixel_y = -2},/obj/item/robot_parts/l_arm,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"hA" = (/obj/structure/grille/broken,/obj/item/stack/rods,/obj/item/stack/rods,/obj/item/weapon/shard{icon_state = "medium"},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"hB" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/fire{pixel_x = 0; pixel_y = 0},/obj/machinery/firealarm{dir = 4; pixel_x = 28},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"hC" = (/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"hD" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hE" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{density = 0; emagged = 1; icon_state = "door_open"; locked = 1; name = "Research Director's Office"; opacity = 0; req_access_txt = "201"; req_one_access_txt = "0"},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hF" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/fire{pixel_x = 0; pixel_y = 0},/obj/machinery/firealarm{dir = 4; pixel_x = 28},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"hG" = (/obj/structure/noticeboard{dir = 1; pixel_y = -32},/obj/machinery/light/small{active_power_usage = 0; dir = 2; icon_state = "bulb-broken"; status = 2},/obj/item/weapon/paper{info = "
In The Event of Xenobiology Breach: Evacuate staff, Lock down Xenobiology, Notify on-site superiors and/or Central Command immediatly.
I fucking knew it. There was a major breach, that idiotic force field failed, and the xenomorphs rushed out and took out the scientists. I've managed to make it to my office and closed the blast doors. I can hear them trying to pry open the doors. Probably don't have long. I have no clue what has happened to the rest of the crew, for all I know they've been killed to produce more of the fucks."; name = "Hastily Written Note"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"iv" = (/obj/effect/decal/cleanable/blood/splatter{color = "red"},/turf/simulated/floor/plasteel{ icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"iw" = (/obj/structure/sign/securearea{pixel_y = 32},/obj/machinery/shower{dir = 4; icon_state = "shower"; name = "emergency shower"; tag = "icon-shower (EAST)"},/turf/simulated/floor/plasteel{dir = 9; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"ix" = (/obj/structure/closet/firecloset,/turf/simulated/floor/plasteel{dir = 5; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"iy" = (/obj/structure/toilet{dir = 4},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel{ icon_state = "freezerfloor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"iz" = (/obj/machinery/door/airlock{name = "Unit 1"},/turf/simulated/floor/plasteel{ icon_state = "freezerfloor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"iA" = (/obj/machinery/door/airlock{name = "Unisex Showers"},/turf/simulated/floor/plasteel{ icon_state = "freezerfloor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"iB" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{ icon_state = "freezerfloor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"iC" = (/obj/machinery/shower{dir = 8},/obj/item/weapon/bikehorn/rubberducky,/turf/simulated/floor/plasteel{ icon_state = "freezerfloor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"iD" = (/obj/structure/table,/obj/item/weapon/cigbutt,/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"iE" = (/obj/structure/table,/obj/item/trash/plate,/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"iF" = (/obj/structure/table,/obj/item/trash/raisins,/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"iG" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"iH" = (/obj/machinery/door/airlock{name = "Private Restroom"},/turf/simulated/floor/plasteel{ icon_state = "freezerfloor"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"it" = (/obj/item/weapon/storage/secure/safe{pixel_x = 32; pixel_y = 0},/obj/effect/decal/cleanable/blood/splatter,/obj/item/weapon/pen,/obj/item/weapon/paper/crumpled{info = "19 06 2554
I fucking knew it. There was a major breach, that idiotic force field failed, and the xenomorphs rushed out and took out the scientists. I've managed to make it to my office and closed the blast doors. I can hear them trying to pry open the doors. Probably don't have long. I have no clue what has happened to the rest of the crew, for all I know they've been killed to produce more of the fucks."; name = "Hastily Written Note"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"iu" = (/obj/effect/decal/cleanable/blood/splatter{color = "red"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"iv" = (/obj/structure/sign/securearea{pixel_y = 32},/obj/machinery/shower{dir = 4; icon_state = "shower"; name = "emergency shower"; tag = "icon-shower (EAST)"},/turf/simulated/floor/plasteel{dir = 9; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"iw" = (/obj/structure/closet/firecloset,/turf/simulated/floor/plasteel{dir = 5; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"ix" = (/obj/structure/toilet{dir = 4},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"iy" = (/obj/machinery/door/airlock{name = "Unit 1"},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"iz" = (/obj/machinery/door/airlock{name = "Unisex Showers"},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"iA" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"iB" = (/obj/machinery/shower{dir = 8},/obj/item/weapon/bikehorn/rubberducky,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"iC" = (/obj/structure/table,/obj/item/weapon/cigbutt,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"iD" = (/obj/structure/table,/obj/item/trash/plate,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"iE" = (/obj/structure/table,/obj/item/trash/raisins,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"iF" = (/obj/machinery/door/airlock{name = "Private Restroom"},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"iG" = (/obj/machinery/vending/medical{req_access_txt = "271"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"iH" = (/obj/structure/sink{pixel_y = 28},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"iI" = (/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 0; pixel_y = -32},/obj/machinery/light/small{active_power_usage = 0; dir = 2; icon_state = "bulb-broken"; status = 2},/obj/machinery/camera{c_tag = "Research Director's Office"; dir = 1; network = list("MO19","MO19R")},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"iJ" = (/obj/machinery/newscaster{pixel_x = 0; pixel_y = -30},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"iK" = (/obj/structure/table,/obj/item/device/radio/off,/obj/item/device/laser_pointer,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"iL" = (/obj/structure/sink{pixel_y = 28},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plasteel{ icon_state = "freezerfloor"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"iM" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plasteel{dir = 10; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"iN" = (/obj/structure/table,/obj/item/weapon/storage/secure/briefcase,/obj/item/device/taperecorder{pixel_x = -3},/turf/simulated/floor/plasteel{dir = 6; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"iO" = (/obj/machinery/light/small,/turf/simulated/floor/plasteel{dir = 2; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"iP" = (/obj/structure/sink{dir = 8; icon_state = "sink"; pixel_x = -12; pixel_y = 2},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 10; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"iQ" = (/obj/structure/closet/emcloset,/obj/machinery/light/small,/turf/simulated/floor/plasteel{dir = 6; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"iR" = (/obj/machinery/shower{dir = 1; pixel_y = 0},/turf/simulated/floor/plasteel{ icon_state = "freezerfloor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"iS" = (/obj/structure/stool/bed/chair{dir = 1},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"iT" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"iL" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/effect/decal/cleanable/blood/oil{color = "black"},/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a7)
+"iM" = (/obj/structure/table,/obj/item/weapon/storage/secure/briefcase,/obj/item/device/taperecorder{pixel_x = -3},/turf/simulated/floor/plasteel{dir = 6; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"iN" = (/obj/machinery/light/small,/turf/simulated/floor/plasteel{dir = 2; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"iO" = (/obj/structure/sink{dir = 8; icon_state = "sink"; pixel_x = -12; pixel_y = 2},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 10; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"iP" = (/obj/structure/closet/emcloset,/obj/machinery/light/small,/turf/simulated/floor/plasteel{dir = 6; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"iQ" = (/obj/machinery/shower{dir = 1; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"iR" = (/obj/structure/stool/bed/chair{dir = 1},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"iS" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"iT" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"iU" = (/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 0; pixel_y = 0},/turf/simulated/wall/rust,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"iV" = (/obj/machinery/vending/boozeomat{req_access_txt = "0"},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"iW" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"iX" = (/obj/structure/table,/obj/machinery/microwave{pixel_x = -3; pixel_y = 6},/turf/simulated/floor/plasteel{burnt = 1; dir = 8; icon_state = "floorscorched1"; tag = "icon-floorscorched1 (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"iW" = (/obj/structure/table,/obj/machinery/microwave{pixel_x = -3; pixel_y = 6},/turf/simulated/floor/plasteel{burnt = 1; dir = 8; icon_state = "floorscorched1"; tag = "icon-floorscorched1 (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"iX" = (/obj/structure/table,/obj/machinery/microwave{pixel_x = -3; pixel_y = 6},/turf/simulated/floor/plasteel{burnt = 1; dir = 8; icon_state = "floorscorched2"; tag = "icon-floorscorched2 (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"iY" = (/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"iZ" = (/obj/structure/table,/obj/machinery/reagentgrinder,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"ja" = (/obj/structure/table,/obj/machinery/microwave{pixel_x = -3; pixel_y = 6},/turf/simulated/floor/plasteel{burnt = 1; dir = 8; icon_state = "floorscorched2"; tag = "icon-floorscorched2 (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"ja" = (/obj/structure/toilet{dir = 1},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"jb" = (/obj/item/stack/rods,/obj/item/weapon/shard,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
-"jc" = (/obj/structure/toilet{dir = 1},/turf/simulated/floor/plasteel{ icon_state = "freezerfloor"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"jd" = (/obj/structure/table,/obj/item/weapon/book/manual/detective,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"je" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jf" = (/turf/simulated/floor/plasteel{burnt = 1; dir = 8; icon_state = "floorscorched2"; tag = "icon-floorscorched2 (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jc" = (/obj/structure/table,/obj/item/weapon/book/manual/detective,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jd" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"je" = (/turf/simulated/floor/plasteel{burnt = 1; dir = 8; icon_state = "floorscorched2"; tag = "icon-floorscorched2 (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jf" = (/obj/machinery/door/airlock{name = "Unisex Restrooms"; req_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"jg" = (/obj/machinery/vending/cola,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"jh" = (/obj/machinery/vending/coffee,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"ji" = (/obj/structure/stool/bed/chair/comfy/black{dir = 8},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jj" = (/obj/machinery/door/airlock{name = "Unisex Restrooms"; req_access_txt = "0"},/turf/simulated/floor/plasteel{ icon_state = "freezerfloor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jk" = (/obj/structure/closet/crate/bin,/obj/machinery/light/small{dir = 8},/obj/item/trash/cheesie,/obj/item/trash/can,/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jl" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jj" = (/obj/structure/closet/crate/bin,/obj/machinery/light/small{dir = 8},/obj/item/trash/cheesie,/obj/item/trash/can,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jk" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jl" = (/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"jm" = (/obj/structure/stool,/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jn" = (/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jn" = (/obj/structure/stool/bed/chair,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"jo" = (/obj/effect/decal/cleanable/flour,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"jp" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/table,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"jq" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor,/obj/item/weapon/reagent_containers/food/condiment/peppermill{pixel_x = 3},/obj/item/weapon/reagent_containers/food/condiment/saltshaker{pixel_x = -3; pixel_y = 0},/obj/machinery/door/poddoor/shutters{dir = 8; id_tag = "awaykitchen"; name = "Serving Hatch"},/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/effect/decal/cleanable/blood/oil{color = "black"},/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"js" = (/obj/structure/stool/bed/chair,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jt" = (/obj/item/weapon/twohanded/required/kirbyplants{desc = "A plastic potted plant."; layer = 4.1; pixel_y = 3},/turf/simulated/floor/plasteel{burnt = 1; dir = 8; icon_state = "floorscorched1"; tag = "icon-floorscorched1 (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"ju" = (/obj/structure/table,/obj/item/weapon/newspaper,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jr" = (/obj/structure/closet/secure_closet{icon_broken = "rdsecurebroken"; icon_closed = "rdsecure"; icon_locked = "rdsecure1"; icon_off = "rdsecureoff"; icon_opened = "rdsecureopen"; icon_state = "rdsecure1"; locked = 1; name = "research director's locker"; req_access_txt = "271"},/obj/item/weapon/storage/backpack/satchel_tox,/obj/item/clothing/gloves/color/latex,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"js" = (/obj/item/weapon/twohanded/required/kirbyplants{desc = "A plastic potted plant."; layer = 4.1; pixel_y = 3},/turf/simulated/floor/plasteel{burnt = 1; dir = 8; icon_state = "floorscorched1"; tag = "icon-floorscorched1 (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jt" = (/obj/structure/closet/crate/bin,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"ju" = (/obj/machinery/vending/snack,/obj/structure/sign/poster{icon_state = "poster14"; pixel_x = 0; pixel_y = 32; serial_number = 14; subtype = 0},/turf/simulated/floor/plasteel{burnt = 1; dir = 8; icon_state = "floorscorched2"; tag = "icon-floorscorched2 (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"jv" = (/obj/structure/stool/bed/chair,/obj/effect/decal/cleanable/generic,/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"jw" = (/obj/structure/stool/bed/chair,/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jx" = (/obj/machinery/vending/snack,/obj/structure/sign/poster{icon_state = "poster14"; pixel_x = 0; pixel_y = 32; serial_number = 14; subtype = 0},/turf/simulated/floor/plasteel{burnt = 1; dir = 8; icon_state = "floorscorched2"; tag = "icon-floorscorched2 (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jy" = (/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = 30},/turf/simulated/floor/plasteel{burnt = 1; dir = 8; icon_state = "floorscorched1"; tag = "icon-floorscorched1 (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jz" = (/obj/structure/sign/science{pixel_x = 0; pixel_y = 32},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 9; icon_state = "purple"; tag = "icon-purple (NORTHWEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jA" = (/turf/simulated/floor/plasteel{dir = 5; icon_state = "purple"; tag = "icon-purple (NORTHEAST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jx" = (/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = 30},/turf/simulated/floor/plasteel{burnt = 1; dir = 8; icon_state = "floorscorched1"; tag = "icon-floorscorched1 (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jy" = (/obj/structure/sign/science{pixel_x = 0; pixel_y = 32},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 9; icon_state = "purple"; tag = "icon-purple (NORTHWEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jz" = (/turf/simulated/floor/plasteel{dir = 5; icon_state = "purple"; tag = "icon-purple (NORTHEAST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"jB" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
"jC" = (/obj/structure/alien/weeds,/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
"jD" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/weeds/node,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
-"jE" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 1; icon_state = "purple"; tag = "icon-purple (NORTH)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jE" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"jF" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"jG" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"jH" = (/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jI" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jJ" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/power/apc/noalarm{cell_type = 15000; dir = 1; locked = 0; name = "Worn-out APC"; pixel_x = 0; pixel_y = 25; req_access = null; start_charge = 100},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jK" = (/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = 30},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jI" = (/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = 30},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jJ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"jK" = (/obj/structure/noticeboard{pixel_y = 32},/obj/item/weapon/paper{info = "
I Can't Believe It's Not Pasta: Half off on Wednesdays
Burger night every Friday 6PM-10PM, free drinks with purchase of meal!
Premiering Tonight: The comedy stylings of Shoe Snatching Willy! 11AM-7PM
"; name = "Specials This Week"},/turf/simulated/floor/plasteel{burnt = 1; dir = 8; icon_state = "floorscorched1"; tag = "icon-floorscorched1 (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"jL" = (/obj/machinery/alarm/monitor{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jM" = (/obj/structure/noticeboard{pixel_y = 32},/obj/item/weapon/paper{info = "
I Can't Believe It's Not Pasta: Half off on Wednesdays
Burger night every Friday 6PM-10PM, free drinks with purchase of meal!
Premiering Tonight: The comedy stylings of Shoe Snatching Willy! 11AM-7PM
"; name = "Specials This Week"},/turf/simulated/floor/plasteel{burnt = 1; dir = 8; icon_state = "floorscorched1"; tag = "icon-floorscorched1 (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jN" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jM" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jN" = (/obj/item/weapon/cigbutt,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"jO" = (/obj/structure/grille,/obj/structure/window/full/basic,/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jP" = (/obj/item/weapon/cigbutt,/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jP" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"jQ" = (/obj/structure/table,/obj/item/weapon/book/manual/barman_recipes{pixel_y = 5},/obj/item/weapon/reagent_containers/food/drinks/shaker,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"jR" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"jS" = (/obj/machinery/vending/dinnerware,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"jT" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor,/obj/machinery/door/poddoor/shutters{dir = 8; id_tag = "awaykitchen"; name = "Serving Hatch"},/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jU" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = "90Curve"},/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg1"; tag = "icon-platingdmg1"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"jV" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jU" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jV" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"jW" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jX" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jY" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"jZ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/item/weapon/cigbutt,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"ka" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 1; icon_state = "purplecorner"; tag = "icon-purplecorner (NORTH)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kb" = (/obj/machinery/light/small{dir = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/alarm/monitor{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/turf/simulated/floor/plasteel{dir = 4; icon_state = "purplecorner"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kc" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 4; icon_state = "purplecorner"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"jX" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"jY" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{density = 0; emagged = 1; icon_state = "door_open"; locked = 1; name = "Research Director's Office"; opacity = 0; req_access_txt = "271"; req_one_access_txt = "0"},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"jZ" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"ka" = (/obj/machinery/door/airlock/glass_research{name = "Research Storage"; req_access_txt = "271"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"kb" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/awaycontent/a7)
+"kc" = (/obj/structure/closet/crate,/obj/item/weapon/storage/box/lights/mixed,/obj/item/weapon/contraband/poster,/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg1"; tag = "icon-platingdmg1"},/area/awaycontent/a7)
"kd" = (/obj/structure/grille,/obj/structure/window/full/reinforced,/turf/simulated/floor/plating/airless{name = "plating"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"ke" = (/obj/structure/grille,/turf/simulated/floor/plating/airless{name = "plating"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kf" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel/airless{icon_state = "damaged1"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kg" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel/airless{icon_state = "floorscorched2"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kh" = (/obj/machinery/light/small{dir = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel/airless{icon_state = "floorgrime"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"ki" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel/airless{icon_state = "floorgrime"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kj" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating/airless{icon_state = "platingdmg1"; name = "plating"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kk" = (/obj/machinery/door/firedoor{density = 1; icon_state = "door_closed"; opacity = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kl" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor{density = 1; icon_state = "door_closed"; opacity = 1},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"km" = (/obj/machinery/light/small,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kn" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"kf" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1; pressure_checks = 1},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"kg" = (/obj/machinery/door/firedoor,/obj/machinery/door/poddoor{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id_tag = "Awaybiohazard"; layer = 2.9; name = "Acid-Proof biohazard containment door"; unacidable = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"kh" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating{burnt = 1; icon_state = "panelscorched"; tag = "icon-panelscorched"},/area/awaycontent/a7)
+"ki" = (/obj/machinery/door/airlock/glass_medical{glass = 0; icon = 'icons/obj/doors/Doorresearch.dmi'; id_tag = ""; name = "Research Division"; opacity = 1; req_access_txt = "271"; req_one_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"kj" = (/obj/structure/table/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door_control{id = "Awaybiohazard"; name = "Biohazard Shutter Control"; pixel_x = 0; pixel_y = 8; req_access_txt = "271"},/obj/machinery/door_control{id = "AwayRD"; name = "Privacy Shutter Control"; pixel_x = 0; pixel_y = -2; req_access_txt = "271"},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"kk" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/awaycontent/a7)
+"kl" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table,/obj/machinery/computer/id_upgrader,/turf/simulated/floor/plasteel{dir = 10; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"km" = (/obj/structure/closet/crate/bin,/obj/item/trash/candy,/obj/item/trash/can,/turf/simulated/floor/plasteel{dir = 2; icon_state = "arrival"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"kn" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/effect/decal/cleanable/blood/oil{color = "black"},/turf/simulated/floor/plating,/area/awaycontent/a7)
"ko" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Diner"},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"kp" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"kq" = (/obj/structure/table,/obj/item/weapon/kitchen/rollingpin,/obj/item/weapon/kitchen/knife,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"kr" = (/obj/structure/table,/obj/item/weapon/book/manual/chef_recipes{pixel_x = 2; pixel_y = 6},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"ks" = (/obj/effect/decal/cleanable/plant_smudge,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"kt" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/processor,/obj/machinery/alarm/monitor{dir = 8; frequency = 1439; locked = 0; pixel_x = 23; pixel_y = 0; req_access = null},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"ku" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor,/obj/item/weapon/reagent_containers/glass/rag{pixel_y = 5},/obj/machinery/door/poddoor/shutters{dir = 8; id_tag = "awaykitchen"; name = "Serving Hatch"},/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kv" = (/obj/structure/closet/crate/bin,/obj/item/trash/candy,/obj/item/trash/can,/turf/simulated/floor/plasteel{dir = 2; icon_state = "arrival"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kw" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 2; icon_state = "arrival"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kx" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "arrival"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"ky" = (/obj/machinery/light/small,/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 0; pixel_y = -32},/obj/machinery/camera{c_tag = "Arrivals North"; dir = 1; network = list("MO19")},/turf/simulated/floor/plasteel{dir = 2; icon_state = "arrival"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kz" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitecorner"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kA" = (/obj/structure/sign/poster{icon_state = "poster2_legit"; pixel_x = 0; pixel_y = -32; serial_number = 2; subtype = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "arrival"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"ku" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/item/weapon/newspaper,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"kv" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 2; icon_state = "arrival"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"kw" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "arrival"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"kx" = (/obj/machinery/light/small,/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 0; pixel_y = -32},/obj/machinery/camera{c_tag = "Arrivals North"; dir = 1; network = list("MO19")},/turf/simulated/floor/plasteel{dir = 2; icon_state = "arrival"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"ky" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitecorner"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"kz" = (/obj/structure/sign/poster{icon_state = "poster2_legit"; pixel_x = 0; pixel_y = -32; serial_number = 2; subtype = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "arrival"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"kA" = (/obj/machinery/light/small,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"kB" = (/obj/machinery/door/firedoor{density = 1; icon_state = "door_closed"; opacity = 1},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kC" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel/airless{icon_state = "floorscorched1"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kD" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel/airless{icon_state = "damaged3"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"kC" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 1; icon_state = "purple"; tag = "icon-purple (NORTH)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"kD" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/power/apc/noalarm{cell_type = 15000; dir = 1; locked = 0; name = "Habitat APC"; pixel_x = 0; pixel_y = 25; req_access = null; start_charge = 100},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"kE" = (/turf/simulated/floor/plating/airless{name = "plating"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"kF" = (/turf/simulated/floor/plasteel/airless{icon_state = "damaged2"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"kG" = (/turf/simulated/floor/plasteel/airless{icon_state = "floorgrime"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"kH" = (/obj/effect/decal/cleanable/generic,/obj/effect/decal/remains/human{desc = "They look like human remains. The skeleton is curled up in fetal position with the hands placed near the throat."},/turf/simulated/floor/plasteel/airless{icon_state = "damaged4"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kI" = (/obj/machinery/light/small,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"kI" = (/obj/effect/decal/cleanable/generic,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"kJ" = (/obj/machinery/door/firedoor{density = 1; icon_state = "door_closed"; opacity = 1},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"kK" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kL" = (/obj/effect/decal/cleanable/generic,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kM" = (/obj/effect/decal/cleanable/blood/xeno{color = "green"},/obj/effect/decal/cleanable/blood/gibs/xeno,/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"kL" = (/obj/effect/decal/cleanable/blood/xeno{color = "green"},/obj/effect/decal/cleanable/blood/gibs/xeno,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"kM" = (/obj/effect/decal/cleanable/blood/xeno{color = "green"},/obj/effect/decal/remains/xeno{desc = "They look like the remains of something... alien. The front of skull appears to have been completely obliterated."},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"kN" = (/obj/structure/closet/crate/bin,/obj/item/trash/plate,/obj/item/weapon/reagent_containers/food/snacks/badrecipe,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kO" = (/obj/effect/decal/cleanable/blood/xeno{color = "green"},/obj/effect/decal/remains/xeno{desc = "They look like the remains of something... alien. The front of skull appears to have been completely obliterated."},/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kP" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "arrival"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"kO" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "arrival"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"kP" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"kQ" = (/turf/simulated/floor/plasteel/airless{icon_state = "damaged5"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"kR" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel/airless{icon_state = "floorgrime"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kS" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kT" = (/obj/machinery/door/firedoor{density = 1; icon_state = "door_closed"; opacity = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kU" = (/obj/machinery/door/firedoor{density = 1; icon_state = "door_closed"; opacity = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"kS" = (/obj/machinery/door/firedoor{density = 1; icon_state = "door_closed"; opacity = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"kT" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = "90Curve"},/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg1"; tag = "icon-platingdmg1"},/area/awaycontent/a7)
+"kU" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; layer = 2.4; on = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"kV" = (/obj/machinery/door_control{id = "awaydorm1"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = -25; pixel_y = 0; req_access_txt = "0"; specialfunctions = 4},/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kW" = (/obj/structure/closet/secure_closet{desc = "It's a secure locker for personnel. The first card swiped gains control."; icon_broken = "cabinetdetective_broken"; icon_closed = "cabinetdetective"; icon_locked = "cabinetdetective_locked"; icon_off = "cabinetdetective_broken"; icon_opened = "cabinetdetective_open"; icon_state = "cabinetdetective"; locked = 0; name = "personal closet"; req_access_txt = "201"},/obj/item/clothing/under/suit_jacket/navy,/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"kW" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"kX" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "0"},/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kY" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/item/device/multitool,/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"kZ" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"la" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"lb" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"kY" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"kZ" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"la" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"lb" = (/obj/structure/stool/bed/chair,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lc" = (/obj/structure/extinguisher_cabinet{pixel_x = 26; pixel_y = 0},/obj/machinery/camera{c_tag = "Kitchen"; dir = 8; network = list("MO19")},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"ld" = (/turf/simulated/floor/plating/airless/asteroid,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"le" = (/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lf" = (/turf/simulated/floor/plating/airless/asteroid,/turf/simulated/shuttle/wall{dir = 3; icon_state = "swall_f10"; layer = 2},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"lg" = (/obj/structure/stool/bed/chair,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"lh" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 8; icon_state = "arrival"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"li" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plasteel{dir = 2; icon_state = "warningcorner"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"lg" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 8; icon_state = "arrival"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"lh" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plasteel{dir = 2; icon_state = "warningcorner"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"li" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lj" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lk" = (/obj/item/stack/rods,/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
-"ll" = (/obj/item/stack/rods,/obj/structure/grille{density = 0; destroyed = 1; icon_state = "brokengrille"},/obj/item/stack/rods,/obj/item/weapon/shard{icon_state = "medium"},/turf/simulated/floor/plating/airless{name = "plating"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"lm" = (/obj/structure/grille{density = 0; destroyed = 1; icon_state = "brokengrille"},/obj/item/stack/rods,/turf/simulated/floor/plating/airless{icon_state = "platingdmg3"; name = "plating"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"ln" = (/obj/item/weapon/cigbutt,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"ll" = (/obj/item/stack/rods,/obj/structure/grille/broken,/obj/item/stack/rods,/obj/item/weapon/shard{icon_state = "medium"},/turf/simulated/floor/plating/airless{name = "plating"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"lm" = (/obj/structure/grille/broken,/obj/item/stack/rods,/turf/simulated/floor/plating/airless{icon_state = "platingdmg3"; name = "plating"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"ln" = (/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lo" = (/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lp" = (/obj/machinery/door/airlock{id_tag = "awaydorm1"; name = "Dorm 1"},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lq" = (/obj/machinery/light/small{dir = 4},/obj/structure/stool/bed/chair/wood/normal,/obj/machinery/alarm/monitor{dir = 8; frequency = 1439; locked = 0; pixel_x = 23; pixel_y = 0; req_access = null},/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"lr" = (/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"ls" = (/obj/machinery/light/small{dir = 8},/obj/structure/table,/obj/item/weapon/storage/box,/obj/machinery/alarm/monitor{dir = 4; frequency = 1439; locked = 0; pixel_x = -23; pixel_y = 0; req_access = null},/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"lt" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"lr" = (/obj/machinery/light/small{dir = 8},/obj/structure/table,/obj/item/weapon/storage/box,/obj/machinery/alarm/monitor{dir = 4; frequency = 1439; locked = 0; pixel_x = -23; pixel_y = 0; req_access = null},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"ls" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"lt" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/effect/decal/cleanable/dirt,/obj/machinery/camera{c_tag = "Bar"; dir = 8; network = list("MO19")},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lu" = (/obj/machinery/door_control{id = "awaykitchen"; name = "Kitchen Shutters Control"; pixel_x = -25; pixel_y = 0; req_access_txt = "0"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"lv" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/effect/decal/cleanable/dirt,/obj/machinery/camera{c_tag = "Bar"; dir = 8; network = list("MO19")},/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"lw" = (/obj/machinery/door/airlock{name = "Kitchen Cold Room"; req_access_txt = "201"},/turf/simulated/floor/plasteel{ icon_state = "showroomfloor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"lx" = (/obj/structure/sink/kitchen{desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; name = "old sink"; pixel_y = 28},/turf/simulated/floor/plasteel{ icon_state = "showroomfloor"; temperature = 273.15},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"ly" = (/turf/simulated/floor/plasteel{ icon_state = "showroomfloor"; temperature = 273.15},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"lv" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/item/weapon/cigbutt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"lw" = (/obj/structure/sink/kitchen{desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; name = "old sink"; pixel_y = 28},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"; temperature = 273.15},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"lx" = (/turf/simulated/floor/plasteel{icon_state = "showroomfloor"; temperature = 273.15},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"ly" = (/obj/structure/closet/crate{desc = "It's a storage unit for kitchen clothes and equipment."; name = "Kitchen Crate"},/obj/item/weapon/storage/box/mousetraps,/obj/item/clothing/under/waiter,/turf/simulated/floor/plasteel{icon_state = "showroomfloor"; temperature = 273.15},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lz" = (/turf/simulated/shuttle/wall{icon_state = "swall14"; dir = 2},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lA" = (/turf/simulated/shuttle/wall{icon_state = "swall8"; dir = 2},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lB" = (/obj/structure/grille,/obj/structure/window/full/reinforced,/turf/simulated/shuttle/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lC" = (/turf/simulated/shuttle/wall{icon_state = "swall4"; dir = 2},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lD" = (/turf/simulated/shuttle/wall{icon_state = "swall1"; dir = 2},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lE" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel/airless{dir = 4; icon_state = "neutral"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"lF" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-burst_r (WEST)"; icon_state = "burst_r"; dir = 8},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"lG" = (/obj/structure/closet/crate{desc = "It's a storage unit for kitchen clothes and equipment."; name = "Kitchen Crate"},/obj/item/weapon/storage/box/mousetraps,/obj/item/clothing/under/waiter,/turf/simulated/floor/plasteel{ icon_state = "showroomfloor"; temperature = 273.15},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"lH" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"lI" = (/obj/structure/table,/obj/item/weapon/storage/fancy/cigarettes/dromedaryco,/turf/simulated/floor/plasteel{dir = 6; icon_state = "warning"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"lJ" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plasteel/airless{dir = 8; icon_state = "neutralcorner"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"lF" = (/obj/structure/shuttle/engine/propulsion{dir = 4; icon_state = "burst_r"; tag = "icon-burst_r (WEST)"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"lG" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"lH" = (/obj/structure/table,/obj/item/weapon/storage/fancy/cigarettes/dromedaryco,/turf/simulated/floor/plasteel{dir = 6; icon_state = "warning"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"lI" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"lJ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 1; icon_state = "purplecorner"; tag = "icon-purplecorner (NORTH)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lK" = (/obj/structure/shuttle/engine/heater{tag = "icon-heater (EAST)"; icon_state = "heater"; dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless{name = "plating"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"lL" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "warningcorner"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"lL" = (/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg1"; tag = "icon-platingdmg1"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lM" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lN" = (/obj/structure/table/woodentable,/obj/item/weapon/lighter/zippo,/obj/machinery/newscaster{pixel_x = 30; pixel_y = 0},/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lO" = (/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lP" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lQ" = (/obj/effect/decal/cleanable/blood/oil{color = "black"},/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"lR" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock{name = "Kitchen"; req_access_txt = "201"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"lR" = (/obj/machinery/light/small{dir = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/alarm/monitor{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 4; icon_state = "purplecorner"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lS" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lT" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lU" = (/obj/structure/table,/obj/effect/decal/cleanable/dirt,/obj/item/clothing/suit/chaplain_hoodie,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"lV" = (/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg1"; tag = "icon-platingdmg1"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"lV" = (/obj/machinery/light/small{dir = 4},/obj/effect/decal/remains/human{desc = "They look like human remains. The skeleton is sitting upright with its legs tucked in and hands still holding onto its arms."},/obj/item/weapon/gun/projectile/shotgun/sc_pump,/turf/simulated/floor/plasteel{icon_state = "showroomfloor"; temperature = 273.15},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lW" = (/turf/simulated/shuttle/floor,/turf/simulated/shuttle/wall{icon_state = "swall_f9"; dir = 2},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lX" = (/obj/structure/table,/obj/item/weapon/storage/lockbox,/turf/simulated/shuttle/floor,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"lY" = (/obj/structure/table,/obj/item/device/radio/off,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
@@ -628,26 +628,26 @@
"md" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"me" = (/obj/machinery/newscaster{pixel_x = 0; pixel_y = 30},/obj/machinery/light/small{dir = 1},/turf/simulated/shuttle/floor,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mf" = (/obj/structure/closet/emcloset,/turf/simulated/shuttle/floor,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"mg" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-burst_l (WEST)"; icon_state = "burst_l"; dir = 8},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"mh" = (/obj/machinery/light/small{dir = 4},/obj/effect/decal/remains/human{desc = "They look like human remains. The skeleton is sitting upright with its legs tucked in and hands still holding onto its arms."},/obj/item/weapon/gun/projectile/shotgun/sc_pump,/turf/simulated/floor/plasteel{ icon_state = "showroomfloor"; temperature = 273.15},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"mg" = (/obj/structure/shuttle/engine/propulsion{dir = 4; icon_state = "burst_l"; tag = "icon-burst_l (WEST)"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"mh" = (/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mi" = (/turf/simulated/floor/plasteel/airless{icon_state = "neutralcorner"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"mj" = (/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"mj" = (/obj/structure/stool,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mk" = (/obj/machinery/portable_atmospherics/canister/air,/obj/effect/decal/cleanable/dirt,/obj/structure/window/basic{dir = 1},/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"ml" = (/obj/structure/stool,/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"ml" = (/obj/machinery/light/small,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mm" = (/obj/structure/table,/obj/item/weapon/storage/backpack/satchel/withwallet,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"mn" = (/obj/machinery/light/small,/turf/simulated/floor/plasteel{ icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"mo" = (/obj/structure/closet/secure_closet{icon_broken = "fridgebroken"; icon_closed = "fridge"; icon_locked = "fridge1"; icon_off = "fridgeoff"; icon_opened = "fridgeopen"; icon_state = "fridge"; locked = 0; name = "meat fridge"; req_access_txt = "201"},/obj/item/weapon/reagent_containers/food/snacks/meat/monkey,/obj/item/weapon/reagent_containers/food/snacks/meat/monkey,/obj/item/weapon/reagent_containers/food/snacks/meat/monkey,/obj/item/weapon/reagent_containers/food/snacks/meat/monkey,/turf/simulated/floor/plasteel{ icon_state = "showroomfloor"; temperature = 273.15},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"mp" = (/obj/structure/closet/secure_closet{icon_state = "secure"; locked = 0; name = "kitchen Cabinet"; req_access_txt = "201"},/obj/item/weapon/reagent_containers/food/condiment/flour,/obj/item/weapon/reagent_containers/food/condiment/flour,/obj/item/weapon/reagent_containers/food/condiment/sugar,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{ icon_state = "showroomfloor"; temperature = 273.15},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"mn" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 4; icon_state = "purplecorner"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"mo" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"mp" = (/obj/machinery/door/firedoor{density = 1; icon_state = "door_closed"; opacity = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mq" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets,/turf/simulated/shuttle/floor,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mr" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/light/small{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"ms" = (/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mt" = (/obj/effect/landmark{name = "awaystart"},/turf/simulated/shuttle/floor,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mu" = (/obj/structure/stool/bed/chair{dir = 8},/obj/effect/landmark{name = "awaystart"},/turf/simulated/shuttle/floor,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mv" = (/obj/machinery/light/small{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"mw" = (/obj/structure/closet/secure_closet{icon_broken = "fridgebroken"; icon_closed = "fridge"; icon_locked = "fridge1"; icon_off = "fridgeoff"; icon_opened = "fridgeopen"; icon_state = "fridge"; locked = 0; name = "refrigerator"; req_access_txt = "201"},/obj/item/weapon/reagent_containers/food/condiment/milk,/obj/item/weapon/reagent_containers/food/condiment/milk,/obj/item/weapon/reagent_containers/food/condiment/milk,/obj/item/weapon/storage/fancy/egg_box,/turf/simulated/floor/plasteel{ icon_state = "showroomfloor"; temperature = 273.15},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"mw" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel/airless{icon_state = "damaged1"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mx" = (/obj/structure/grille,/obj/structure/sign/vacuum{desc = "A warning sign which reads 'HOSTILE ATMOSPHERE AHEAD'"; name = "\improper HOSTILE ATMOSPHERE AHEAD"; pixel_x = 0},/obj/structure/window/full/reinforced,/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"my" = (/turf/simulated/floor/plasteel/airless{dir = 8; icon_state = "neutralcorner"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"mz" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"my" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel/airless{icon_state = "floorscorched2"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"mz" = (/obj/machinery/light/small{dir = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/floor/plasteel/airless{icon_state = "floorgrime"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mA" = (/obj/structure/table/woodentable,/obj/machinery/door_control{id = "awaydorm2"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = -25; pixel_y = 0; req_access_txt = "0"; specialfunctions = 4},/obj/machinery/newscaster{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mB" = (/obj/structure/stool/bed/chair/wood/normal{dir = 8},/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mC" = (/obj/machinery/computer/arcade,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
@@ -666,7 +666,7 @@
"mP" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mQ" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel/airless{icon_state = "neutralcorner"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mR" = (/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 4; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plasteel/airless{icon_state = "floorscorched2"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"mS" = (/obj/machinery/light/small{dir = 4},/obj/effect/decal/cleanable/dirt,/obj/structure/noticeboard{dir = 8; pixel_x = 32; pixel_y = 0},/obj/item/weapon/paper{info = "
Welcome to Moon Outpost 19! Property of Nanotrasen Inc.
Staff Roster:
Dr. Gerald Rosswell: Research Director & Acting Captain
Dr. Sakuma Sano: Xenobiologist
Dr. Mark Douglas: Xenobiologist
Kenneth Cunningham: Security Officer
Ivan Volodin: Engineer
Mathias Kuester: Bartender
Sven Edling: Chef
Steve: Assistant
Please enjoy your stay, and report any abnormalities to an officer."; name = "Welcome Notice"},/obj/machinery/camera{c_tag = "Arrivals South"; dir = 8; network = list("MO19")},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"mS" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mT" = (/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 4; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mU" = (/obj/machinery/door/airlock{id_tag = "awaydorm2"; name = "Dorm 2"},/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 4; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mV" = (/obj/machinery/light/small{dir = 4},/obj/machinery/alarm/monitor{dir = 8; frequency = 1439; locked = 0; pixel_x = 23; pixel_y = 0; req_access = null},/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
@@ -674,53 +674,53 @@
"mX" = (/obj/structure/stool/bed/chair,/obj/machinery/light/small{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mY" = (/turf/simulated/shuttle/wall{icon_state = "swall2"; dir = 2},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"mZ" = (/obj/machinery/light/small{dir = 4},/obj/structure/window/reinforced,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"na" = (/obj/machinery/light/small{dir = 8},/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 9; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plasteel/airless{dir = 8; icon_state = "neutralcorner"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"na" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel/airless{icon_state = "floorgrime"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nb" = (/obj/machinery/portable_atmospherics/scrubber,/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nc" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/obj/effect/decal/cleanable/blood{color = "red"},/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"nd" = (/obj/structure/closet/secure_closet{desc = "It's a secure locker for personnel. The first card swiped gains control."; icon_broken = "cabinetdetective_broken"; icon_closed = "cabinetdetective"; icon_locked = "cabinetdetective_locked"; icon_off = "cabinetdetective_broken"; icon_opened = "cabinetdetective_open"; icon_state = "cabinetdetective"; locked = 0; name = "personal closet"; req_access_txt = "201"},/obj/item/clothing/under/assistantformal,/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"nd" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plating/airless{icon_state = "platingdmg1"; name = "plating"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"ne" = (/turf/simulated/floor/plating/airless/asteroid,/turf/simulated/shuttle/wall{icon_state = "swall_f5"; dir = 2},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nf" = (/turf/simulated/shuttle/floor,/turf/simulated/shuttle/wall{icon_state = "swall_f10"; dir = 2},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"ng" = (/obj/structure/filingcabinet,/turf/simulated/shuttle/floor,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nh" = (/obj/structure/stool/bed/chair{dir = 8},/obj/machinery/light/small,/turf/simulated/shuttle/floor,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"ni" = (/obj/machinery/newscaster{pixel_x = 0; pixel_y = -30},/obj/machinery/light/small,/turf/simulated/shuttle/floor,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"nj" = (/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plasteel/airless{dir = 8; icon_state = "neutralcorner"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"nj" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel/airless{icon_state = "floorscorched1"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nk" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel/airless{icon_state = "damaged2"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nl" = (/obj/machinery/space_heater,/obj/effect/decal/cleanable/generic,/obj/structure/window/basic,/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nm" = (/obj/item/weapon/cigbutt,/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nn" = (/obj/effect/decal/cleanable/dirt,/obj/item/trash/candy,/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"no" = (/turf/simulated/shuttle/wall{icon_state = "swall13"; dir = 2},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"np" = (/obj/structure/sign/vacuum{desc = "A warning sign which reads 'HOSTILE ATMOSPHERE AHEAD'"; name = "\improper HOSTILE ATMOSPHERE AHEAD"; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"nq" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"nr" = (/turf/simulated/floor/plasteel/airless{icon_state = "floorscorched2"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"ns" = (/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg2"; tag = "icon-platingdmg2"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"nq" = (/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg2"; tag = "icon-platingdmg2"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"nr" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor{density = 1; icon_state = "door_closed"; opacity = 1},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"ns" = (/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nt" = (/obj/structure/grille,/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"nu" = (/obj/structure/grille{density = 0; destroyed = 1; icon_state = "brokengrille"},/obj/item/stack/rods,/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"nv" = (/obj/machinery/camera{c_tag = "Dormitories"; dir = 4; network = list("MO19")},/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plasteel/airless{icon_state = "damaged1"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"nu" = (/obj/structure/grille/broken,/obj/item/stack/rods,/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"nv" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel/airless{icon_state = "damaged3"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nw" = (/turf/simulated/floor/plating/airless/asteroid,/turf/simulated/shuttle/wall{icon_state = "swall_f9"; dir = 2},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nx" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plasteel/airless{icon_plating = "asteroidplating"; icon_state = "asteroidplating"; name = "plating"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"ny" = (/obj/machinery/light/small{dir = 1},/obj/structure/window/reinforced{dir = 4; layer = 2.9},/obj/structure/table,/obj/structure/bedsheetbin,/obj/item/clothing/accessory/black,/obj/item/clothing/under/lawyer/black,/turf/simulated/floor/plasteel/airless{icon_state = "barber"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nz" = (/obj/machinery/washing_machine,/turf/simulated/floor/plasteel/airless{icon_state = "barber"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"nA" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "201"; req_one_access_txt = "0"},/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"nA" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nB" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nC" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nD" = (/obj/item/stack/rods,/obj/item/weapon/shard{icon_state = "small"},/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 4; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
"nE" = (/obj/machinery/alarm/monitor{dir = 8; frequency = 1439; locked = 0; pixel_x = 23; pixel_y = 0; req_access = null},/turf/simulated/floor/plasteel/airless{icon_state = "neutralcorner"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"nF" = (/obj/structure/grille{density = 0; destroyed = 1; icon_state = "brokengrille"},/obj/item/stack/rods,/obj/item/weapon/shard,/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 4; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plating/airless{icon_state = "platingdmg1"; name = "plating"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"nF" = (/obj/structure/grille/broken,/obj/item/stack/rods,/obj/item/weapon/shard,/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 4; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plating/airless{icon_state = "platingdmg1"; name = "plating"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nG" = (/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 4; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plasteel/airless{icon_state = "floorgrime"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nH" = (/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 4; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plating/airless{icon_state = "platingdmg3"; name = "plating"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nI" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/obj/machinery/door_control{id = "awaydorm3"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = -25; pixel_y = 0; req_access_txt = "0"; specialfunctions = 4},/obj/effect/decal/remains/human{desc = "They look like human remains. The skeleton is laid out on its side and there seems to have been no sign of struggle."; layer = 4.1},/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nJ" = (/obj/structure/dresser,/obj/item/weapon/paper{info = "Bugs break out. I run to here and lock door. I hear door next to me break open and screams. All nice people here dead now. I no want to be eaten, and bottle always said to be coward way out, but person who say that is stupid. Mira, there is no escape for me, tell Alexis and Elena that father will never come home, and that I love you all."; name = "Note"},/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"nK" = (/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/plating{broken = 1; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"nK" = (/obj/machinery/light/small,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nL" = (/obj/structure/sign/vacuum{desc = "A warning sign which reads 'HOSTILE ATMOSPHERE AHEAD'"; name = "\improper HOSTILE ATMOSPHERE AHEAD"; pixel_x = -32},/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nM" = (/obj/machinery/suit_storage_unit/standard_unit,/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"nN" = (/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 6; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plasteel/airless{icon_state = "floorgrime"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"nN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nO" = (/obj/structure/stool/bed/chair/comfy/black{dir = 8},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel/airless{dir = 8; icon_state = "neutralcorner"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nP" = (/obj/item/weapon/pen,/obj/item/weapon/storage/pill_bottle{pixel_y = 6},/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nQ" = (/obj/machinery/door/airlock{icon_state = "door_locked"; id_tag = "awaydorm3"; locked = 1; name = "Dorm 3"},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nR" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nS" = (/obj/structure/closet,/obj/item/weapon/storage/box/lights/mixed,/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nT" = (/turf/simulated/floor/plasteel/airless{dir = 4; icon_state = "neutral"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
-"nU" = (/obj/structure/closet/secure_closet{desc = "It's a secure locker for personnel. The first card swiped gains control."; icon_broken = "cabinetdetective_broken"; icon_closed = "cabinetdetective"; icon_locked = "cabinetdetective_locked"; icon_off = "cabinetdetective_broken"; icon_opened = "cabinetdetective_open"; icon_state = "cabinetdetective"; locked = 0; name = "personal closet"; req_access_txt = "201"},/obj/item/clothing/under/suit_jacket/burgundy,/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"nU" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nV" = (/obj/machinery/newscaster{pixel_x = 30; pixel_y = 0},/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nW" = (/obj/structure/grille,/obj/structure/disposalpipe/segment,/obj/structure/window/full/reinforced,/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"nX" = (/obj/structure/table,/obj/item/toy/cards/deck,/turf/simulated/floor/plasteel/airless{icon_state = "damaged1"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
@@ -736,9 +736,55 @@
"oh" = (/obj/item/weapon/pickaxe,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
"oi" = (/obj/structure/stool/bed/chair/comfy/black,/turf/simulated/floor/plating/airless,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"oj" = (/obj/structure/disposaloutlet,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/plasteel/airless{icon_plating = "asteroidplating"; icon_state = "asteroidplating"; name = "plating"},/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
+"ok" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"ol" = (/turf/simulated/mineral,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
"om" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
"on" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
+"oo" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"op" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oq" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Diner"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"or" = (/obj/structure/stool,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"os" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"ot" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor,/obj/item/weapon/reagent_containers/glass/rag{pixel_y = 5},/obj/machinery/door/poddoor/shutters{dir = 8; id_tag = "awaykitchen"; name = "Serving Hatch"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"ou" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"ov" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1; pressure_checks = 1},/turf/simulated/floor/plasteel/airless{icon_state = "floorgrime"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"ow" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"ox" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1; pressure_checks = 1},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oy" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oz" = (/obj/machinery/door/firedoor{density = 1; icon_state = "door_closed"; opacity = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oA" = (/obj/structure/closet/secure_closet{desc = "It's a secure locker for personnel. The first card swiped gains control."; icon_broken = "cabinetdetective_broken"; icon_closed = "cabinetdetective"; icon_locked = "cabinetdetective_locked"; icon_off = "cabinetdetective_broken"; icon_opened = "cabinetdetective_open"; icon_state = "cabinetdetective"; locked = 0; name = "personal closet"; req_access_txt = "271"},/obj/item/clothing/under/suit_jacket/navy,/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oB" = (/obj/structure/table,/obj/item/device/multitool,/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oC" = (/obj/item/weapon/cigbutt,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oD" = (/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel/airless{dir = 8; icon_state = "neutralcorner"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oE" = (/obj/machinery/door/airlock{name = "Kitchen Cold Room"; req_access_txt = "271"},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 2; icon_state = "warningcorner"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oG" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel/airless{dir = 8; icon_state = "neutralcorner"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oH" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock{name = "Kitchen"; req_access_txt = "271"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oJ" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "0"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oK" = (/obj/structure/closet/secure_closet{icon_broken = "fridgebroken"; icon_closed = "fridge"; icon_locked = "fridge1"; icon_off = "fridgeoff"; icon_opened = "fridgeopen"; icon_state = "fridge"; locked = 0; name = "meat fridge"; req_access_txt = "271"},/obj/item/weapon/reagent_containers/food/snacks/meat/monkey,/obj/item/weapon/reagent_containers/food/snacks/meat/monkey,/obj/item/weapon/reagent_containers/food/snacks/meat/monkey,/obj/item/weapon/reagent_containers/food/snacks/meat/monkey,/turf/simulated/floor/plasteel{icon_state = "showroomfloor"; temperature = 273.15},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oL" = (/obj/structure/closet/secure_closet{icon_state = "secure"; locked = 0; name = "kitchen Cabinet"; req_access_txt = "271"},/obj/item/weapon/reagent_containers/food/condiment/flour,/obj/item/weapon/reagent_containers/food/condiment/flour,/obj/item/weapon/reagent_containers/food/condiment/sugar,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "showroomfloor"; temperature = 273.15},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oM" = (/obj/structure/closet/secure_closet{icon_broken = "fridgebroken"; icon_closed = "fridge"; icon_locked = "fridge1"; icon_off = "fridgeoff"; icon_opened = "fridgeopen"; icon_state = "fridge"; locked = 0; name = "refrigerator"; req_access_txt = "271"},/obj/item/weapon/reagent_containers/food/condiment/milk,/obj/item/weapon/reagent_containers/food/condiment/milk,/obj/item/weapon/reagent_containers/food/condiment/milk,/obj/item/weapon/storage/fancy/egg_box,/turf/simulated/floor/plasteel{icon_state = "showroomfloor"; temperature = 273.15},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oN" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oO" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 6; level = 1},/obj/machinery/meter,/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oQ" = (/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oR" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel/airless{dir = 8; icon_state = "neutralcorner"; name = "floor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"})
+"oS" = (/obj/machinery/light/small{dir = 4},/obj/effect/decal/cleanable/dirt,/obj/structure/noticeboard{dir = 8; pixel_x = 32; pixel_y = 0},/obj/item/weapon/paper{info = "
Welcome to Moon Outpost 19! Property of Nanotrasen Inc.
Staff Roster:
Dr. Gerald Rosswell: Research Director & Acting Captain
- Toxins
- Oxygen
- Nitrogen
- Carbon Dioxide
- Nitrous Oxide
- Nothing
- Desirable output pressure:
- [target_pressure]kPa | Change
- "}
+/obj/machinery/atmospherics/trinary/filter/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state)
+ user.set_machine(src)
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "atmos_filter.tmpl", name, 475, 155, state = state)
+ ui.open()
- var/datum/browser/popup = new(user, "atmo_filter", name, 400, 400)
- popup.set_content(dat)
- popup.open(0)
- onclose(user, "atmo_filter")
+/obj/machinery/atmospherics/trinary/filter/ui_data(mob/user)
+ var/list/data = list()
+ data["on"] = on
+ data["pressure"] = round(target_pressure)
+ data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
+ data["filter_type"] = filter_type
+ return data
/obj/machinery/atmospherics/trinary/filter/Topic(href, href_list) // -- TLE
if(..())
return 1
- usr.set_machine(src)
- add_fingerprint(usr)
- if(href_list["filterset"])
- filter_type = text2num(href_list["filterset"])
- if(href_list["temp"])
- temp = null
- if(href_list["set_press"])
- var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",target_pressure) as num
- target_pressure = max(0, min(4500, new_pressure))
+
if(href_list["power"])
- on=!on
+ on = !on
+ investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
+ . = TRUE
+ if(href_list["pressure"])
+ var/pressure = href_list["pressure"]
+ if(pressure == "max")
+ pressure = MAX_OUTPUT_PRESSURE
+ . = TRUE
+ else if(pressure == "input")
+ pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
+ if(!isnull(pressure) && !..())
+ . = TRUE
+ else if(text2num(pressure) != null)
+ pressure = text2num(pressure)
+ . = TRUE
+ if(.)
+ target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
+ investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
+ if(href_list["filter"])
+ filter_type = text2num(href_list["filter"])
+ investigate_log("was set to filter [filter_type] by [key_name(usr)]", "atmos")
+ . = TRUE
+
update_icon()
- updateUsrDialog()
\ No newline at end of file
+ nanomanager.update_uis(src)
\ No newline at end of file
diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
index f859175cdb2..0657f8d9f5f 100644
--- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
@@ -16,7 +16,7 @@
icon_state = "mmap"
flipped = 1
-/obj/machinery/atmospherics/trinary/mixer/update_icon(var/safety = 0)
+/obj/machinery/atmospherics/trinary/mixer/update_icon(safety = 0)
if(flipped)
icon_state = "m"
else
@@ -107,9 +107,9 @@
parent3.update = 1
return 1
-
-/obj/machinery/atmospherics/trinary/mixer/attack_ghost(mob/user)
- interact(user)
+
+/obj/machinery/atmospherics/trinary/mixer/attack_ghost(mob/user)
+ ui_interact(user)
/obj/machinery/atmospherics/trinary/mixer/attack_hand(mob/user)
if(..())
@@ -118,52 +118,61 @@
if(!allowed(user))
to_chat(user, "Access denied.")
return
-
- interact(user)
-
-/obj/machinery/atmospherics/trinary/mixer/interact(mob/user)
- user.set_machine(src)
- add_fingerprint(user)
- var/dat = {"Power: [on?"On":"Off"]
- Desirable output pressure:
- [target_pressure]kPa | Change
-
- Node 1 Concentration:
- -
- -
- [node1_concentration]([node1_concentration*100]%)
- +
- +
-
- Node 2 Concentration:
- -
- -
- [node2_concentration]([node2_concentration*100]%)
- +
- +
- "}
- var/datum/browser/popup = new(user, "atmo_mixer", name, 400, 400)
- popup.set_content(dat)
- popup.open(0)
- onclose(user, "atmo_mixer")
+ add_fingerprint(user)
+ ui_interact(user)
+
+/obj/machinery/atmospherics/trinary/mixer/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state)
+ user.set_machine(src)
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "atmos_mixer.tmpl", name, 370, 165, state = state)
+ ui.open()
+
+/obj/machinery/atmospherics/trinary/mixer/ui_data(mob/user)
+ var/list/data = list()
+ data["on"] = on
+ data["pressure"] = round(target_pressure)
+ data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
+ data["node1_concentration"] = round(node1_concentration*100)
+ data["node2_concentration"] = round(node2_concentration*100)
+ return data
/obj/machinery/atmospherics/trinary/mixer/Topic(href,href_list)
if(..())
return 1
+
if(href_list["power"])
on = !on
- if(href_list["set_press"])
- var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",target_pressure) as num
- target_pressure = max(0, min(4500, new_pressure))
- if(href_list["node1_c"])
- var/value = text2num(href_list["node1_c"])
+ investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
+ . = TRUE
+ if(href_list["pressure"])
+ var/pressure = href_list["pressure"]
+ if(pressure == "max")
+ pressure = MAX_OUTPUT_PRESSURE
+ . = TRUE
+ else if(pressure == "input")
+ pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
+ if(!isnull(pressure) && !..())
+ . = TRUE
+ else if(text2num(pressure) != null)
+ pressure = text2num(pressure)
+ . = TRUE
+ if(.)
+ target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
+ investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
+ if(href_list["node1"])
+ var/value = text2num(href_list["node1"])
node1_concentration = max(0, min(1, node1_concentration + value))
node2_concentration = max(0, min(1, node2_concentration - value))
- if(href_list["node2_c"])
- var/value = text2num(href_list["node2_c"])
+ investigate_log("was set to [node1_concentration] % on node 1 by [key_name(usr)]", "atmos")
+ . = TRUE
+ if(href_list["node2"])
+ var/value = text2num(href_list["node2"])
node2_concentration = max(0, min(1, node2_concentration + value))
node1_concentration = max(0, min(1, node1_concentration - value))
+ investigate_log("was set to [node2_concentration] % on node 2 by [key_name(usr)]", "atmos")
+ . = TRUE
+
update_icon()
- updateUsrDialog()
- return
+ nanomanager.update_uis(src)
\ No newline at end of file
diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm
index a2ba4429ffa..08febf1c572 100644
--- a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm
@@ -325,9 +325,9 @@
var/obj/item/weapon/weldingtool/WT = W
if(WT.remove_fuel(0,user))
to_chat(user, "Now welding the vent.")
- if(do_after(user, 20, target = src))
+ if(do_after(user, 20 * WT.toolspeed, target = src))
if(!src || !WT.isOn()) return
- playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(src.loc, WT.usesound, 50, 1)
if(!welded)
user.visible_message("[user] welds the vent shut.", "You weld the vent shut.", "You hear welding.")
welded = 1
@@ -337,23 +337,25 @@
welded = 0
update_icon()
else
-
to_chat(user, "The welding tool needs to be on to start this task.")
+ return 1
else
to_chat(user, "You need more welding fuel to complete this task.")
return 1
if(istype(W, /obj/item/weapon/screwdriver))
if(!welded)
if(open)
- to_chat(user, " Now closing the vent.")
- if(do_after(user, 20, target = src))
+ to_chat(user, "Now closing the vent.")
+ if(do_after(user, 20 * W.toolspeed, target = src))
+ playsound(loc, W.usesound, 100, 1)
open = 0
user.visible_message("[user] screwdrivers the vent shut.", "You screwdriver the vent shut.", "You hear a screwdriver.")
else
- to_chat(user, " Now opening the vent.")
- if(do_after(user, 20, target = src))
+ to_chat(user, "Now opening the vent.")
+ if(do_after(user, 20 * W.toolspeed, target = src))
+ playsound(loc, W.usesound, 100, 1)
open = 1
- user.visible_message("[user] screwdrivers the vent shut.", "You screwdriver the vent shut.", "You hear a screwdriver.")
+ user.visible_message("[user] screwdrivers the vent open.", "You screwdriver the vent open.", "You hear a screwdriver.")
return
if(istype(W, /obj/item/weapon/paper))
if(!welded)
@@ -364,7 +366,7 @@
to_chat(user, "You can't shove that down there when it is closed")
else
to_chat(user, "The vent is welded.")
- return
+ return 1
if(istype(W, /obj/item/device/multitool))
update_multitool_menu(user)
return 1
diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm
index 5554723c945..6747b103972 100644
--- a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm
@@ -375,9 +375,9 @@
var/obj/item/weapon/weldingtool/WT = W
if(WT.remove_fuel(0,user))
to_chat(user, "Now welding the scrubber.")
- if(do_after(user, 20, target = src))
+ if(do_after(user, 20 * WT.toolspeed, target = src))
if(!src || !WT.isOn()) return
- playsound(get_turf(src), 'sound/items/Welder2.ogg', 50, 1)
+ playsound(get_turf(src), WT.usesound, 50, 1)
if(!welded)
user.visible_message("[user] welds the scrubber shut.", "You weld the vent scrubber.", "You hear welding.")
welded = 1
diff --git a/code/ATMOSPHERICS/pipes/pipe.dm b/code/ATMOSPHERICS/pipes/pipe.dm
index f319e563835..05c5d18df99 100644
--- a/code/ATMOSPHERICS/pipes/pipe.dm
+++ b/code/ATMOSPHERICS/pipes/pipe.dm
@@ -21,8 +21,7 @@
/obj/machinery/atmospherics/pipe/Destroy()
releaseAirToTurf()
- qdel(air_temporary)
- air_temporary = null
+ QDEL_NULL(air_temporary)
var/turf/T = loc
for(var/obj/machinery/meter/meter in T)
diff --git a/code/LINDA/LINDA_system.dm b/code/LINDA/LINDA_system.dm
index 3c2d0cd34a7..cbb3c546990 100644
--- a/code/LINDA/LINDA_system.dm
+++ b/code/LINDA/LINDA_system.dm
@@ -35,10 +35,10 @@
atom/movable/proc/CanAtmosPass()
return 1
-atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
- return (!density || !height || air_group)
+atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5)
+ return (!density || !height)
-turf/CanPass(atom/movable/mover, turf/target, height=1.5,air_group=0)
+turf/CanPass(atom/movable/mover, turf/target, height=1.5)
if(!target) return 0
if(istype(mover)) // turf/Enter(...) will perform more advanced checks
@@ -49,10 +49,10 @@ turf/CanPass(atom/movable/mover, turf/target, height=1.5,air_group=0)
return 0
for(var/obj/obstacle in src)
- if(!obstacle.CanPass(mover, target, height, air_group))
+ if(!obstacle.CanPass(mover, target, height))
return 0
for(var/obj/obstacle in target)
- if(!obstacle.CanPass(mover, src, height, air_group))
+ if(!obstacle.CanPass(mover, src, height))
return 0
return 1
diff --git a/code/LINDA/LINDA_turf_tile.dm b/code/LINDA/LINDA_turf_tile.dm
index 7004e6c55fb..28c1a7e6860 100644
--- a/code/LINDA/LINDA_turf_tile.dm
+++ b/code/LINDA/LINDA_turf_tile.dm
@@ -70,8 +70,7 @@
/turf/simulated/Destroy()
visibilityChanged()
- if(active_hotspot)
- qdel(active_hotspot)
+ QDEL_NULL(active_hotspot)
return ..()
/turf/simulated/assume_air(datum/gas_mixture/giver)
diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm
index d2988a6474f..fe7e2b0067c 100644
--- a/code/__DEFINES/atmospherics.dm
+++ b/code/__DEFINES/atmospherics.dm
@@ -114,4 +114,9 @@
// Atmos pipe limits
#define MAX_OUTPUT_PRESSURE 4500 // (kPa) What pressure pumps and powered equipment max out at.
-#define MAX_TRANSFER_RATE 200 // (L/s) Maximum speed powered equipment can work at.
\ No newline at end of file
+#define MAX_TRANSFER_RATE 200 // (L/s) Maximum speed powered equipment can work at.
+
+// Atmos alarm defines
+#define ATMOS_ALARM_NONE 0
+#define ATMOS_ALARM_WARNING 1
+#define ATMOS_ALARM_DANGER 2
\ No newline at end of file
diff --git a/code/__DEFINES/clothing.dm b/code/__DEFINES/clothing.dm
index 6e1934a77ae..1d87f8845c8 100644
--- a/code/__DEFINES/clothing.dm
+++ b/code/__DEFINES/clothing.dm
@@ -71,6 +71,13 @@
#define THERMAL_PROTECTION_HAND_LEFT 0.025
#define THERMAL_PROTECTION_HAND_RIGHT 0.025
+//flags for covering body parts
+#define GLASSESCOVERSEYES 1
+#define MASKCOVERSEYES 2 // get rid of some of the other retardation in these flags
+#define HEADCOVERSEYES 4 // feel free to realloc these numbers for other purposes
+#define MASKCOVERSMOUTH 8 // on other items, these are just for mask/head
+#define HEADCOVERSMOUTH 16
+
// Suit sensor levels
#define SUIT_SENSOR_OFF 0
#define SUIT_SENSOR_BINARY 1
diff --git a/code/__DEFINES/construction.dm b/code/__DEFINES/construction.dm
new file mode 100644
index 00000000000..ce1003d33a8
--- /dev/null
+++ b/code/__DEFINES/construction.dm
@@ -0,0 +1,7 @@
+/*ALL DEFINES RELATED TO CONSTRUCTION, CONSTRUCTING THINGS, OR CONSTRUCTED OBJECTS GO HERE*/
+
+//Defines for construction states
+
+//plastic flaps construction states
+#define PLASTIC_FLAPS_NORMAL 0
+#define PLASTIC_FLAPS_DETACHED 1
diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm
index a4d9ca87384..1cba02075a7 100644
--- a/code/__DEFINES/flags.dm
+++ b/code/__DEFINES/flags.dm
@@ -8,17 +8,12 @@
#define ABSTRACT 64 // for all things that are technically items but used for various different stuff, made it 128 because it could conflict with other flags other way
#define ON_BORDER 128 // item has priority to check when entering or leaving
-#define GLASSESCOVERSEYES 1024
-#define MASKCOVERSEYES 1024 // get rid of some of the other retardation in these flags
-#define HEADCOVERSEYES 1024 // feel free to realloc these numbers for other purposes
-#define MASKCOVERSMOUTH 2048 // on other items, these are just for mask/head
-#define HEADCOVERSMOUTH 2048
-
-#define HEADBANGPROTECT 4096
#define EARBANGPROTECT 1024
#define NOSLIP 1024 //prevents from slipping on wet floors, in space etc
+#define HEADBANGPROTECT 4096
+
#define OPENCONTAINER 4096 // is an open container for chemistry purposes
#define BLOCK_GAS_SMOKE_EFFECT 8192 // blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY!
diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm
index 6771d8062fc..4126fe1725f 100644
--- a/code/__DEFINES/hud.dm
+++ b/code/__DEFINES/hud.dm
@@ -7,7 +7,7 @@
#define STATUS_HUD "2" // a simple line rounding the mob's number health
#define ID_HUD "3" // the job asigned to your ID
#define WANTED_HUD "4" // wanted, released, parroled, security status
-#define IMPLOYAL_HUD "5" // loyality implant
+#define IMPMINDSHIELD_HUD "5" // mindshield implant
#define IMPCHEM_HUD "6" // chemical implant
#define IMPTRACK_HUD "7" // tracking implant
#define DIAG_STAT_HUD "8" // Silicon/Mech Status
diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm
index c95c3bb5b55..23b44679a9d 100644
--- a/code/__DEFINES/machines.dm
+++ b/code/__DEFINES/machines.dm
@@ -31,4 +31,43 @@
// multitool_topic() shit
#define MT_ERROR -1
#define MT_UPDATE 1
-#define MT_REINIT 2
\ No newline at end of file
+#define MT_REINIT 2
+
+//Modular computer/NTNet defines
+
+//Modular computer part defines
+#define MC_CPU "CPU"
+#define MC_HDD "HDD"
+#define MC_SDD "SDD"
+#define MC_CARD "CARD"
+#define MC_NET "NET"
+#define MC_PRINT "PRINT"
+#define MC_CELL "CELL"
+#define MC_CHARGE "CHARGE"
+#define MC_AI "AI"
+
+//NTNet stuff, for modular computers
+ // NTNet module-configuration values. Do not change these. If you need to add another use larger number (5..6..7 etc)
+#define NTNET_SOFTWAREDOWNLOAD 1 // Downloads of software from NTNet
+#define NTNET_PEERTOPEER 2 // P2P transfers of files between devices
+#define NTNET_COMMUNICATION 3 // Communication (messaging)
+#define NTNET_SYSTEMCONTROL 4 // Control of various systems, RCon, air alarm control, etc.
+
+//NTNet transfer speeds, used when downloading/uploading a file/program.
+#define NTNETSPEED_LOWSIGNAL 0.5 // GQ/s transfer speed when the device is wirelessly connected and on Low signal
+#define NTNETSPEED_HIGHSIGNAL 1 // GQ/s transfer speed when the device is wirelessly connected and on High signal
+#define NTNETSPEED_ETHERNET 2 // GQ/s transfer speed when the device is using wired connection
+
+//Caps for NTNet logging. Less than 10 would make logging useless anyway, more than 500 may make the log browser too laggy. Defaults to 100 unless user changes it.
+#define MAX_NTNET_LOGS 300
+#define MIN_NTNET_LOGS 10
+
+//Program bitflags
+#define PROGRAM_ALL 7
+#define PROGRAM_CONSOLE 1
+#define PROGRAM_LAPTOP 2
+#define PROGRAM_TABLET 4
+//Program states
+#define PROGRAM_STATE_KILLED 0
+#define PROGRAM_STATE_BACKGROUND 1
+#define PROGRAM_STATE_ACTIVE 2
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 75f953f6c79..b3263a93425 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -58,6 +58,16 @@
#define COLOR_WHITE "#FFFFFF"
#define COLOR_GRAY "#808080"
+//FONTS:
+// Used by Paper and PhotoCopier (and PaperBin once a year).
+// Used by PDA's Notekeeper.
+// Used by NewsCaster and NewsPaper.
+// Used by Modular Computers
+#define PEN_FONT "Verdana"
+#define CRAYON_FONT "Comic Sans MS"
+#define PRINTER_FONT "Times New Roman"
+#define SIGNFONT "Times New Roman"
+
//some arbitrary defines to be used by self-pruning global lists. (see master_controller)
#define PROCESS_KILL 26 //Used to trigger removal from a processing list
diff --git a/code/__DEFINES/mob.dm b/code/__DEFINES/mob.dm
index 7ab8a19f86d..97cea621dae 100644
--- a/code/__DEFINES/mob.dm
+++ b/code/__DEFINES/mob.dm
@@ -54,6 +54,8 @@
#define DEFAULT_MARKING_STYLES list("head" = "None", "body" = "None", "tail" = "None") //Marking styles. Use instead of initial() for m_styles.
#define DEFAULT_MARKING_COLOURS list("head" = "#000000", "body" = "#000000", "tail" = "#000000") //Marking colours. Use instead of initial() for m_colours.
+#define OXYCONCEN_PLASMEN_IGNITION 0.5 //Moles of oxygen in the air needed to light up a poorly clothed Plasmaman. Same as LINDA requirements for plasma burning.
+
////////REAGENT STUFF////////
// How many units of reagent are consumed per tick, by default.
#define REAGENTS_METABOLISM 0.4
@@ -122,6 +124,9 @@
#define islarva(A) (istype((A), /mob/living/carbon/alien/larva))
#define isslime(A) (istype((A), /mob/living/carbon/slime))
+//Human sub-species
+#define isabductor(A) (is_species(A, "Abductor"))
+
#define isanimal(A) (istype((A), /mob/living/simple_animal))
#define iscorgi(A) (istype((A), /mob/living/simple_animal/pet/corgi))
#define ismouse(A) (istype((A), /mob/living/simple_animal/mouse))
@@ -129,11 +134,21 @@
#define isswarmer(A) (istype((A), /mob/living/simple_animal/hostile/swarmer))
#define isguardian(A) (istype((A), /mob/living/simple_animal/hostile/guardian))
+
+
#define issilicon(A) (istype((A), /mob/living/silicon))
#define isAI(A) (istype((A), /mob/living/silicon/ai))
#define isrobot(A) (istype((A), /mob/living/silicon/robot))
#define ispAI(A) (istype((A), /mob/living/silicon/pai))
+// For the tcomms monitor
+#define ispathhuman(A) (ispath(A, /mob/living/carbon/human))
+#define ispathbrain(A) (ispath(A, /mob/living/carbon/brain))
+#define ispathslime(A) (ispath(A, /mob/living/carbon/slime))
+#define ispathbot(A) (ispath(A, /mob/living/simple_animal/bot))
+#define ispathsilicon(A) (ispath(A, /mob/living/silicon))
+#define ispathanimal(A) (ispath(A, /mob/living/simple_animal))
+
#define isAutoAnnouncer(A) (istype((A), /mob/living/automatedannouncer))
#define isAIEye(A) (istype((A), /mob/camera/aiEye))
diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm
index 667c7152e85..1b848686bc3 100644
--- a/code/__DEFINES/role_preferences.dm
+++ b/code/__DEFINES/role_preferences.dm
@@ -8,6 +8,7 @@
//then you MUST update the database!
// If you're adding a new role, remember to update modules/admin/topic.dm, so admins can dish out
// justice if someone's abusing your role
+#define ROLE_SYNDICATE "Syndicate"
#define ROLE_TRAITOR "traitor"
#define ROLE_OPERATIVE "operative"
#define ROLE_CHANGELING "changeling"
@@ -37,7 +38,7 @@
#define ROLE_MORPH "morph"
#define ROLE_ERT "emergency response team"
#define ROLE_NYMPH "Dionaea"
-#define ROLE_GSPIDER "giant spider"
+#define ROLE_GSPIDER "giant spider"
//Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR.
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index c6f0e9bf1c9..5edccb012e3 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -463,7 +463,7 @@ proc/pollCandidates(Question, be_special_type, antag_age_check = 0, poll_time =
G << 'sound/misc/notice2.ogg'//Alerting them to their consideration
if(flashwindow)
window_flash(G.client)
- switch(alert(G,Question,"Please answer in [poll_time/10] seconds!","Yes","No","Not This Round"))
+ switch(alert(G,Question,"Please answer in [poll_time/10] seconds!","No","Yes","Not This Round"))
if("Yes")
to_chat(G, "Choice registered: Yes.")
if((world.time-time_passed)>poll_time)//If more than 30 game seconds passed.
diff --git a/code/__HELPERS/logging.dm b/code/__HELPERS/logging.dm
index 3dd0f9235bd..de827703443 100644
--- a/code/__HELPERS/logging.dm
+++ b/code/__HELPERS/logging.dm
@@ -78,6 +78,10 @@
if(config.log_pda)
diary << "\[[time_stamp()]]PDA: [text][log_end]"
+/proc/log_chat(text)
+ if (config.log_pda)
+ diary << "\[[time_stamp()]]CHAT: [text]"
+
/proc/log_misc(text)
diary << "\[[time_stamp()]]MISC: [text][log_end]"
@@ -98,7 +102,7 @@
/proc/log_after_setup(var/message)
if(ticker && ticker.current_state > GAME_STATE_SETTING_UP)
to_chat(world, "[message]")
- log_to_dd(message)
+ log_to_dd(message)
// Helper procs for building detailed log lines
diff --git a/code/__HELPERS/maths.dm b/code/__HELPERS/maths.dm
index b0312d44134..aa73b686b9d 100644
--- a/code/__HELPERS/maths.dm
+++ b/code/__HELPERS/maths.dm
@@ -110,3 +110,9 @@ var/gaussian_next
if(new_val < bound_lower)
new_val = min(orig_val, bound_lower)
return new_val
+
+// sqrt, but if you give it a negative number, you get 0 instead of a runtime
+/proc/sqrtor0(num)
+ if(num < 0)
+ return 0
+ return sqrt(num)
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index 3cc200ce004..0abf2ac1af3 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -363,6 +363,13 @@ proc/add_logs(mob/user, mob/target, what_done, var/object=null, var/addition=nul
if(progress)
qdel(progbar)
+/proc/is_species(A, species_name)
+ . = FALSE
+ if(ishuman(A))
+ var/mob/living/carbon/human/H = A
+ if(H.get_species() == species_name)
+ . = TRUE
+
/proc/admin_mob_info(mob/M, mob/user = usr)
if(!ismob(M))
to_chat(user, "This can only be used on instances of type /mob")
@@ -433,3 +440,27 @@ proc/add_logs(mob/user, mob/target, what_done, var/object=null, var/addition=nul
break
if(!.)
to_chat(user, "No mob located in [A].")
+
+// Suppress the mouse macros
+/client/var/next_mouse_macro_warning
+/mob/proc/LogMouseMacro(verbused, params)
+ if(!client)
+ return
+ if(!client.next_mouse_macro_warning) // Log once
+ log_admin("[key_name(usr)] attempted to use a mouse macro: [verbused] [params]")
+ message_admins("[key_name_admin(usr)] attempted to use a mouse macro: [verbused] [html_encode(params)]")
+ if(client.next_mouse_macro_warning < world.time) // Warn occasionally
+ usr << 'sound/misc/sadtrombone.ogg'
+ client.next_mouse_macro_warning = world.time + 600
+/mob/verb/ClickSubstitute(params as command_text)
+ set hidden = 1
+ set name = ".click"
+ LogMouseMacro(".click", params)
+/mob/verb/DblClickSubstitute(params as command_text)
+ set hidden = 1
+ set name = ".dblclick"
+ LogMouseMacro(".dblclick", params)
+/mob/verb/MouseSubstitute(params as command_text)
+ set hidden = 1
+ set name = ".mouse"
+ LogMouseMacro(".mouse", params)
diff --git a/code/__HELPERS/qdel.dm b/code/__HELPERS/qdel.dm
new file mode 100644
index 00000000000..e8a11f27a66
--- /dev/null
+++ b/code/__HELPERS/qdel.dm
@@ -0,0 +1,2 @@
+#define QDEL_IN(item, time) addtimer(GLOBAL_PROC, "qdel", time, FALSE, item)
+#define QDEL_NULL(item) if(item) { qdel(item); item = null }
\ No newline at end of file
diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm
index 84c8ec3656e..89755d7acf0 100644
--- a/code/__HELPERS/text.dm
+++ b/code/__HELPERS/text.dm
@@ -64,6 +64,14 @@
/proc/strip_html(var/t,var/limit=MAX_MESSAGE_LEN)
return copytext((sanitize(strip_html_simple(t))),1,limit)
+// Used to get a properly sanitized multiline input, of max_length
+/proc/stripped_multiline_input(mob/user, message = "", title = "", default = "", max_length=MAX_MESSAGE_LEN, no_trim=FALSE)
+ var/name = input(user, message, title, default) as message|null
+ if(no_trim)
+ return copytext(html_encode(name), 1, max_length)
+ else
+ return trim(html_encode(name), max_length)
+
//Runs byond's sanitization proc along-side strip_html_simple
//I believe strip_html_simple() is required to run first to prevent '<' from displaying as '<' that html_encode() would cause
/proc/adminscrub(var/t,var/limit=MAX_MESSAGE_LEN)
@@ -378,18 +386,10 @@ proc/checkhtml(var/t)
return sanitize(replace_characters(input, list(">"=" ","<"=" ", "\""="'")), max_length, encode, trim, extra)
-//Replaces \red \blue \green \b etc with span classes for to_chat
+//Replace BYOND text macros with span classes for to_chat
/proc/replace_text_macro(match, code, rest)
- var/regex/text_macro = new("(\\xFF.)(.*)$")
- switch(code)
- if("\red")
- return "[text_macro.Replace(rest, /proc/replace_text_macro)]"
- if("\blue", "\green")
- return "[text_macro.Replace(rest, /proc/replace_text_macro)]"
- if("\b")
- return "[text_macro.Replace(rest, /proc/replace_text_macro)]"
- else
- return text_macro.Replace(rest, /proc/replace_text_macro)
+ var/regex/text_macro = new("(\\xFF.)(.*)$")
+ return text_macro.Replace(rest, /proc/replace_text_macro)
/proc/macro2html(text)
var/static/regex/text_macro = new("(\\xFF.)(.*)$")
@@ -448,7 +448,7 @@ proc/checkhtml(var/t)
// Pencode
-/proc/pencode_to_html(text, mob/user, var/obj/item/weapon/pen/P = null, deffont = "Verdana", signfont = "Times New Roman", crayonfont = "Comic Sans MS")
+/proc/pencode_to_html(text, mob/user, obj/item/weapon/pen/P = null, sign = 1, fields = 1, deffont = PEN_FONT, signfont = SIGNFONT, crayonfont = CRAYON_FONT)
text = replacetext(text, "\n", " ")
text = replacetext(text, "\[center\]", "
")
text = replacetext(text, "\[/center\]", "
")
@@ -461,8 +461,10 @@ proc/checkhtml(var/t)
text = replacetext(text, "\[/u\]", "")
text = replacetext(text, "\[large\]", "")
text = replacetext(text, "\[/large\]", "")
- text = replacetext(text, "\[sign\]", "[user ? user.real_name : "Anonymous"]")
- text = replacetext(text, "\[field\]", "")
+ if(sign)
+ text = replacetext(text, "\[sign\]", "[user ? user.real_name : "Anonymous"]")
+ if(fields)
+ text = replacetext(text, "\[field\]", "")
text = replacetext(text, "\[h1\]", "
")
text = replacetext(text, "\[/h1\]", "
")
@@ -539,3 +541,4 @@ proc/checkhtml(var/t)
text = replacetext(text, "
", "\[cell\]")
text = replacetext(text, "", "\[logo\]")
return text
+
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 930e8244eb6..82b2ea8b419 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -550,17 +550,17 @@ proc/anim(turf/location as turf,target as mob|obj,a_icon,a_icon_state as text,fl
var/turf/current = get_turf(source)
var/turf/target_turf = get_turf(target)
var/steps = 1
-
+
if(current != target_turf)
- current = get_step_towards(current, target_turf)
+ current = get_step_towards(current, target_turf)
while(current != target_turf)
- if(steps > length)
+ if(steps > length)
return 0
- if(current.opacity)
+ if(current.opacity)
return 0
for(var/thing in current)
var/atom/A = thing
- if(A.opacity)
+ if(A.opacity)
return 0
current = get_step_towards(current, target_turf)
steps++
@@ -1347,19 +1347,19 @@ Standard way to write links -Sayu
/proc/get_location_accessible(mob/M, location)
var/covered_locations = 0 //based on body_parts_covered
var/face_covered = 0 //based on flags_inv
- var/eyesmouth_covered = 0 //based on flags
+ var/eyesmouth_covered = 0 //based on flags_cover
if(iscarbon(M))
var/mob/living/carbon/C = M
for(var/obj/item/clothing/I in list(C.back, C.wear_mask))
covered_locations |= I.body_parts_covered
face_covered |= I.flags_inv
- eyesmouth_covered |= I.flags
+ eyesmouth_covered |= I.flags_cover
if(ishuman(C))
var/mob/living/carbon/human/H = C
for(var/obj/item/I in list(H.wear_suit, H.w_uniform, H.shoes, H.belt, H.gloves, H.glasses, H.head, H.r_ear, H.l_ear))
covered_locations |= I.body_parts_covered
face_covered |= I.flags_inv
- eyesmouth_covered |= I.flags
+ eyesmouth_covered |= I.flags_cover
switch(location)
if("head")
@@ -1863,7 +1863,7 @@ var/global/list/g_fancy_list_of_types = null
pois[name] = A
return pois
-
+
/proc/flash_color(mob_or_client, flash_color="#960000", flash_time=20)
var/client/C
if(istype(mob_or_client, /mob))
@@ -1881,7 +1881,7 @@ var/global/list/g_fancy_list_of_types = null
C.color = flash_color
spawn(0)
animate(C, color = initial(C.color), time = flash_time)
-
+
#define RANDOM_COLOUR (rgb(rand(0,255),rand(0,255),rand(0,255)))
/proc/make_bit_triplet()
diff --git a/code/_globalvars/configuration.dm b/code/_globalvars/configuration.dm
index 3e2d7d995d6..2d9b9761523 100644
--- a/code/_globalvars/configuration.dm
+++ b/code/_globalvars/configuration.dm
@@ -19,6 +19,10 @@ var/shuttle_left = 0
var/tinted_weldhelh = 1
var/mouse_respawn_time = 5 //Amount of time that must pass between a player dying as a mouse and repawning as a mouse. In minutes.
+// Command to run if shutting down (SHUTDOWN_ON_REBOOT) instead of rebooting
+// It's defined here as a global because this is a hilariously bad thing to have on the easily-edited config datum
+var/global/shutdown_shell_command
+
// Debug is used exactly once (in living.dm) but is commented out in a lot of places. It is not set anywhere and only checked.
// Debug2 is used in conjunction with a lot of admin verbs and therefore is actually legit.
var/Debug = 0 // global debug switch
diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm
index c139b969df1..4639f5d93cf 100644
--- a/code/_globalvars/lists/flavor_misc.dm
+++ b/code/_globalvars/lists/flavor_misc.dm
@@ -25,12 +25,10 @@ var/global/list/socks_m = list() //stores only socks name
var/global/list/socks_f = list() //stores only socks name
//Alt Heads
var/global/list/alt_heads_list = list() //stores /datum/sprite_accessory/alt_heads indexed by name
- //Backpacks
-var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt")
var/static/list/scarySounds = list('sound/weapons/thudswoosh.ogg','sound/weapons/Taser.ogg','sound/weapons/armbomb.ogg','sound/voice/hiss1.ogg','sound/voice/hiss2.ogg', \
'sound/voice/hiss3.ogg','sound/voice/hiss4.ogg','sound/voice/hiss5.ogg','sound/voice/hiss6.ogg','sound/effects/Glassbr1.ogg','sound/effects/Glassbr2.ogg','sound/effects/Glassbr3.ogg', \
-'sound/items/Welder.ogg','sound/items/Welder2.ogg','sound/machines/airlock.ogg','sound/effects/clownstep1.ogg','sound/effects/clownstep2.ogg')
+'sound/items/Welder.ogg','sound/items/Welder2.ogg','sound/machines/airlock_open.ogg','sound/effects/clownstep1.ogg','sound/effects/clownstep2.ogg')
// Reference list for disposal sort junctions. Set the sortType variable on disposal sort junctions to
// the index of the sort department that you want. For example, sortType set to 2 will reroute all packages
@@ -62,4 +60,14 @@ var/global/list/phonetic_alphabet = list("Alpha", "Bravo", "Charlie",
var/global/list/numbers_as_words = list("One", "Two", "Three", "Four",
"Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve",
"Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen",
- "Eighteen", "Nineteen")
\ No newline at end of file
+ "Eighteen", "Nineteen")
+
+ //Backpacks
+#define GBACKPACK "Grey Backpack"
+#define GSATCHEL "Grey Satchel"
+#define GDUFFLEBAG "Grey Dufflebag"
+#define LSATCHEL "Leather Satchel"
+#define DBACKPACK "Department Backpack"
+#define DSATCHEL "Department Satchel"
+#define DDUFFLEBAG "Department Dufflebag"
+var/global/list/backbaglist = list(DBACKPACK, DSATCHEL, DDUFFLEBAG, GBACKPACK, GSATCHEL, GDUFFLEBAG, LSATCHEL)
diff --git a/code/_globalvars/lists/misc.dm b/code/_globalvars/lists/misc.dm
index eb5c500573b..a6b78bce94c 100644
--- a/code/_globalvars/lists/misc.dm
+++ b/code/_globalvars/lists/misc.dm
@@ -14,10 +14,19 @@ var/list/restricted_camera_networks = list( //Those networks can only be accesse
"Thunderdome",
"UO45",
"UO45R",
+ "UO71",
"Xeno",
"Hotel"
)
var/list/mineral_turfs = list()
-var/list/ruin_landmarks = list()
\ No newline at end of file
+var/list/ruin_landmarks = list()
+
+var/list/round_end_sounds = list( // Maps available round end sounds to their duration
+ 'sound/AI/newroundsexy.ogg' = 2.3 SECONDS,
+ 'sound/misc/apcdestroyed.ogg' = 3 SECONDS,
+ 'sound/misc/bangindonk.ogg' = 1.6 SECONDS,
+ 'sound/goonstation/misc/newround1.ogg' = 6.9 SECONDS,
+ 'sound/goonstation/misc/newround2.ogg' = 14.8 SECONDS
+ )
diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm
index 41588a7b07a..f4fad058068 100644
--- a/code/_globalvars/lists/objects.dm
+++ b/code/_globalvars/lists/objects.dm
@@ -30,7 +30,7 @@ var/global/list/deliverybeacons = list() //list of all MULEbot delivery beacon
var/global/list/deliverybeacontags = list() //list of all tags associated with delivery beacons.
var/global/list/beacons = list()
-var/global/list/shuttle_caller_list = list() //list of all communication consoles and AIs, for automatic shuttle calls when there are none.
+var/global/list/shuttle_caller_list = list() //list of all communication consoles, comms consoles circuit and AIs, for automatic shuttle calls when there are none.
var/global/list/tracked_implants = list() //list of all current implants that are tracked to work out what sort of trek everyone is on. Sadly not on lavaworld not implemented...
var/global/list/pinpointer_list = list() //list of all pinpointers. Used to change stuff they are pointing to all at once.
var/global/list/abductor_equipment = list() //list of all abductor equipment
diff --git a/code/_globalvars/mapping.dm b/code/_globalvars/mapping.dm
index 841fbced3f7..4915b91f3d0 100644
--- a/code/_globalvars/mapping.dm
+++ b/code/_globalvars/mapping.dm
@@ -40,6 +40,7 @@ var/list/prisonwarped = list() //list of players already warped
var/list/blobstart = list()
var/list/ninjastart = list()
var/list/carplist = list() //list of all carp-spawn landmarks
+var/list/avatarspawn = list()
//away missions
var/list/awaydestinations = list() //a list of landmarks that the warpgate can take you to
@@ -51,4 +52,5 @@ var/list/datum/map_template/ruins_templates = list()
var/list/datum/map_template/space_ruins_templates = list()
var/list/datum/map_template/lava_ruins_templates = list()
var/list/datum/map_template/shelter_templates = list()
-var/list/datum/map_template/shuttle_templates = list()
\ No newline at end of file
+var/list/datum/map_template/shuttle_templates = list()
+var/list/datum/map_template/vr_templates = list()
\ No newline at end of file
diff --git a/code/_globalvars/station.dm b/code/_globalvars/station.dm
index 523965b66a1..6d2578e5b88 100644
--- a/code/_globalvars/station.dm
+++ b/code/_globalvars/station.dm
@@ -1,7 +1,7 @@
-var/global/obj/effect/datacore/data_core = null
+var/global/datum/datacore/data_core = null
var/CELLRATE = 0.002 // multiplier for watts per tick <> cell storage (eg: .002 means if there is a load of 1000 watts, 20 units will be taken from a cell per second)
-var/CHARGELEVEL = 0.0005 // Cap for how fast cells charge, as a percentage-per-tick (.001 means cellcharge is capped to 1% per second)
+var/CHARGELEVEL = 0.001 // Cap for how fast cells charge, as a percentage-per-tick (.001 means cellcharge is capped to 1% per second)
var/list/powernets = list()
var/list/deferred_powernet_rebuilds = list()
diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index a20efc98a06..0090dd654fd 100644
--- a/code/_onclick/hud/alert.dm
+++ b/code/_onclick/hud/alert.dm
@@ -3,15 +3,18 @@
//PUBLIC - call these wherever you want
-/mob/proc/throw_alert(category, type, severity, obj/new_master)
+/mob/proc/throw_alert(category, type, severity, obj/new_master, override = FALSE)
-/* Proc to create or update an alert. Returns the alert if the alert is new or updated, 0 if it was thrown already
+/*
+ Proc to create or update an alert. Returns the alert if the alert is new or updated, 0 if it was thrown already
category is a text string. Each mob may only have one alert per category; the previous one will be replaced
path is a type path of the actual alert type to throw
severity is an optional number that will be placed at the end of the icon_state for this alert
For example, high pressure's icon_state is "highpressure" and can be serverity 1 or 2 to get "highpressure1" or "highpressure2"
new_master is optional and sets the alert's icon state to "template" in the ui_style icons with the master as an overlay.
- Clicks are forwarded to master */
+ Clicks are forwarded to master
+ Override makes it so the alert is not replaced until cleared by a clear_alert with clear_override, and it's used for hallucinations.
+ */
if(!category)
return
@@ -19,6 +22,8 @@
var/obj/screen/alert/alert
if(alerts[category])
alert = alerts[category]
+ if(alert.override_alerts)
+ return 0
if(new_master && new_master != alert.master)
WARNING("[src] threw alert [category] with new_master [new_master] while already having that alert with master [alert.master]")
clear_alert(category)
@@ -33,7 +38,10 @@
else //no need to update
return 0
else
- alert = new type
+ alert = new type()
+ alert.override_alerts = override
+ if(override)
+ alert.timeout = null
if(new_master)
var/old_layer = new_master.layer
@@ -63,10 +71,12 @@
return alert
// Proc to clear an existing alert.
-/mob/proc/clear_alert(category)
+/mob/proc/clear_alert(category, clear_override = FALSE)
var/obj/screen/alert/alert = alerts[category]
if(!alert)
return 0
+ if(alert.override_alerts && !clear_override)
+ return 0
alerts -= category
if(client && hud_used)
@@ -83,6 +93,7 @@
var/timeout = 0 //If set to a number, this alert will clear itself after that many deciseconds
var/severity = 0
var/alerttooltipstyle = ""
+ var/override_alerts = FALSE //If it is overriding other alerts of the same type
/obj/screen/alert/MouseEntered(location,control,params)
@@ -197,12 +208,12 @@ The box in your backpack has an oxygen tank and gas mask in it."
name = "High Pressure"
desc = "The air around you is hazardously thick. A fire suit would protect you."
icon_state = "highpressure"
-
+
/obj/screen/alert/lightexposure
name = "Light Exposure"
desc = "You're exposed to light."
icon_state = "lightexposure"
-
+
/obj/screen/alert/nolight
name = "No Light"
desc = "You're not exposed to any light."
diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm
index 29e7c676ac4..08fe2347cb4 100644
--- a/code/_onclick/hud/hud.dm
+++ b/code/_onclick/hud/hud.dm
@@ -54,8 +54,7 @@
qdel(hide_actions_toggle)
hide_actions_toggle = null
- qdel(module_store_icon)
- module_store_icon = null
+ QDEL_NULL(module_store_icon)
if(static_inventory.len)
for(var/thing in static_inventory)
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index 4c9f57d4e4e..59cbf9c6219 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -84,7 +84,7 @@
if(istype(M, /mob/living/carbon/slime))
var/mob/living/carbon/slime/slime = M
if(prob(25))
- to_chat(user, "\red [src] passes right through [M]!")
+ to_chat(user, "[src] passes right through [M]!")
return
if(power > 0)
diff --git a/code/controllers/Processes/lighting.dm b/code/controllers/Processes/lighting.dm
index d92fe8a36b1..d46cab1d19f 100644
--- a/code/controllers/Processes/lighting.dm
+++ b/code/controllers/Processes/lighting.dm
@@ -1,9 +1,3 @@
-// Solves problems with lighting updates lagging shit
-// Max constraints on number of updates per doWork():
-#define MAX_LIGHT_UPDATES_PER_WORK 100
-#define MAX_CORNER_UPDATES_PER_WORK 1000
-#define MAX_OVERLAY_UPDATES_PER_WORK 2000
-
/var/lighting_overlays_initialised = FALSE
/var/list/lighting_update_lights = list() // List of lighting sources queued for update.
@@ -16,10 +10,22 @@
/datum/controller/process/lighting
+ // Queues of update counts, waiting to be rolled into stats lists
+ var/list/stats_queues = list(
+ "Source" = list(), "Corner" = list(), "Overlay" = list())
+ // Stats lists
+ var/list/stats_lists = list(
+ "Source" = list(), "Corner" = list(), "Overlay" = list())
+ var/update_stats_every = (1 SECONDS)
+ var/next_stats_update = 0
+ var/stat_updates_to_keep = 5
+
/datum/controller/process/lighting/setup()
name = "lighting"
- schedule_interval = world.tick_lag // run as fast as you possibly can
+ schedule_interval = 0 // run as fast as you possibly can
+ sleep_interval = 10 // Yield every 10% of a tick
+ defer_usage = 80 // Defer at 80% of a tick
create_all_lighting_overlays()
lighting_overlays_initialised = TRUE
@@ -28,17 +34,10 @@
doWork(1)
/datum/controller/process/lighting/doWork(roundstart)
- // Counters
- var/light_updates = 0
- var/corner_updates = 0
- var/overlay_updates = 0
lighting_update_lights_old = lighting_update_lights //We use a different list so any additions to the update lists during a delay from scheck() don't cause things to be cut from the list without being updated.
lighting_update_lights = list()
for(var/datum/light_source/L in lighting_update_lights_old)
- if(light_updates >= MAX_LIGHT_UPDATES_PER_WORK && !roundstart)
- lighting_update_lights += L
- continue // DON'T break, we're adding stuff back into the update queue.
if(L.check() || L.destroyed || L.force_update)
L.remove_lum()
@@ -52,52 +51,48 @@
L.force_update = FALSE
L.needs_update = FALSE
- light_updates++
-
SCHECK
lighting_update_corners_old = lighting_update_corners //Same as above.
lighting_update_corners = list()
for(var/A in lighting_update_corners_old)
- if(corner_updates >= MAX_CORNER_UPDATES_PER_WORK && !roundstart)
- lighting_update_corners += A
- continue // DON'T break, we're adding stuff back into the update queue.
-
var/datum/lighting_corner/C = A
C.update_overlays()
C.needs_update = FALSE
- corner_updates++
-
SCHECK
lighting_update_overlays_old = lighting_update_overlays //Same as above.
lighting_update_overlays = list()
- for(var/atom/movable/lighting_overlay/O in lighting_update_overlays_old)
- if(overlay_updates >= MAX_OVERLAY_UPDATES_PER_WORK && !roundstart)
- lighting_update_overlays += O
- continue // DON'T break, we're adding stuff back into the update queue.
-
+ for(var/A in lighting_update_overlays_old)
+ var/atom/movable/lighting_overlay/O = A
O.update_overlay()
O.needs_update = 0
- overlay_updates++
SCHECK
+ stats_queues["Source"] += lighting_update_lights_old.len
+ stats_queues["Corner"] += lighting_update_corners_old.len
+ stats_queues["Overlay"] += lighting_update_overlays_old.len
+ if(next_stats_update <= world.time)
+ next_stats_update = world.time + update_stats_every
+ for(var/stat_name in stats_queues)
+ var/stat_sum = 0
+ var/list/stats_queue = stats_queues[stat_name]
+ for(var/count in stats_queue)
+ stat_sum += count
+ stats_queue.Cut()
+ var/list/stats_list = stats_lists[stat_name]
+ stats_list.Insert(1, stat_sum)
+ if(stats_list.len > stat_updates_to_keep)
+ stats_list.Cut(stats_list.len)
/datum/controller/process/lighting/statProcess()
..()
- stat(null, "[all_lighting_sources.len] light sources exist")
- stat(null, "[all_lighting_corners.len] light corners exist")
- stat(null, "[global.all_lighting_overlays.len] light overlays exist")
- stat(null, "[lighting_update_lights.len] lighting sources queued")
- stat(null, "[lighting_update_corners.len] lighting corners queued")
- stat(null, "[lighting_update_overlays.len] lighting overlays queued")
-
-#undef MAX_LIGHT_UPDATES_PER_WORK
-#undef MAX_CORNER_UPDATES_PER_WORK
-#undef MAX_OVERLAY_UPDATES_PER_WORK
+ stat(null, "[total_lighting_sources] sources, [total_lighting_corners] corners, [total_lighting_overlays] overlays")
+ for(var/stat_type in stats_lists)
+ stat(null, "[stat_type] updates: [jointext(stats_lists[stat_type], " | ")]")
diff --git a/code/controllers/Processes/shuttles.dm b/code/controllers/Processes/shuttles.dm
index 9c01974a1a9..c027a63b902 100644
--- a/code/controllers/Processes/shuttles.dm
+++ b/code/controllers/Processes/shuttles.dm
@@ -160,6 +160,8 @@ var/const/CALL_SHUTTLE_REASON_LENGTH = 12
/datum/controller/process/shuttle/proc/canRecall()
if(emergency.mode != SHUTTLE_CALL)
return
+ if(!emergency.canRecall)
+ return
if(ticker.mode.name == "meteor")
return
if(seclevel2num(get_security_level()) >= SEC_LEVEL_RED)
@@ -182,6 +184,8 @@ var/const/CALL_SHUTTLE_REASON_LENGTH = 12
var/obj/machinery/computer/communications/C = thing
if(C.stat & BROKEN)
continue
+ else if(istype(thing, /datum/computer_file/program/comm) || istype(thing, /obj/item/weapon/circuitboard/communications))
+ continue
var/turf/T = get_turf(thing)
if(T && is_station_level(T.z))
diff --git a/code/controllers/communications.dm b/code/controllers/communications.dm
index e65cc040917..9b056472bde 100644
--- a/code/controllers/communications.dm
+++ b/code/controllers/communications.dm
@@ -347,3 +347,21 @@ var/global/datum/controller/radio/radio_controller
var/list/L = data[i]
for(var/t in L)
. += "data\[\"[i]\"\] list has: [t]"
+
+/datum/signal/proc/get_race(mob/M)
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ . = H.species.name
+ else if(isbrain(M))
+ var/mob/living/carbon/brain/B = M
+ . = B.get_race()
+ else if(issilicon(M))
+ . = "Artificial Life"
+ else if(isslime(M))
+ . = "Slime"
+ else if(isbot(M))
+ . = "Bot"
+ else if(isanimal(M))
+ . = "Domestic Animal"
+ else
+ . = "Unidentifiable"
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index 251494d9f89..c593296c30f 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -189,6 +189,8 @@
var/disable_ooc_emoji = 0 // prevents people from using emoji in OOC
+ var/shutdown_on_reboot = 0 // Whether to shut down the world instead of rebooting it
+
/datum/configuration/New()
var/list/L = subtypesof(/datum/game_mode)
for(var/T in L)
@@ -585,6 +587,12 @@
if("disable_ooc_emoji")
config.disable_ooc_emoji = 1
+ if("shutdown_on_reboot")
+ config.shutdown_on_reboot = 1
+
+ if("shutdown_shell_command")
+ shutdown_shell_command = value
+
else
diary << "Unknown setting in configuration: '[name]'"
diff --git a/code/datums/action.dm b/code/datums/action.dm
index f1826c334c5..0bec4e37d35 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -29,8 +29,7 @@
Remove(owner)
if(target)
target = null
- qdel(button)
- button = null
+ QDEL_NULL(button)
return ..()
/datum/action/proc/Grant(mob/M)
@@ -187,7 +186,7 @@
/datum/action/item_action/toggle_hardsuit_mode
name = "Toggle Hardsuit Mode"
-
+
/datum/action/item_action/toggle_unfriendly_fire
name = "Toggle Friendly Fire \[ON\]"
desc = "Toggles if the staff causes friendly fire."
@@ -357,7 +356,7 @@
..()
name = "Toggle [target.name]"
button.name = name
-
+
/datum/action/item_action/organ_action/use/New(Target)
..()
name = "Use [target.name]"
diff --git a/code/datums/cache/apc.dm b/code/datums/cache/apc.dm
index 4271886ac4b..29a2574f6e0 100644
--- a/code/datums/cache/apc.dm
+++ b/code/datums/cache/apc.dm
@@ -1,8 +1,8 @@
var/global/datum/repository/apc/apc_repository = new()
-/datum/repository/apc/proc/apc_data(var/obj/machinery/computer/monitor/powermonitor)
+/datum/repository/apc/proc/apc_data(datum/powernet/powernet)
var/apcData[0]
-
+
var/datum/cache_entry/cache_entry = cache_data
if(!cache_entry)
cache_entry = new/datum/cache_entry
@@ -10,10 +10,10 @@ var/global/datum/repository/apc/apc_repository = new()
if(world.time < cache_entry.timestamp)
return cache_entry.data
-
- if(powermonitor && !isnull(powermonitor.powernet))
+
+ if(powernet)
var/list/L = list()
- for(var/obj/machinery/power/terminal/term in powermonitor.powernet.nodes)
+ for(var/obj/machinery/power/terminal/term in powernet.nodes)
if(istype(term.master, /obj/machinery/power/apc))
var/obj/machinery/power/apc/A = term.master
L += A
@@ -24,5 +24,5 @@ var/global/datum/repository/apc/apc_repository = new()
apcData[++apcData.len] = list("Name" = html_encode(A.area.name), "Equipment" = Status[A.equipment+1], "Lights" = Status[A.lighting+1], "Environment" = Status[A.environ+1], "CellPct" = A.cell ? round(A.cell.percent(),1) : "M", "CellStatus" = A.cell ? chg[A.charging+1] : "M", "Load" = round(A.lastused_total,1))
cache_entry.timestamp = world.time + 5 SECONDS
- cache_entry.data = apcData
+ cache_entry.data = apcData
return apcData
\ No newline at end of file
diff --git a/code/datums/cargoprofile.dm b/code/datums/cargoprofile.dm
index becb3ccee56..97edbc2ea7b 100644
--- a/code/datums/cargoprofile.dm
+++ b/code/datums/cargoprofile.dm
@@ -147,7 +147,7 @@
name = "Exotic materials"
id = "exotics"
blacklist = null
- whitelist = list(/obj/item/weapon/coin, /obj/item/weapon/spacecash, /obj/item/seeds,
+ whitelist = list(/obj/item/weapon/coin, /obj/item/stack/spacecash, /obj/item/seeds,
/obj/item/stack/sheet/mineral,/obj/item/stack/sheet/wood,/obj/item/stack/sheet/leather)
/datum/cargoprofile/organics
@@ -341,13 +341,13 @@
C:broken = 1
C.open()
C.update_icon()
- master.visible_message("\red [master] breaks open [C]!")
+ master.visible_message("[master] breaks open [C]!")
else
- master.visible_message("\blue [master] is trying to force [C] open!")
+ master.visible_message("[master] is trying to force [C] open!")
master.sleep += 1 // mechanical strain
return BIG_OBJECT_WORK
- master.visible_message("\blue [master] is trying to open [C], but can't!")
+ master.visible_message("[master] is trying to open [C], but can't!")
master.sleep = 5
return 0
@@ -647,7 +647,7 @@
M.loc = master
master.types[M.type] = src
M.apply_damage(damage) // todo: ugly
- M.visible_message("\red [M.name] gets pulled into the machine!")
+ M.visible_message("[M.name] gets pulled into the machine!")
return MOB_WORK
outlet_reaction(var/atom/W,var/turf/D)
var/mob/living/M = W
@@ -659,7 +659,7 @@
if(bruteloss < 100) // requires tenderization
M.apply_damage(rand(5,15),BRUTE)
to_chat(M, "The machine is tearing you apart!")
- master.visible_message("\red [master] makes a squishy grinding noise.")
+ master.visible_message("[master] makes a squishy grinding noise.")
return
M.loc = master.loc
M.gib()
@@ -700,7 +700,7 @@
M.forceMove(master)
master.types[M.type] = src
M.apply_damage(damage) // todo: ugly
- M.visible_message("\red [M.name] gets pulled into the machine!")
+ M.visible_message("[M.name] gets pulled into the machine!")
return MOB_WORK
outlet_reaction(var/atom/W,var/turf/D)
@@ -711,7 +711,7 @@
D = get_step(D,master.outdir) // throw attempt
eject_speed = rand(0,4)
- M.visible_message("\blue [M.name] is ejected from the unloader.")
+ M.visible_message("[M.name] is ejected from the unloader.")
M.throw_at(D,eject_speed,eject_speed)
return
@@ -752,7 +752,7 @@
if(!damage)
playsound(master.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
- master.visible_message("\red \The [src] punched at [M], but whiffed!")
+ master.visible_message("\The [src] punched at [M], but whiffed!")
if(maxpunches > 1 && prob(50)) // Follow through on a miss, 50% chance
return punch(M,maxpunches - 1) + 1
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index 6a73d9108dd..364f39c208f 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -1,16 +1,231 @@
/hook/startup/proc/createDatacore()
- data_core = new /obj/effect/datacore()
+ data_core = new /datum/datacore()
return 1
-/obj/effect/datacore/proc/manifest(var/nosleep = 0)
- spawn()
- if(!nosleep)
- sleep(40)
- for(var/mob/living/carbon/human/H in player_list)
- manifest_inject(H)
- return
+/datum/datacore
+ var/list/medical = list()
+ var/list/general = list()
+ var/list/security = list()
+ //This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character().
+ var/list/locked = list()
-/obj/effect/datacore/proc/manifest_modify(var/name, var/assignment)
+/datum/datacore/proc/get_manifest(monochrome, OOC)
+ var/list/heads = new()
+ var/list/sec = new()
+ var/list/eng = new()
+ var/list/med = new()
+ var/list/sci = new()
+ var/list/ser = new()
+ var/list/sup = new()
+ var/list/bot = new()
+ var/list/misc = new()
+ var/list/isactive = new()
+ var/dat = {"
+
+
+
Name
Rank
Activity
+ "}
+ var/even = 0
+ // sort mobs
+ for(var/datum/data/record/t in data_core.general)
+ var/name = t.fields["name"]
+ var/rank = t.fields["rank"]
+ var/real_rank = t.fields["real_rank"]
+ if(OOC)
+ var/active = 0
+ for(var/mob/M in player_list)
+ if(M.real_name == name && M.client && M.client.inactivity <= 10 * 60 * 10)
+ active = 1
+ break
+ isactive[name] = active ? "Active" : "Inactive"
+ else
+ isactive[name] = t.fields["p_stat"]
+ var/department = 0
+ if(real_rank in command_positions)
+ heads[name] = rank
+ department = 1
+ if(real_rank in security_positions)
+ sec[name] = rank
+ department = 1
+ if(real_rank in engineering_positions)
+ eng[name] = rank
+ department = 1
+ if(real_rank in medical_positions)
+ med[name] = rank
+ department = 1
+ if(real_rank in science_positions)
+ sci[name] = rank
+ department = 1
+ if(real_rank in service_positions)
+ ser[name] = rank
+ department = 1
+ if(real_rank in supply_positions)
+ sup[name] = rank
+ department = 1
+ if(real_rank in nonhuman_positions)
+ bot[name] = rank
+ department = 1
+ if(!department && !(name in heads))
+ misc[name] = rank
+ if(heads.len > 0)
+ dat += "
Heads
"
+ for(var/name in heads)
+ dat += "
[name]
[heads[name]]
[isactive[name]]
"
+ even = !even
+ if(sec.len > 0)
+ dat += "
Security
"
+ for(var/name in sec)
+ dat += "
[name]
[sec[name]]
[isactive[name]]
"
+ even = !even
+ if(eng.len > 0)
+ dat += "
Engineering
"
+ for(var/name in eng)
+ dat += "
[name]
[eng[name]]
[isactive[name]]
"
+ even = !even
+ if(med.len > 0)
+ dat += "
Medical
"
+ for(var/name in med)
+ dat += "
[name]
[med[name]]
[isactive[name]]
"
+ even = !even
+ if(sci.len > 0)
+ dat += "
Science
"
+ for(var/name in sci)
+ dat += "
[name]
[sci[name]]
[isactive[name]]
"
+ even = !even
+ if(ser.len > 0)
+ dat += "
Service
"
+ for(var/name in ser)
+ dat += "
[name]
[ser[name]]
[isactive[name]]
"
+ even = !even
+ if(sup.len > 0)
+ dat += "
Supply
"
+ for(var/name in sup)
+ dat += "
[name]
[sup[name]]
[isactive[name]]
"
+ even = !even
+ if(bot.len > 0)
+ dat += "
Silicon
"
+ for(var/name in bot)
+ dat += "
[name]
[bot[name]]
[isactive[name]]
"
+ even = !even
+ if(misc.len > 0)
+ dat += "
Miscellaneous
"
+ for(var/name in misc)
+ dat += "
[name]
[misc[name]]
[isactive[name]]
"
+ even = !even
+
+ dat += "
"
+ dat = replacetext(dat, "\n", "") // so it can be placed on paper correctly
+ dat = replacetext(dat, "\t", "")
+ return dat
+
+
+/*
+We can't just insert in HTML into the nanoUI so we need the raw data to play with.
+Instead of creating this list over and over when someone leaves their PDA open to the page
+we'll only update it when it changes. The PDA_Manifest global list is zeroed out upon any change
+using /datum/datacore/proc/manifest_inject(), or manifest_insert()
+*/
+
+var/global/list/PDA_Manifest = list()
+
+/datum/datacore/proc/get_manifest_json()
+ if(PDA_Manifest.len)
+ return
+ var/heads[0]
+ var/sec[0]
+ var/eng[0]
+ var/med[0]
+ var/sci[0]
+ var/ser[0]
+ var/sup[0]
+ var/bot[0]
+ var/misc[0]
+ for(var/datum/data/record/t in data_core.general)
+ var/name = sanitize(t.fields["name"])
+ var/rank = sanitize(t.fields["rank"])
+ var/real_rank = t.fields["real_rank"]
+
+ var/isactive = t.fields["p_stat"]
+ var/department = 0
+ var/depthead = 0 // Department Heads will be placed at the top of their lists.
+ if(real_rank in command_positions)
+ heads[++heads.len] = list("name" = name, "rank" = rank, "active" = isactive)
+ department = 1
+ depthead = 1
+ if(rank == "Captain" && heads.len != 1)
+ heads.Swap(1, heads.len)
+
+ if(real_rank in security_positions)
+ sec[++sec.len] = list("name" = name, "rank" = rank, "active" = isactive)
+ department = 1
+ if(depthead && sec.len != 1)
+ sec.Swap(1, sec.len)
+
+ if(real_rank in engineering_positions)
+ eng[++eng.len] = list("name" = name, "rank" = rank, "active" = isactive)
+ department = 1
+ if(depthead && eng.len != 1)
+ eng.Swap(1, eng.len)
+
+ if(real_rank in medical_positions)
+ med[++med.len] = list("name" = name, "rank" = rank, "active" = isactive)
+ department = 1
+ if(depthead && med.len != 1)
+ med.Swap(1, med.len)
+
+ if(real_rank in science_positions)
+ sci[++sci.len] = list("name" = name, "rank" = rank, "active" = isactive)
+ department = 1
+ if(depthead && sci.len != 1)
+ sci.Swap(1, sci.len)
+
+ if(real_rank in service_positions)
+ ser[++ser.len] = list("name" = name, "rank" = rank, "active" = isactive)
+ department = 1
+ if(depthead && ser.len != 1)
+ ser.Swap(1, ser.len)
+
+ if(real_rank in supply_positions)
+ sup[++sup.len] = list("name" = name, "rank" = rank, "active" = isactive)
+ department = 1
+ if(depthead && sup.len != 1)
+ sup.Swap(1, sup.len)
+
+ if(real_rank in nonhuman_positions)
+ bot[++bot.len] = list("name" = name, "rank" = rank, "active" = isactive)
+ department = 1
+
+ if(!department && !(name in heads))
+ misc[++misc.len] = list("name" = name, "rank" = rank, "active" = isactive)
+
+
+ PDA_Manifest = list(\
+ "heads" = heads,\
+ "sec" = sec,\
+ "eng" = eng,\
+ "med" = med,\
+ "sci" = sci,\
+ "ser" = ser,\
+ "sup" = sup,\
+ "bot" = bot,\
+ "misc" = misc\
+ )
+ return
+
+
+
+/datum/datacore/proc/manifest()
+ for(var/mob/living/carbon/human/H in player_list)
+ manifest_inject(H)
+
+/datum/datacore/proc/manifest_modify(name, assignment)
if(PDA_Manifest.len)
PDA_Manifest.Cut()
var/datum/data/record/foundrecord
@@ -35,7 +250,8 @@
foundrecord.fields["rank"] = assignment
foundrecord.fields["real_rank"] = real_title
-/obj/effect/datacore/proc/manifest_inject(var/mob/living/carbon/human/H)
+var/record_id_num = 1001
+/datum/datacore/proc/manifest_inject(mob/living/carbon/human/H)
if(PDA_Manifest.len)
PDA_Manifest.Cut()
@@ -50,7 +266,7 @@
else
assignment = "Unassigned"
- var/id = add_zero(num2hex(rand(1, 1.6777215E7)), 6) //this was the best they could come up with? A large random number? *sigh*
+ var/id = num2hex(record_id_num++, 6)
//General Record
@@ -125,8 +341,7 @@
locked += L
return
-
-proc/get_id_photo(var/mob/living/carbon/human/H)
+/proc/get_id_photo(mob/living/carbon/human/H)
var/icon/preview_icon = null
var/obj/item/organ/external/head/head_organ = H.get_organ("head")
var/obj/item/organ/internal/eyes/eyes_organ = H.get_int_organ(/obj/item/organ/internal/eyes)
diff --git a/code/datums/diseases/advance/symptoms/choking.dm b/code/datums/diseases/advance/symptoms/choking.dm
index 172c4b63757..62e31105b92 100644
--- a/code/datums/diseases/advance/symptoms/choking.dm
+++ b/code/datums/diseases/advance/symptoms/choking.dm
@@ -43,11 +43,11 @@ Bonus
return
/datum/symptom/choking/proc/Choke_stage_3_4(mob/living/M, datum/disease/advance/A)
- var/get_damage = sqrt(21+A.totalStageSpeed()*0.5)+sqrt(16+A.totalStealth())
+ var/get_damage = sqrtor0(21+A.totalStageSpeed()*0.5)+sqrtor0(16+A.totalStealth())
M.adjustOxyLoss(get_damage)
return 1
/datum/symptom/choking/proc/Choke(mob/living/M, datum/disease/advance/A)
- var/get_damage = sqrt(21+A.totalStageSpeed()*0.5)+sqrt(16+A.totalStealth()*5)
+ var/get_damage = sqrtor0(21+A.totalStageSpeed()*0.5)+sqrtor0(16+A.totalStealth()*5)
M.adjustOxyLoss(get_damage)
return 1
\ No newline at end of file
diff --git a/code/datums/diseases/advance/symptoms/fever.dm b/code/datums/diseases/advance/symptoms/fever.dm
index 917ec9f3bf1..b19d821b75f 100644
--- a/code/datums/diseases/advance/symptoms/fever.dm
+++ b/code/datums/diseases/advance/symptoms/fever.dm
@@ -36,6 +36,6 @@ Bonus
return
/datum/symptom/fever/proc/Heat(mob/living/M, datum/disease/advance/A)
- var/get_heat = (sqrt(21+A.totalTransmittable()*2))+(sqrt(20+A.totalStageSpeed()*3))
+ var/get_heat = (sqrtor0(21+A.totalTransmittable()*2))+(sqrtor0(20+A.totalStageSpeed()*3))
M.bodytemperature = min(M.bodytemperature + (get_heat * A.stage), BODYTEMP_HEAT_DAMAGE_LIMIT - 1)
return 1
\ No newline at end of file
diff --git a/code/datums/diseases/advance/symptoms/fire.dm b/code/datums/diseases/advance/symptoms/fire.dm
index ad828efdd4c..1466bc86459 100644
--- a/code/datums/diseases/advance/symptoms/fire.dm
+++ b/code/datums/diseases/advance/symptoms/fire.dm
@@ -45,13 +45,13 @@ Bonus
return
/datum/symptom/fire/proc/Firestacks_stage_4(mob/living/M, datum/disease/advance/A)
- var/get_stacks = (sqrt(20+A.totalStageSpeed()*2))-(sqrt(16+A.totalStealth()))
+ var/get_stacks = (sqrtor0(20+A.totalStageSpeed()*2))-(sqrtor0(16+A.totalStealth()))
M.adjust_fire_stacks(get_stacks)
M.adjustFireLoss(get_stacks/2)
return 1
/datum/symptom/fire/proc/Firestacks_stage_5(mob/living/M, datum/disease/advance/A)
- var/get_stacks = (sqrt(20+A.totalStageSpeed()*3))-(sqrt(16+A.totalStealth()))
+ var/get_stacks = (sqrtor0(20+A.totalStageSpeed()*3))-(sqrtor0(16+A.totalStealth()))
M.adjust_fire_stacks(get_stacks)
M.adjustFireLoss(get_stacks)
return 1
\ No newline at end of file
diff --git a/code/datums/diseases/advance/symptoms/flesh_eating.dm b/code/datums/diseases/advance/symptoms/flesh_eating.dm
index e99f6f2835b..9cfdf8a9d34 100644
--- a/code/datums/diseases/advance/symptoms/flesh_eating.dm
+++ b/code/datums/diseases/advance/symptoms/flesh_eating.dm
@@ -38,6 +38,6 @@ Bonus
return
/datum/symptom/flesh_eating/proc/Flesheat(mob/living/M, datum/disease/advance/A)
- var/get_damage = ((sqrt(16-A.totalStealth()))*5)
+ var/get_damage = ((sqrtor0(16-A.totalStealth()))*5)
M.adjustBruteLoss(get_damage)
return 1
\ No newline at end of file
diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm
index 11235d9a35b..007bbc92f0b 100644
--- a/code/datums/diseases/advance/symptoms/heal.dm
+++ b/code/datums/diseases/advance/symptoms/heal.dm
@@ -34,7 +34,7 @@ Bonus
return
/datum/symptom/heal/proc/Heal(mob/living/M, datum/disease/advance/A)
- var/get_damage = (sqrt(20+A.totalStageSpeed())*(1+rand()))
+ var/get_damage = (sqrtor0(20+A.totalStageSpeed())*(1+rand()))
M.adjustToxLoss(-get_damage)
return 1
@@ -148,7 +148,7 @@ Bonus
level = 5
/datum/symptom/heal/dna/Heal(mob/living/carbon/M, datum/disease/advance/A)
- var/amt_healed = (sqrt(20+A.totalStageSpeed()*(3+rand())))-(sqrt(16+A.totalStealth()*rand()))
+ var/amt_healed = (sqrtor0(20+A.totalStageSpeed()*(3+rand())))-(sqrtor0(16+A.totalStealth()*rand()))
M.adjustBrainLoss(-amt_healed)
//Non-power mutations, excluding race, so the virus does not force monkey -> human transformations.
var/list/unclean_mutations = (not_good_mutations|bad_mutations) - mutations_list[RACEMUT]
diff --git a/code/datums/diseases/advance/symptoms/shivering.dm b/code/datums/diseases/advance/symptoms/shivering.dm
index a26a19de048..d52a0a02256 100644
--- a/code/datums/diseases/advance/symptoms/shivering.dm
+++ b/code/datums/diseases/advance/symptoms/shivering.dm
@@ -35,6 +35,6 @@ Bonus
return
/datum/symptom/shivering/proc/Chill(mob/living/M, datum/disease/advance/A)
- var/get_cold = (sqrt(16+A.totalStealth()*2))+(sqrt(21+A.totalResistance()*2))
+ var/get_cold = (sqrtor0(16+A.totalStealth()*2))+(sqrtor0(21+A.totalResistance()*2))
M.bodytemperature = min(M.bodytemperature - (get_cold * A.stage), BODYTEMP_COLD_DAMAGE_LIMIT + 1)
return 1
\ No newline at end of file
diff --git a/code/datums/diseases/cold.dm b/code/datums/diseases/cold.dm
index 9e1d350bdc4..975c92b2aef 100644
--- a/code/datums/diseases/cold.dm
+++ b/code/datums/diseases/cold.dm
@@ -16,7 +16,7 @@
if(2)
/*
if(affected_mob.sleeping && prob(40)) //removed until sleeping is fixed
- to_chat(affected_mob, "\blue You feel better.")
+ to_chat(affected_mob, "You feel better.")
cure()
return
*/
@@ -39,7 +39,7 @@
if(3)
/*
if(affected_mob.sleeping && prob(25)) //removed until sleeping is fixed
- to_chat(affected_mob, "\blue You feel better.")
+ to_chat(affected_mob, "You feel better.")
cure()
return
*/
diff --git a/code/datums/helper_datums/construction_datum.dm b/code/datums/helper_datums/construction_datum.dm
index 0a17435c5c0..04054c17632 100644
--- a/code/datums/helper_datums/construction_datum.dm
+++ b/code/datums/helper_datums/construction_datum.dm
@@ -46,17 +46,20 @@
if(istype(used_atom, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/W = used_atom
if(W.remove_fuel(0, user))
- playsound(holder, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(holder, W.usesound, 50, 1)
else
return 0
else if(istype(used_atom, /obj/item/weapon/wrench))
- playsound(holder, 'sound/items/Ratchet.ogg', 50, 1)
+ var/obj/item/weapon/wrench/W = used_atom
+ playsound(holder, W.usesound, 50, 1)
else if(istype(used_atom, /obj/item/weapon/screwdriver))
- playsound(holder, 'sound/items/Screwdriver.ogg', 50, 1)
+ var/obj/item/weapon/screwdriver/S = used_atom
+ playsound(holder, S.usesound, 50, 1)
else if(istype(used_atom, /obj/item/weapon/wirecutters))
- playsound(holder, 'sound/items/Wirecutter.ogg', 50, 1)
+ var/obj/item/weapon/wirecutters/W = used_atom
+ playsound(holder, W.usesound, 50, 1)
else if(istype(used_atom, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = used_atom
@@ -65,7 +68,7 @@
return 0
else
C.use(4)
- playsound(holder, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(holder, C.usesound, 50, 1)
else if(istype(used_atom, /obj/item/stack))
var/obj/item/stack/S = used_atom
if(S.amount < 5)
diff --git a/code/datums/helper_datums/global_iterator.dm b/code/datums/helper_datums/global_iterator.dm
index 485dfa3563e..e3f22e2a3e2 100644
--- a/code/datums/helper_datums/global_iterator.dm
+++ b/code/datums/helper_datums/global_iterator.dm
@@ -139,7 +139,7 @@ Data storage vars:
arg_list = arguments
return 1
else
-// to_chat(world, "\red Invalid arguments supplied for [src.type], ref = \ref[src]")
+// to_chat(world, "Invalid arguments supplied for [src.type], ref = \ref[src]")
return 0
proc/toggle_null_checks()
diff --git a/code/datums/helper_datums/map_template.dm b/code/datums/helper_datums/map_template.dm
index ead199814f3..1ecf89de0fe 100644
--- a/code/datums/helper_datums/map_template.dm
+++ b/code/datums/helper_datums/map_template.dm
@@ -114,6 +114,7 @@
preloadRuinTemplates()
preloadShelterTemplates()
preloadShuttleTemplates()
+ preloadVRTemplates()
/proc/preloadRuinTemplates()
// Still supporting bans by filename
@@ -163,4 +164,15 @@
var/datum/map_template/shuttle/S = new shuttle_type()
shuttle_templates[S.shuttle_id] = S
- map_templates[S.shuttle_id] = S
\ No newline at end of file
+ map_templates[S.shuttle_id] = S
+
+/proc/preloadVRTemplates()
+ for(var/item in subtypesof(/datum/map_template/vr))
+ var/datum/map_template/vr/vr_type = item
+ if(!initial(vr_type.suffix))
+ continue
+
+ var/datum/map_template/vr/V = new vr_type()
+
+ vr_templates[V.id] = V
+ map_templates[V.id] = V
\ No newline at end of file
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 27947b9e608..886661d4fdb 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -157,7 +157,7 @@
var/mob/living/carbon/human/H = current
if(ishuman(current))
/** Impanted**/
- if(isloyal(H))
+ if(ismindshielded(H))
text = "Mindshield Implant:Remove|Implanted"
else
text = "Mindshield Implant:No Implant|Implant him!"
@@ -167,7 +167,7 @@
if(ticker.mode.config_tag=="revolution")
text += uppertext(text)
text = "[text]: "
- if(isloyal(H))
+ if(ismindshielded(H))
text += "NO|headrev|rev"
else if(src in ticker.mode.head_revolutionaries)
text += "no|HEADREV|rev"
@@ -203,7 +203,7 @@
if(ticker.mode.config_tag=="cult")
text = uppertext(text)
text = "[text]: "
- if(isloyal(H))
+ if(ismindshielded(H))
text += "NO|cultist"
else if(src in ticker.mode.cult)
text += "no|CULTIST"
@@ -593,7 +593,7 @@
new_objective.explanation_text = "Absorb [target_number] compatible genomes."
if("blood")
new_objective = new /datum/objective/blood
- new_objective.explanation_text = "Accumulate atleast [target_number] units of blood in total."
+ new_objective.explanation_text = "Accumulate at least [target_number] total units of blood."
new_objective.owner = src
new_objective.target_amount = target_number
@@ -657,15 +657,15 @@
switch(href_list["implant"])
if("remove")
- for(var/obj/item/weapon/implant/loyalty/I in H.contents)
+ for(var/obj/item/weapon/implant/mindshield/I in H.contents)
if(I && I.implanted)
I.removed(H)
qdel(I)
- to_chat(H, "\blue Your mindshield implant has been deactivated.")
+ to_chat(H, "Your mindshield implant has been deactivated.")
log_admin("[key_name(usr)] has deactivated [key_name(current)]'s mindshield implant")
message_admins("[key_name_admin(usr)] has deactivated [key_name_admin(current)]'s mindshield implant")
if("add")
- var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
+ var/obj/item/weapon/implant/mindshield/L = new/obj/item/weapon/implant/mindshield(H)
L.imp_in = H
L.implanted = 1
H.sec_hud_set_implants()
@@ -673,15 +673,15 @@
log_admin("[key_name(usr)] has given [key_name(current)] a mindshield implant")
message_admins("[key_name_admin(usr)] has given [key_name_admin(current)] a mindshield implant")
- to_chat(H, "\red You somehow have become the recepient of a mindshield transplant, and it just activated!")
+ to_chat(H, "You somehow have become the recepient of a mindshield transplant, and it just activated!")
if(src in ticker.mode.revolutionaries)
special_role = null
ticker.mode.revolutionaries -= src
- to_chat(src, "\red The nanobots in the mindshield implant remove all thoughts about being a revolutionary. Get back to work!")
+ to_chat(src, "The nanobots in the mindshield implant remove all thoughts about being a revolutionary. Get back to work!")
if(src in ticker.mode.head_revolutionaries)
special_role = null
ticker.mode.head_revolutionaries -=src
- to_chat(src, "\red The nanobots in the mindshield implant remove all thoughts about being a revolutionary. Get back to work!")
+ to_chat(src, "The nanobots in the mindshield implant remove all thoughts about being a revolutionary. Get back to work!")
if(src in ticker.mode.cult)
ticker.mode.cult -= src
ticker.mode.update_cult_icons_removed(src)
@@ -689,7 +689,7 @@
var/datum/game_mode/cult/cult = ticker.mode
if(istype(cult))
cult.memorize_cult_objectives(src)
- to_chat(current, "\red The nanobots in the mindshield implant remove all thoughts about being in a cult. Have a productive day!")
+ to_chat(current, "The nanobots in the mindshield implant remove all thoughts about being in a cult. Have a productive day!")
memory = ""
else if(href_list["revolution"])
@@ -698,12 +698,12 @@
if("clear")
if(src in ticker.mode.revolutionaries)
ticker.mode.revolutionaries -= src
- to_chat(current, "\red You have been brainwashed! You are no longer a revolutionary!")
+ to_chat(current, "You have been brainwashed! You are no longer a revolutionary!")
ticker.mode.update_rev_icons_removed(src)
special_role = null
if(src in ticker.mode.head_revolutionaries)
ticker.mode.head_revolutionaries -= src
- to_chat(current, "\red You have been brainwashed! You are no longer a head revolutionary!")
+ to_chat(current, "You have been brainwashed! You are no longer a head revolutionary!")
ticker.mode.update_rev_icons_removed(src)
special_role = null
log_admin("[key_name(usr)] has de-rev'd [key_name(current)]")
@@ -713,9 +713,9 @@
if(src in ticker.mode.head_revolutionaries)
ticker.mode.head_revolutionaries -= src
ticker.mode.update_rev_icons_removed(src)
- to_chat(current, "\red Revolution has been disappointed of your leader traits! You are a regular revolutionary now!")
+ to_chat(current, "Revolution has been disappointed of your leadership traits! You are a regular revolutionary now!")
else if(!(src in ticker.mode.revolutionaries))
- to_chat(current, "\red You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!")
+ to_chat(current, " You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!")
else
return
ticker.mode.revolutionaries += src
@@ -728,9 +728,9 @@
if(src in ticker.mode.revolutionaries)
ticker.mode.revolutionaries -= src
ticker.mode.update_rev_icons_removed(src)
- to_chat(current, "\red You have proved your devotion to revoltion! Yea are a head revolutionary now!")
+ to_chat(current, "\red You have proven your devotion to revolution! You are a head revolutionary now!")
else if(!(src in ticker.mode.head_revolutionaries))
- to_chat(current, "\blue You are a member of the revolutionaries' leadership now!")
+ to_chat(current, "You are a member of the revolutionaries' leadership now!")
else
return
if(ticker.mode.head_revolutionaries.len>0)
@@ -758,7 +758,7 @@
if("flash")
if(!ticker.mode.equip_revolutionary(current))
- to_chat(usr, "\red Spawning flash failed!")
+ to_chat(usr, "Spawning flash failed!")
log_admin("[key_name(usr)] has given [key_name(current)] a flash")
message_admins("[key_name_admin(usr)] has given [key_name_admin(current)] a flash")
@@ -766,7 +766,7 @@
var/list/L = current.get_contents()
var/obj/item/device/flash/flash = locate() in L
if(!flash)
- to_chat(usr, "\red Deleting flash failed!")
+ to_chat(usr, "Deleting flash failed!")
qdel(flash)
log_admin("[key_name(usr)] has taken [key_name(current)]'s flash")
message_admins("[key_name_admin(usr)] has taken [key_name_admin(current)]'s flash")
@@ -775,7 +775,7 @@
var/list/L = current.get_contents()
var/obj/item/device/flash/flash = locate() in L
if(!flash)
- to_chat(usr, "\red Repairing flash failed!")
+ to_chat(usr, "Repairing flash failed!")
else
flash.broken = 0
log_admin("[key_name(usr)] has repaired [key_name(current)]'s flash")
@@ -790,7 +790,7 @@
fail |= !ticker.mode.equip_traitor(current, 1)
fail |= !ticker.mode.equip_revolutionary(current)
if(fail)
- to_chat(usr, "\red Reequipping revolutionary goes wrong!")
+ to_chat(usr, "Reequipping revolutionary goes wrong!")
return
log_admin("[key_name(usr)] has equipped [key_name(current)] as a revolutionary")
message_admins("[key_name_admin(usr)] has equipped [key_name_admin(current)] as a revolutionary")
@@ -825,7 +825,7 @@
)
var/where = H.equip_in_one_of_slots(T, slots)
if(!where)
- to_chat(usr, "\red Spawning tome failed!")
+ to_chat(usr, "Spawning tome failed!")
qdel(T)
else
to_chat(H, "A tome, a message from your new master, appears in your [where].")
@@ -834,7 +834,7 @@
if("equip")
if(!ticker.mode.equip_cultist(current))
- to_chat(usr, "\red Spawning equipment failed!")
+ to_chat(usr, "Spawning equipment failed!")
log_admin("[key_name(usr)] has equipped [key_name(current)] as a cultist")
message_admins("[key_name_admin(usr)] has equipped [key_name_admin(current)] as a cultist")
@@ -848,7 +848,7 @@
current.spellremove(current)
current.faction = list("Station")
ticker.mode.update_wiz_icons_removed(src)
- to_chat(current, "\red You have been brainwashed! You are no longer a wizard!")
+ to_chat(current, "You have been brainwashed! You are no longer a wizard!")
log_admin("[key_name(usr)] has de-wizarded [key_name(current)]")
message_admins("[key_name_admin(usr)] has de-wizarded [key_name_admin(current)]")
if("wizard")
@@ -857,7 +857,7 @@
special_role = SPECIAL_ROLE_WIZARD
//ticker.mode.learn_basic_spells(current)
ticker.mode.update_wiz_icons_added(src)
- to_chat(current, "You are the Space Wizard!")
+ to_chat(current, "You are a Space Wizard!")
current.faction = list("wizard")
log_admin("[key_name(usr)] has wizarded [key_name(current)]")
message_admins("[key_name_admin(usr)] has wizarded [key_name_admin(current)]")
@@ -875,7 +875,7 @@
message_admins("[key_name_admin(usr)] has allowed wizard [key_name_admin(current)] to name themselves")
if("autoobjectives")
ticker.mode.forge_wizard_objectives(src)
- to_chat(usr, "\blue The objectives for wizard [key] have been generated. You can edit them and anounce manually.")
+ to_chat(usr, "The objectives for wizard [key] have been generated. You can edit them and announce manually.")
log_admin("[key_name(usr)] has automatically forged wizard objectives for [key_name(current)]")
message_admins("[key_name_admin(usr)] has automatically forged wizard objectives for [key_name_admin(current)]")
@@ -898,19 +898,19 @@
ticker.mode.grant_changeling_powers(current)
ticker.mode.update_change_icons_added(src)
special_role = SPECIAL_ROLE_CHANGELING
- to_chat(current, "Your powers are awoken. A flash of memory returns to us...we are a changeling!")
+ to_chat(current, "Your powers have awoken. A flash of memory returns to us... we are a changeling!")
log_admin("[key_name(usr)] has changelinged [key_name(current)]")
message_admins("[key_name_admin(usr)] has changelinged [key_name_admin(current)]")
if("autoobjectives")
ticker.mode.forge_changeling_objectives(src)
- to_chat(usr, "\blue The objectives for changeling [key] have been generated. You can edit them and anounce manually.")
+ to_chat(usr, "The objectives for changeling [key] have been generated. You can edit them and announce manually.")
log_admin("[key_name(usr)] has automatically forged objectives for [key_name(current)]")
message_admins("[key_name_admin(usr)] has automatically forged objectives for [key_name_admin(current)]")
if("initialdna")
if(!changeling || !changeling.absorbed_dna.len)
- to_chat(usr, "\red Resetting DNA failed!")
+ to_chat(usr, "Resetting DNA failed!")
else
current.dna = changeling.absorbed_dna[1]
current.real_name = current.dna.real_name
@@ -942,13 +942,13 @@
slaved.masters += src
som = slaved //we MIGT want to mindslave someone
special_role = SPECIAL_ROLE_VAMPIRE
- to_chat(current, "Your powers are awoken. Your lust for blood grows... You are a Vampire!")
+ to_chat(current, "Your powers have awoken. Your lust for blood grows... You are a Vampire!")
log_admin("[key_name(usr)] has vampired [key_name(current)]")
message_admins("[key_name_admin(usr)] has vampired [key_name_admin(current)]")
if("autoobjectives")
ticker.mode.forge_vampire_objectives(src)
- to_chat(usr, "\blue The objectives for vampire [key] have been generated. You can edit them and announce manually.")
+ to_chat(usr, "The objectives for vampire [key] have been generated. You can edit them and announce manually.")
log_admin("[key_name(usr)] has automatically forged objectives for [key_name(current)]")
message_admins("[key_name_admin(usr)] has automatically forged objectives for [key_name_admin(current)]")
@@ -971,7 +971,7 @@
special_role = null
for(var/datum/objective/nuclear/O in objectives)
objectives-=O
- to_chat(current, "\red You have been brainwashed! You are no longer a syndicate operative!")
+ to_chat(current, "You have been brainwashed! You are no longer a syndicate operative!")
log_admin("[key_name(usr)] has de-nuke op'd [key_name(current)]")
message_admins("[key_name_admin(usr)] has de-nuke op'd [key_name_admin(current)]")
if("nuclear")
@@ -983,7 +983,7 @@
else
current.real_name = "[syndicate_name()] Operative #[ticker.mode.syndicates.len-1]"
special_role = SPECIAL_ROLE_NUKEOPS
- to_chat(current, "\blue You are a [syndicate_name()] agent!")
+ to_chat(current, "You are a [syndicate_name()] agent!")
ticker.mode.forge_syndicate_objectives(src)
ticker.mode.greet_syndicate(src)
log_admin("[key_name(usr)] has nuke op'd [key_name(current)]")
@@ -1006,7 +1006,7 @@
qdel(H.w_uniform)
if(!ticker.mode.equip_syndicate(current))
- to_chat(usr, "\red Equipping a syndicate failed!")
+ to_chat(usr, "Equipping a syndicate failed!")
return
log_admin("[key_name(usr)] has equipped [key_name(current)] as a nuclear operative")
message_admins("[key_name_admin(usr)] has equipped [key_name_admin(current)] as a nuclear operative")
@@ -1023,7 +1023,7 @@
log_admin("[key_name(usr)] has given [key_name(current)] the nuclear authorization code")
message_admins("[key_name_admin(usr)] has given [key_name_admin(current)] the nuclear authorization code")
else
- to_chat(usr, "\red No valid nuke found!")
+ to_chat(usr, "No valid nuke found!")
else if(href_list["traitor"])
switch(href_list["traitor"])
@@ -1031,7 +1031,7 @@
if(src in ticker.mode.traitors)
ticker.mode.traitors -= src
special_role = null
- to_chat(current, "\red You have been brainwashed! You are no longer a traitor!")
+ to_chat(current, "You have been brainwashed! You are no longer a traitor!")
log_admin("[key_name(usr)] has de-traitored [key_name(current)]")
message_admins("[key_name_admin(usr)] has de-traitored [key_name_admin(current)]")
if(isAI(current))
@@ -1061,7 +1061,7 @@
if("autoobjectives")
ticker.mode.forge_traitor_objectives(src)
- to_chat(usr, "\blue The objectives for traitor [key] have been generated. You can edit them and anounce manually.")
+ to_chat(usr, "The objectives for traitor [key] have been generated. You can edit them and announce manually.")
log_admin("[key_name(usr)] has automatically forged objectives for [key_name(current)]")
message_admins("[key_name_admin(usr)] has automatically forged objectives for [key_name_admin(current)]")
@@ -1197,17 +1197,18 @@
message_admins("[key_name_admin(usr)] has set [key_name_admin(current)]'s telecrystals to [crystals]")
if("uplink")
if(!ticker.mode.equip_traitor(current, !(src in ticker.mode.traitors)))
- to_chat(usr, "\red Equipping a syndicate failed!")
+ to_chat(usr, "Equipping a syndicate failed!")
return
log_admin("[key_name(usr)] has given [key_name(current)] an uplink")
message_admins("[key_name_admin(usr)] has given [key_name_admin(current)] an uplink")
else if(href_list["obj_announce"])
var/obj_count = 1
- to_chat(current, "\blue Your current objectives:")
+ to_chat(current, " Your current objectives:")
for(var/datum/objective/objective in objectives)
to_chat(current, "Objective #[obj_count]: [objective.explanation_text]")
obj_count++
+ current << 'sound/ambience/alarm4.ogg'
log_admin("[key_name(usr)] has announced [key_name(current)]'s objectives")
message_admins("[key_name_admin(usr)] has announced [key_name_admin(current)]'s objectives")
@@ -1275,7 +1276,7 @@
current.real_name = "[syndicate_name()] Operative #[ticker.mode.syndicates.len-1]"
special_role = SPECIAL_ROLE_NUKEOPS
assigned_role = "MODE"
- to_chat(current, "\blue You are a [syndicate_name()] agent!")
+ to_chat(current, "You are a [syndicate_name()] agent!")
ticker.mode.forge_syndicate_objectives(src)
ticker.mode.greet_syndicate(src)
@@ -1359,7 +1360,7 @@
to_chat(H, "A tome, a message from your new master, appears in your [where].")
if(!ticker.mode.equip_cultist(current))
- to_chat(H, "Spawning an amulet from your Master failed.")
+ to_chat(H, "Summoning an amulet from your Master failed.")
/datum/mind/proc/make_Rev()
if(ticker.mode.head_revolutionaries.len>0)
diff --git a/code/datums/outfits/outfit.dm b/code/datums/outfits/outfit.dm
new file mode 100644
index 00000000000..9517ee09ef8
--- /dev/null
+++ b/code/datums/outfits/outfit.dm
@@ -0,0 +1,143 @@
+/datum/outfit
+ var/name = "Naked"
+ var/collect_not_del = FALSE
+
+ var/uniform = null
+ var/suit = null
+ var/back = null
+ var/belt = null
+ var/gloves = null
+ var/shoes = null
+ var/head = null
+ var/mask = null
+ var/l_ear = null
+ var/r_ear = null
+ var/glasses = null
+ var/id = null
+ var/l_pocket = null
+ var/r_pocket = null
+ var/suit_store = null
+ var/l_hand = null
+ var/r_hand = null
+ var/pda = null
+ var/internals_slot = null //ID of slot containing a gas tank
+ var/list/backpack_contents = list() // In the list(path=count,otherpath=count) format
+
+
+/datum/outfit/proc/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ //to be overriden for customization depending on client prefs,species etc
+ return
+
+// Used to equip an item to the mob. Mainly to prevent copypasta for collect_not_del.
+/datum/outfit/proc/equip_item(mob/living/carbon/human/H, path, slot)
+ var/obj/item/I = new path(H)
+ if(collect_not_del)
+ H.equip_or_collect(I, slot)
+ else
+ H.equip_to_slot_or_del(I, slot)
+
+/datum/outfit/proc/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ //to be overriden for toggling internals, id binding, access etc
+ return
+
+/datum/outfit/proc/equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ pre_equip(H, visualsOnly)
+
+ //Start with uniform,suit,backpack for additional slots
+ if(uniform)
+ equip_item(H, uniform, slot_w_uniform)
+ if(suit)
+ equip_item(H, suit, slot_wear_suit)
+ if(back)
+ equip_item(H, back, slot_back)
+ if(belt)
+ equip_item(H, belt, slot_belt)
+ if(gloves)
+ equip_item(H, gloves, slot_gloves)
+ if(shoes)
+ equip_item(H, shoes, slot_shoes)
+ if(head)
+ equip_item(H, head, slot_head)
+ if(mask)
+ equip_item(H, mask, slot_wear_mask)
+ if(l_ear)
+ equip_item(H, l_ear, slot_l_ear)
+ if(r_ear)
+ equip_item(H, r_ear, slot_r_ear)
+ if(glasses)
+ equip_item(H, glasses, slot_glasses)
+ if(id)
+ equip_item(H, id, slot_wear_id)
+ if(suit_store)
+ equip_item(H, suit_store, slot_s_store)
+
+ if(l_hand)
+ H.put_in_l_hand(new l_hand(H))
+ if(r_hand)
+ H.put_in_r_hand(new r_hand(H))
+
+ if(pda)
+ equip_item(H, pda, slot_wear_pda)
+
+ if(!visualsOnly) // Items in pockets or backpack don't show up on mob's icon.
+ if(l_pocket)
+ equip_item(H, l_pocket, slot_l_store)
+ if(r_pocket)
+ equip_item(H, r_pocket, slot_r_store)
+
+ for(var/path in backpack_contents)
+ var/number = backpack_contents[path]
+ for(var/i = 0, i < number, i++)
+ equip_item(H, path, slot_in_backpack)
+
+ post_equip(H, visualsOnly)
+
+ if(!visualsOnly)
+ apply_fingerprints(H)
+ if(internals_slot)
+ H.internal = H.get_item_by_slot(internals_slot)
+ H.update_action_buttons_icon()
+
+ H.update_body()
+ return 1
+
+/datum/outfit/proc/apply_fingerprints(mob/living/carbon/human/H)
+ if(!istype(H))
+ return
+ if(H.back)
+ H.back.add_fingerprint(H, 1) //The 1 sets a flag to ignore gloves
+ for(var/obj/item/I in H.back.contents)
+ I.add_fingerprint(H, 1)
+ if(H.wear_id)
+ H.wear_id.add_fingerprint(H, 1)
+ if(H.w_uniform)
+ H.w_uniform.add_fingerprint(H, 1)
+ if(H.wear_suit)
+ H.wear_suit.add_fingerprint(H, 1)
+ if(H.wear_mask)
+ H.wear_mask.add_fingerprint(H, 1)
+ if(H.head)
+ H.head.add_fingerprint(H, 1)
+ if(H.shoes)
+ H.shoes.add_fingerprint(H, 1)
+ if(H.gloves)
+ H.gloves.add_fingerprint(H, 1)
+ if(H.l_ear)
+ H.l_ear.add_fingerprint(H, 1)
+ if(H.r_ear)
+ H.r_ear.add_fingerprint(H, 1)
+ if(H.glasses)
+ H.glasses.add_fingerprint(H, 1)
+ if(H.belt)
+ H.belt.add_fingerprint(H, 1)
+ for(var/obj/item/I in H.belt.contents)
+ I.add_fingerprint(H, 1)
+ if(H.s_store)
+ H.s_store.add_fingerprint(H, 1)
+ if(H.l_store)
+ H.l_store.add_fingerprint(H, 1)
+ if(H.r_store)
+ H.r_store.add_fingerprint(H, 1)
+ if(H.wear_pda)
+ H.wear_pda.add_fingerprint(H, 1)
+ return 1
\ No newline at end of file
diff --git a/code/datums/outfits/outfit_admin.dm b/code/datums/outfits/outfit_admin.dm
new file mode 100644
index 00000000000..9bc700ebabe
--- /dev/null
+++ b/code/datums/outfits/outfit_admin.dm
@@ -0,0 +1,1181 @@
+// Used for 'select equipment'
+// code/modules/admin/verbs/debug.dm 566
+
+/proc/apply_to_card(obj/item/weapon/card/id/I, mob/living/carbon/human/H, list/access = list(), rank, special_icon)
+ if(!istype(I) || !istype(H))
+ return 0
+
+ I.access = access
+ I.registered_name = H.real_name
+ I.rank = rank
+ I.assignment = rank
+ I.sex = capitalize(H.gender)
+ I.age = H.age
+ I.name = "[I.registered_name]'s ID Card ([I.assignment])"
+ I.photo = get_id_photo(H)
+
+ if(special_icon)
+ I.icon_state = special_icon
+
+/datum/outfit/admin
+
+/datum/outfit/admin/syndicate
+ name = "Syndicate Agent"
+
+ uniform = /obj/item/clothing/under/syndicate
+ back = /obj/item/weapon/storage/backpack
+ belt = /obj/item/weapon/storage/belt/utility/full/multitool
+ gloves = /obj/item/clothing/gloves/combat
+ shoes = /obj/item/clothing/shoes/combat
+ l_ear = /obj/item/device/radio/headset/syndicate
+ id = /obj/item/weapon/card/id/syndicate
+ r_pocket = /obj/item/device/radio/uplink
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/engineer = 1,
+ /obj/item/device/flashlight = 1,
+ /obj/item/weapon/card/emag = 1,
+ /obj/item/weapon/reagent_containers/food/snacks/syndidonkpocket = 1
+ )
+
+ var/id_icon = "syndie"
+ var/id_access = "Syndicate Operative"
+ var/uplink_uses = 20
+
+/datum/outfit/admin/syndicate/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_syndicate_access(id_access), name, id_icon)
+
+ var/obj/item/device/radio/uplink/U = H.r_store
+ if(istype(U))
+ U.hidden_uplink.uplink_owner = "[H.key]"
+ U.hidden_uplink.uses = uplink_uses
+
+ var/obj/item/device/radio/R = H.l_ear
+ if(istype(R))
+ R.set_frequency(SYND_FREQ)
+
+/datum/outfit/admin/syndicate/infiltrator
+ name = "Syndicate Infiltrator"
+
+ uniform = /obj/item/clothing/under/chameleon
+ glasses = /obj/item/clothing/glasses/hud/security/chameleon
+ shoes = /obj/item/clothing/shoes/syndigaloshes
+ r_pocket = null
+ pda = /obj/item/device/pda
+
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/engineer = 1,
+ /obj/item/device/flashlight = 1,
+ /obj/item/weapon/reagent_containers/food/snacks/syndidonkpocket = 1
+ )
+
+/datum/outfit/admin/syndicate/infiltrator/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+ if(H.gloves)
+ H.gloves.name = "black gloves"
+
+ var/obj/item/weapon/implant/uplink/U = new /obj/item/weapon/implant/uplink(H)
+ U.implant(H)
+ U.hidden_uplink.uses = uplink_uses
+
+ var/obj/item/weapon/implant/dust/D = new /obj/item/weapon/implant/dust(H)
+ D.implant(H)
+
+/datum/outfit/admin/syndicate/operative
+ name = "Syndicate Nuclear Operative"
+
+ suit = /obj/item/clothing/suit/space/hardsuit/syndi
+ belt = /obj/item/weapon/storage/belt/military
+ head = /obj/item/clothing/head/helmet/space/hardsuit/syndi
+ mask = /obj/item/clothing/mask/gas/syndicate
+ l_ear = /obj/item/device/radio/headset/syndicate/alt
+ glasses = /obj/item/clothing/glasses/night
+ l_pocket = /obj/item/weapon/pinpointer/advpinpointer
+ l_hand = /obj/item/weapon/tank/jetpack/oxygen/harness
+
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/engineer = 1,
+ /obj/item/weapon/reagent_containers/food/pill/initropidril = 1,
+ /obj/item/weapon/gun/projectile/automatic/pistol = 1,
+ /obj/item/ammo_box/magazine/m10mm = 1,
+ /obj/item/weapon/crowbar/red = 1,
+ /obj/item/weapon/grenade/plastic/c4 = 1,
+ /obj/item/weapon/reagent_containers/food/snacks/syndidonkpocket = 1,
+ /obj/item/device/flashlight = 1,
+ )
+
+/datum/outfit/admin/syndicate/operative/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/implant/explosive/E = new(H)
+ E.implant(H)
+
+/datum/outfit/admin/syndicate_strike_team
+ name = "Syndicate Strike Team"
+
+/datum/outfit/admin/syndicate_strike_team/equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ return H.equip_syndicate_commando()
+
+/datum/outfit/admin/syndicate/officer
+ name = "Syndicate Officer"
+
+ belt = /obj/item/weapon/gun/projectile/automatic/pistol/deagle/camo
+ l_ear = /obj/item/device/radio/headset/syndicate/alt
+ l_pocket = /obj/item/weapon/pinpointer/advpinpointer
+
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/engineer = 1,
+ /obj/item/weapon/reagent_containers/food/pill/initropidril = 1,
+ /obj/item/weapon/reagent_containers/food/snacks/syndidonkpocket = 1,
+ /obj/item/ammo_box/magazine/m50 = 2)
+
+ id_icon = "commander"
+ id_access = "Syndicate Operative Leader"
+ uplink_uses = 500
+
+/datum/outfit/admin/syndicate/officer/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/implant/uplink/U = new /obj/item/weapon/implant/uplink(H)
+ U.implant(H)
+ U.hidden_uplink.uses = 500//a measly 1000 TC along with the uplink in the pocket
+
+ var/obj/item/weapon/implant/dust/D = new(H)
+ D.implant(H)
+
+/datum/outfit/admin/syndicate/bomber
+ name = "Syndicate Bomber"
+
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/engineer = 1,
+ /obj/item/device/flashlight = 1,
+ /obj/item/weapon/card/emag = 1,
+ /obj/item/device/radio/beacon/syndicate/bomb = 2,
+ /obj/item/device/syndicatedetonator = 1,
+ /obj/item/weapon/reagent_containers/food/snacks/syndidonkpocket = 1
+ )
+
+/datum/outfit/admin/nt_vip
+ name = "VIP Guest"
+
+ uniform = /obj/item/clothing/under/suit_jacket/really_black
+ back = /obj/item/weapon/storage/backpack/satchel
+ gloves = /obj/item/clothing/gloves/color/black
+ shoes = /obj/item/clothing/shoes/black
+ head = /obj/item/clothing/head/that
+ l_ear = /obj/item/device/radio/headset/ert
+ id = /obj/item/weapon/card/id/centcom
+ pda = /obj/item/device/pda
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/engineer = 1
+ )
+
+/datum/outfit/admin/nt_vip/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_centcom_access("VIP Guest"), "VIP Guest")
+
+/datum/outfit/admin/nt_navy_officer
+ name = "NT Navy Officer"
+
+ uniform = /obj/item/clothing/under/rank/centcom/officer
+ back = /obj/item/weapon/storage/backpack/satchel
+ belt = /obj/item/weapon/gun/energy/pulse/pistol
+ gloves = /obj/item/clothing/gloves/color/white
+ shoes = /obj/item/clothing/shoes/centcom
+ head = /obj/item/clothing/head/beret/centcom/officer
+ l_ear = /obj/item/device/radio/headset/centcom
+ glasses = /obj/item/clothing/glasses/hud/security/sunglasses
+ id = /obj/item/weapon/card/id/centcom
+ pda = /obj/item/device/pda/centcom
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/engineer = 1,
+ /obj/item/weapon/implanter/dust = 1,
+ /obj/item/weapon/implanter/death_alarm = 1
+ )
+
+/datum/outfit/admin/nt_navy_officer/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_centcom_access("Nanotrasen Navy Officer"), "Nanotrasen Navy Officer")
+
+ var/obj/item/weapon/implant/L = new /obj/item/weapon/implant/mindshield(H)
+ L.imp_in = H
+ L.implanted = 1
+ H.sec_hud_set_implants()
+
+
+/datum/outfit/admin/nt_special_ops_officer
+ name = "NT Special Ops Officer"
+
+ uniform = /obj/item/clothing/under/syndicate/combat
+ suit = /obj/item/clothing/suit/space/deathsquad/officer
+ back = /obj/item/weapon/storage/backpack/security
+ belt = /obj/item/weapon/gun/energy/pulse/pistol/m1911
+ gloves = /obj/item/clothing/gloves/combat
+ shoes = /obj/item/clothing/shoes/combat
+ head = /obj/item/clothing/head/helmet/space/deathsquad/beret
+ mask = /obj/item/clothing/mask/cigarette/cigar/cohiba
+ l_ear = /obj/item/device/radio/headset/centcom
+ glasses = /obj/item/clothing/glasses/thermal/cyber
+ id = /obj/item/weapon/card/id/centcom
+ r_pocket = /obj/item/weapon/storage/box/matches
+ pda = /obj/item/device/pda/centcom
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/engineer = 1,
+ /obj/item/weapon/tank/emergency_oxygen/double/full = 1,
+ /obj/item/weapon/implanter/dust = 1,
+ /obj/item/weapon/implanter/death_alarm = 1,
+ /obj/item/weapon/twohanded/dualsaber/red = 1,
+ /obj/item/weapon/pinpointer/advpinpointer = 1,
+ /obj/item/weapon/reagent_containers/hypospray/combat/nanites = 1,
+ /obj/item/weapon/storage/box/zipties = 1,
+ /obj/item/clothing/shoes/magboots/advance = 1,
+ /obj/item/weapon/implanter/mindshield = 1,
+ )
+
+/datum/outfit/admin/nt_special_ops_officer/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_centcom_access("Special Operations Officer"), "Special Operations Officer")
+
+/datum/outfit/admin/nt_special_ops_formal
+ name = "NT Special Ops Formal"
+
+ uniform = /obj/item/clothing/under/rank/centcom/captain
+ back = /obj/item/weapon/storage/backpack/satchel
+ belt = /obj/item/weapon/gun/energy/pulse/pistol/m1911
+ gloves = /obj/item/clothing/gloves/combat
+ shoes = /obj/item/clothing/shoes/combat
+ head = /obj/item/clothing/head/helmet/space/deathsquad/beret
+ mask = /obj/item/clothing/mask/cigarette/cigar/cohiba
+ l_ear = /obj/item/device/radio/headset/centcom
+ glasses = /obj/item/clothing/glasses/thermal/cyber
+ id = /obj/item/weapon/card/id/centcom
+ r_pocket = /obj/item/weapon/storage/box/matches
+ pda = /obj/item/device/pda/centcom
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/engineer = 1,
+ /obj/item/weapon/melee/classic_baton/telescopic = 1,
+ /obj/item/weapon/implanter/dust = 1,
+ /obj/item/weapon/implanter/death_alarm = 1
+ )
+
+/datum/outfit/admin/nt_special_ops_formal/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/device/pda/PDA = H.wear_pda
+ if(istype(PDA))
+ PDA.owner = H.real_name
+ PDA.ownjob = "Special Operations Officer"
+ PDA.icon_state = "pda-syndi"
+ PDA.name = "PDA-[H.real_name] ([PDA.ownjob])"
+ PDA.desc = "A portable microcomputer by Thinktronic Systems, LTD. This is model is a special edition designed for military field work."
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_centcom_access("Special Operations Officer"), "Special Operations Officer")
+
+/datum/outfit/admin/nt_navy_captain
+ name = "NT Navy Captain"
+
+ uniform = /obj/item/clothing/under/rank/centcom/captain
+ back = /obj/item/weapon/storage/backpack/satchel
+ belt = /obj/item/weapon/gun/energy/pulse/pistol
+ gloves = /obj/item/clothing/gloves/color/white
+ shoes = /obj/item/clothing/shoes/centcom
+ head = /obj/item/clothing/head/beret/centcom/captain
+ l_ear = /obj/item/device/radio/headset/centcom
+ glasses = /obj/item/clothing/glasses/hud/security/sunglasses
+ id = /obj/item/weapon/card/id/centcom
+ pda = /obj/item/device/pda/centcom
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/engineer = 1,
+ /obj/item/weapon/implanter/dust = 1,
+ /obj/item/weapon/implanter/death_alarm = 1
+ )
+
+/datum/outfit/admin/nt_navy_captain/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_centcom_access("Nanotrasen Navy Captain"), "Nanotrasen Navy Captain")
+
+ var/obj/item/weapon/implant/L = new /obj/item/weapon/implant/mindshield(H)
+ L.imp_in = H
+ L.implanted = 1
+ H.sec_hud_set_implants()
+
+/datum/outfit/admin/nt_diplomat
+ name = "NT Diplomat"
+
+ uniform = /obj/item/clothing/under/rank/centcom/diplomatic
+ back = /obj/item/weapon/storage/backpack/satchel
+ gloves = /obj/item/clothing/gloves/color/white
+ shoes = /obj/item/clothing/shoes/centcom
+ l_ear = /obj/item/device/radio/headset/centcom
+ id = /obj/item/weapon/card/id/centcom
+ r_pocket = /obj/item/weapon/lighter/zippo/nt_rep
+ l_pocket = /obj/item/weapon/storage/fancy/cigarettes/dromedaryco
+ pda = /obj/item/device/pda/centcom
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/survival = 1,
+ /obj/item/weapon/implanter/dust = 1,
+ /obj/item/weapon/implanter/death_alarm = 1,
+ )
+
+/datum/outfit/admin/nt_diplomat/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_centcom_access("Nanotrasen Navy Representative"), "Nanotrasen Diplomat")
+
+/datum/outfit/admin/death_commando
+ name = "NT Death Commando"
+
+/datum/outfit/admin/death_commando/equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ return H.equip_death_commando()
+
+/datum/outfit/admin/pirate
+ name = "Space Pirate"
+
+ uniform = /obj/item/clothing/under/pirate
+ back = /obj/item/weapon/storage/backpack/satchel
+ shoes = /obj/item/clothing/shoes/brown
+ id = /obj/item/weapon/card/id
+ r_hand = /obj/item/weapon/melee/energy/sword/pirate
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/survival = 1
+ )
+
+/datum/outfit/admin/pirate/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, list(access_maint_tunnels), name)
+
+/datum/outfit/admin/pirate/first_mate
+ name = "Space Pirate First Mate"
+
+ glasses = /obj/item/clothing/glasses/eyepatch
+ head = /obj/item/clothing/head/bandana
+
+/datum/outfit/admin/pirate/captain
+ name = "Space Pirate Captain"
+
+ suit = /obj/item/clothing/suit/pirate_black
+ head = /obj/item/clothing/head/pirate
+
+/datum/outfit/admin/vox
+ name = "Vox Raider"
+ uniform = /obj/item/clothing/under/vox/vox_robes
+ suit = /obj/item/clothing/suit/space/vox/carapace
+ back = /obj/item/weapon/storage/backpack
+ gloves = /obj/item/clothing/gloves/color/yellow/vox
+ shoes = /obj/item/clothing/shoes/magboots/vox
+ head = /obj/item/clothing/head/helmet/space/vox/carapace
+ mask = /obj/item/clothing/mask/gas/syndicate
+ l_ear = /obj/item/device/radio/headset/syndicate
+ glasses = /obj/item/clothing/glasses/thermal/monocle
+ id = /obj/item/weapon/card/id/syndicate/vox
+ l_pocket = /obj/item/weapon/melee/classic_baton/telescopic
+ r_pocket = /obj/item/weapon/tank/emergency_oxygen/vox
+ backpack_contents = list(
+ /obj/item/device/flashlight = 1,
+ /obj/item/weapon/restraints/handcuffs/cable/zipties = 1,
+ /obj/item/device/flash = 1,
+ /obj/item/weapon/gun/energy/noisecannon = 1
+ )
+
+/datum/outfit/admin/vox/equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ if(H.get_species() == "Vox Armalis")
+ . = ..()
+ else
+ H.equip_vox_raider()
+ H.regenerate_icons()
+
+/datum/outfit/admin/vox/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_all_accesses(), "Vox Armalis", "syndie")
+
+/datum/outfit/admin/tunnel_clown
+ name = "Tunnel Clown"
+
+ uniform = /obj/item/clothing/under/rank/clown
+ suit = /obj/item/clothing/suit/hooded/chaplain_hoodie
+ back = /obj/item/weapon/storage/backpack
+ belt = /obj/item/weapon/storage/belt/utility/full/multitool
+ gloves = /obj/item/clothing/gloves/color/black
+ shoes = /obj/item/clothing/shoes/clown_shoes
+ mask = /obj/item/clothing/mask/gas/clown_hat
+ l_ear = /obj/item/device/radio/headset
+ glasses = /obj/item/clothing/glasses/thermal/monocle
+ id = /obj/item/weapon/card/id
+ l_pocket = /obj/item/weapon/reagent_containers/food/snacks/grown/banana
+ r_pocket = /obj/item/weapon/bikehorn
+ r_hand = /obj/item/weapon/twohanded/fireaxe
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/survival = 1,
+ /obj/item/device/flashlight = 1
+ )
+
+/datum/outfit/admin/tunnel_clown/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, list(access_clown, access_theatre, access_maint_tunnels), "Tunnel Clown")
+
+/datum/outfit/admin/mime_assassin
+ name = "Mime Assassin"
+
+ uniform = /obj/item/clothing/under/mime
+ suit = /obj/item/clothing/suit/suspenders
+ back = /obj/item/weapon/storage/backpack/mime
+ belt = /obj/item/weapon/storage/belt/utility/full/multitool
+ gloves = /obj/item/clothing/gloves/color/white
+ shoes = /obj/item/clothing/shoes/black
+ head = /obj/item/clothing/head/beret
+ mask = /obj/item/clothing/mask/gas/mime
+ l_ear = /obj/item/device/radio/headset
+ glasses = /obj/item/clothing/glasses/thermal/monocle
+ id = /obj/item/weapon/card/id/syndicate
+ pda = /obj/item/device/pda/mime
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/survival = 1,
+ /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing = 1,
+ /obj/item/weapon/storage/box/syndie_kit/caneshotgun = 1,
+ /obj/item/toy/crayon/mime = 1,
+ /obj/item/weapon/gun/projectile/automatic/pistol = 1,
+ /obj/item/weapon/suppressor = 1,
+ /obj/item/ammo_casing/shotgun/incendiary/dragonsbreath = 2,
+ /obj/item/weapon/pen/sleepy = 1,
+ /obj/item/weapon/reagent_containers/food/snacks/syndidonkpocket = 1,
+ /obj/item/device/flashlight = 1
+ )
+
+/datum/outfit/admin/mime_assassin/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(H.gender == FEMALE)
+ uniform = /obj/item/clothing/under/sexymime
+ suit = /obj/item/clothing/mask/gas/sexymime
+
+/datum/outfit/admin/mime_assassin/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/device/pda/PDA = H.wear_pda
+ if(istype(PDA))
+ PDA.owner = H.real_name
+ PDA.ownjob = "Mime"
+ PDA.name = "PDA-[H.real_name] ([PDA.ownjob])"
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, list(access_mime, access_theatre, access_maint_tunnels), "Mime")
+
+/datum/outfit/admin/greytide
+ name = "Greytide"
+
+ uniform = /obj/item/clothing/under/color/grey
+ back = /obj/item/weapon/storage/backpack
+ shoes = /obj/item/clothing/shoes/brown
+ mask = /obj/item/clothing/mask/gas
+ l_ear = /obj/item/device/radio/headset
+ id = /obj/item/weapon/card/id
+ l_hand = /obj/item/weapon/storage/toolbox/mechanical
+ r_hand = /obj/item/flag/grey
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/survival = 1,
+ /obj/item/device/flashlight = 1
+ )
+
+/datum/outfit/admin/greytide/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, list(access_maint_tunnels), "Greytide")
+
+/datum/outfit/admin/greytide/leader
+ name = "Greytide Leader"
+
+ belt = /obj/item/weapon/storage/belt/utility/full/multitool
+ gloves = /obj/item/clothing/gloves/color/yellow
+
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/survival = 1,
+ /obj/item/clothing/head/welding = 1,
+ /obj/item/device/flashlight = 1
+ )
+
+/datum/outfit/admin/greytide/leader/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..(H, TRUE)
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, list(access_maint_tunnels), "Greytide Leader")
+
+/datum/outfit/admin/greytide/xeno
+ name = "Greytide Xeno"
+
+ uniform = /obj/item/clothing/under/color/black
+ suit = /obj/item/clothing/suit/xenos
+ back = /obj/item/weapon/storage/backpack/satchel
+ belt = /obj/item/weapon/storage/belt/utility/full/multitool
+ gloves = /obj/item/clothing/gloves/color/yellow
+ shoes = /obj/item/clothing/shoes/black
+ head = /obj/item/clothing/head/xenos
+ glasses = /obj/item/clothing/glasses/thermal
+ l_pocket = /obj/item/weapon/tank/emergency_oxygen/double/full
+ r_pocket = /obj/item/toy/toy_xeno
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/survival = 1,
+ /obj/item/clothing/head/welding = 1,
+ /obj/item/device/flashlight = 1
+ )
+
+/datum/outfit/admin/greytide/xeno/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..(H, TRUE)
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, list(access_maint_tunnels), "Legit Xenomorph")
+
+/datum/outfit/admin/soviet
+ uniform = /obj/item/clothing/under/soviet
+ back = /obj/item/weapon/storage/backpack/satchel
+ head = /obj/item/clothing/head/ushanka
+ id = /obj/item/weapon/card/id
+
+/datum/outfit/admin/soviet/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_all_accesses(), name)
+
+/datum/outfit/admin/soviet/tourist
+ name = "Soviet Tourist"
+
+ gloves = /obj/item/clothing/gloves/color/black
+ shoes = /obj/item/clothing/shoes/black
+ l_ear = /obj/item/device/radio/headset
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/survival = 1
+ )
+
+/datum/outfit/admin/soviet/soldier
+ name = "Soviet Soldier"
+
+ gloves = /obj/item/clothing/gloves/combat
+ shoes = /obj/item/clothing/shoes/combat
+ l_ear = /obj/item/device/radio/headset/syndicate
+ glasses = /obj/item/clothing/glasses/sunglasses
+
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/engineer = 1,
+ /obj/item/weapon/card/emag = 1,
+ /obj/item/device/flashlight = 1,
+ /obj/item/weapon/grenade/plastic/c4 = 2,
+ /obj/item/weapon/gun/projectile/revolver/mateba = 1,
+ /obj/item/ammo_box/a357 = 3
+ )
+
+/datum/outfit/admin/soviet/admiral
+ name = "Soviet Admiral"
+
+ suit = /obj/item/clothing/suit/hgpirate
+ belt = null
+ gloves = /obj/item/clothing/gloves/combat
+ shoes = /obj/item/clothing/shoes/combat
+ head = /obj/item/clothing/head/hgpiratecap
+ mask = null
+ l_ear = /obj/item/device/radio/headset/syndicate
+ r_ear = null
+ glasses = /obj/item/clothing/glasses/thermal/eyepatch
+ id = null
+ l_pocket = null
+ r_pocket = null
+ suit_store = null
+ l_hand = null
+ r_hand = null
+ pda = null
+
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/engineer = 1,
+ /obj/item/weapon/gun/projectile/revolver/mateba = 1,
+ /obj/item/ammo_box/a357 = 3
+ )
+
+/datum/outfit/admin/solgov_rep
+ name = "Solar Federation Representative"
+
+ uniform = /obj/item/clothing/under/solgov/rep
+ back = /obj/item/weapon/storage/backpack/satchel
+ gloves = /obj/item/clothing/gloves/color/white
+ shoes = /obj/item/clothing/shoes/centcom
+ l_ear = /obj/item/device/radio/headset
+ id = /obj/item/weapon/card/id/silver
+ r_pocket = /obj/item/weapon/lighter/zippo/blue
+ l_pocket = /obj/item/weapon/storage/fancy/cigarettes/cigpack_robustgold
+ pda = /obj/item/device/pda
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/survival = 1,
+ /obj/item/weapon/implanter/dust = 1,
+ /obj/item/weapon/implanter/death_alarm = 1,
+ )
+
+/datum/outfit/admin/solgov_rep/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_centcom_access("VIP Guest"), "Solar Federation Representative")
+
+
+/datum/outfit/admin/solgov
+ name = "Solar Federation Marine"
+
+ uniform = /obj/item/clothing/under/solgov
+ back = /obj/item/weapon/storage/backpack/security
+ head = /obj/item/clothing/head/soft/solgov
+ gloves = /obj/item/clothing/gloves/combat
+ shoes = /obj/item/clothing/shoes/combat
+ id = /obj/item/weapon/card/id
+ l_hand = /obj/item/weapon/gun/projectile/automatic/ar
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/survival = 1,
+ /obj/item/weapon/kitchen/knife/combat = 1,
+ /obj/item/ammo_box/magazine/m556 = 3)
+
+
+/datum/outfit/admin/solgov/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_centcom_access("VIP Guest"), name)
+
+/datum/outfit/admin/solgov/lieutenant
+ name = "Solar Federation Lieutenant"
+
+ uniform = /obj/item/clothing/under/solgov/command
+ head = /obj/item/clothing/head/soft/solgov/command
+ back = /obj/item/weapon/storage/backpack/satchel
+ l_hand = null
+ belt = /obj/item/weapon/gun/projectile/automatic/pistol/deagle
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/survival = 1,
+ /obj/item/weapon/kitchen/knife/combat = 1,
+ /obj/item/weapon/melee/classic_baton/telescopic = 1,
+ /obj/item/ammo_box/magazine/m50 = 2)
+
+/datum/outfit/admin/janitorial_ert
+ name = "Janitorial ERT member"
+
+ uniform = /obj/item/clothing/under/syndicate
+ suit = /obj/item/clothing/suit/space/hardsuit/ert/janitor
+ back = /obj/item/weapon/storage/backpack/ert/janitor
+ belt = /obj/item/weapon/storage/belt/janitor/full
+ gloves = /obj/item/clothing/gloves/color/yellow
+ shoes = /obj/item/clothing/shoes/galoshes
+ head = /obj/item/clothing/head/helmet/space/hardsuit/ert/janitor
+ l_ear = /obj/item/device/radio/headset/centcom
+ glasses = /obj/item/clothing/glasses/sunglasses
+ id = /obj/item/weapon/card/id/centcom
+ pda = /obj/item/device/pda/centcom
+ backpack_contents = list(
+ /obj/item/weapon/caution = 2,
+ /obj/item/weapon/reagent_containers/spray/cleaner = 1,
+ /obj/item/weapon/storage/bag/trash = 1,
+ /obj/item/weapon/storage/box/lights/mixed = 1,
+ /obj/item/weapon/holosign_creator = 1)
+
+/datum/outfit/admin/janitorial_ert/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_centcom_access("Emergency Response Team Member"), "Emergency Response Team Member")
+
+ var/obj/item/weapon/implant/L = new /obj/item/weapon/implant/mindshield(H)
+ L.imp_in = H
+ L.implanted = 1
+ H.sec_hud_set_implants()
+
+/datum/outfit/admin/chrono
+ name = "Chrono Legionnaire"
+
+ uniform = /obj/item/clothing/under/syndicate
+ suit = /obj/item/clothing/suit/space/chronos
+ back = /obj/item/weapon/chrono_eraser
+ gloves = /obj/item/clothing/gloves/combat
+ shoes = /obj/item/clothing/shoes/combat
+ head = /obj/item/clothing/head/helmet/space/chronos
+ mask = /obj/item/clothing/mask/gas/syndicate
+ glasses = /obj/item/clothing/glasses/night
+ id = /obj/item/weapon/card/id/syndicate
+ suit_store = /obj/item/weapon/tank/emergency_oxygen/double/full
+
+/datum/outfit/admin/chrono/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_all_accesses() + get_all_centcom_access(), name, "syndie")
+
+/datum/outfit/admin/spacegear
+ name = "Standard Space Gear"
+
+ uniform = /obj/item/clothing/under/color/grey
+ suit = /obj/item/clothing/suit/space
+ back = /obj/item/weapon/tank/jetpack/oxygen
+ shoes = /obj/item/clothing/shoes/black
+ head = /obj/item/clothing/head/helmet/space
+ mask = /obj/item/clothing/mask/breath
+ l_ear = /obj/item/device/radio/headset
+ id = /obj/item/weapon/card/id
+
+/datum/outfit/admin/spacegear/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ if(istype(H.back, /obj/item/weapon/tank/jetpack))
+ var/obj/item/weapon/tank/jetpack/J = H.back
+ J.turn_on()
+ J.toggle_internals(H)
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_all_accesses(), "Space Explorer")
+
+/datum/outfit/admin/hardsuit
+ back = /obj/item/weapon/tank/jetpack/oxygen
+ mask = /obj/item/clothing/mask/breath
+ id = /obj/item/weapon/card/id
+
+/datum/outfit/admin/hardsuit/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ if(istype(H.back, /obj/item/weapon/tank/jetpack))
+ var/obj/item/weapon/tank/jetpack/J = H.back
+ J.turn_on()
+ J.toggle_internals(H)
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_all_accesses(), "Hardsuit Tester")
+
+/datum/outfit/admin/hardsuit/engineer
+ name = "Engineer Hardsuit"
+ suit = /obj/item/clothing/suit/space/hardsuit
+ head = /obj/item/clothing/head/helmet/space/hardsuit
+
+/datum/outfit/admin/hardsuit/ce
+ name = "CE Hardsuit"
+ suit = /obj/item/clothing/suit/space/hardsuit/elite
+ head = /obj/item/clothing/head/helmet/space/hardsuit/elite
+
+/datum/outfit/admin/hardsuit/mining
+ name = "Mining Hardsuit"
+ suit = /obj/item/clothing/suit/space/hardsuit/mining
+ head = /obj/item/clothing/head/helmet/space/hardsuit/mining
+
+/datum/outfit/admin/hardsuit/syndi
+ name = "Syndi Hardsuit"
+ suit = /obj/item/clothing/suit/space/hardsuit/syndi
+ head = /obj/item/clothing/head/helmet/space/hardsuit/syndi
+
+/datum/outfit/admin/hardsuit/wizard
+ name = "Wizard Hardsuit"
+ suit = /obj/item/clothing/suit/space/hardsuit/wizard
+ head = /obj/item/clothing/head/helmet/space/hardsuit/wizard
+
+/datum/outfit/admin/hardsuit/medical
+ name = "Medical Hardsuit"
+ suit = /obj/item/clothing/suit/space/hardsuit/medical
+ head = /obj/item/clothing/head/helmet/space/hardsuit/medical
+
+/datum/outfit/admin/hardsuit/atmos
+ name = "Atmos Hardsuit"
+ suit = /obj/item/clothing/suit/space/hardsuit/atmos
+ head = /obj/item/clothing/head/helmet/space/hardsuit/atmos
+
+
+/datum/outfit/admin/tournament
+ suit = /obj/item/clothing/suit/armor/vest
+ shoes = /obj/item/clothing/shoes/black
+ head = /obj/item/clothing/head/helmet/thunderdome
+ r_pocket = /obj/item/weapon/grenade/smokebomb
+ l_hand = /obj/item/weapon/kitchen/knife
+ r_hand = /obj/item/weapon/gun/energy/pulse/destroyer
+
+/datum/outfit/admin/tournament/red
+ name = "Tournament Standard Red"
+ uniform = /obj/item/clothing/under/color/red
+
+/datum/outfit/admin/tournament/green
+ name = "Tournament Standard Green"
+ uniform = /obj/item/clothing/under/color/green
+
+/datum/outfit/admin/tournament_gangster //gangster are supposed to fight each other. --rastaf0
+ name = "Tournament Gangster"
+
+ uniform = /obj/item/clothing/under/det
+ suit = /obj/item/clothing/suit/storage/det_suit
+ shoes = /obj/item/clothing/shoes/black
+ head = /obj/item/clothing/head/det_hat
+ glasses = /obj/item/clothing/glasses/thermal/monocle
+ l_pocket = /obj/item/ammo_box/a357
+ r_hand = /obj/item/weapon/gun/projectile/automatic/proto
+
+/datum/outfit/admin/tournament_chef //Steven Seagal FTW
+ name = "Tournament Chef"
+
+ uniform = /obj/item/clothing/under/rank/chef
+ suit = /obj/item/clothing/suit/chef
+ shoes = /obj/item/clothing/shoes/black
+ head = /obj/item/clothing/head/chefhat
+ l_pocket = /obj/item/weapon/kitchen/knife
+ r_pocket = /obj/item/weapon/kitchen/knife
+ l_hand = /obj/item/weapon/kitchen/knife
+ r_hand = /obj/item/weapon/kitchen/rollingpin
+
+/datum/outfit/admin/tournament_janitor
+ name = "Tournament Janitor"
+
+ uniform = /obj/item/clothing/under/rank/janitor
+ back = /obj/item/weapon/storage/backpack
+ shoes = /obj/item/clothing/shoes/black
+ l_hand = /obj/item/weapon/reagent_containers/glass/bucket
+ backpack_contents = list(
+ /obj/item/weapon/grenade/chem_grenade/cleaner = 2,
+ /obj/item/stack/tile/plasteel = 7
+ )
+
+/datum/outfit/admin/tournament_janitor/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/reagent_containers/R = H.l_hand
+ if(istype(R))
+ R.reagents.add_reagent("water", 70)
+
+/datum/outfit/admin/survivor
+ name = "Survivor"
+
+ uniform = /obj/item/clothing/under/overalls
+ back = /obj/item/weapon/storage/backpack
+ gloves = /obj/item/clothing/gloves/color/latex
+ shoes = /obj/item/clothing/shoes/white
+ l_ear = /obj/item/device/radio/headset
+ id = /obj/item/weapon/card/id
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/survival = 1
+ )
+
+/datum/outfit/admin/survivor/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+
+ for(var/obj/item/I in H.contents)
+ if(!istype(I, /obj/item/weapon/implant))
+ I.add_blood(H)
+
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, list(access_maint_tunnels), "Survivor")
+
+/datum/outfit/admin/masked_killer
+ name = "Masked Killer"
+
+ uniform = /obj/item/clothing/under/overalls
+ suit = /obj/item/clothing/suit/apron
+ back = /obj/item/weapon/storage/backpack
+ gloves = /obj/item/clothing/gloves/color/latex
+ shoes = /obj/item/clothing/shoes/white
+ head = /obj/item/clothing/head/welding
+ mask = /obj/item/clothing/mask/surgical
+ l_ear = /obj/item/device/radio/headset
+ glasses = /obj/item/clothing/glasses/thermal/monocle
+ id = /obj/item/weapon/card/id/syndicate
+ l_pocket = /obj/item/weapon/kitchen/knife
+ r_pocket = /obj/item/weapon/scalpel
+ r_hand = /obj/item/weapon/twohanded/fireaxe
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/survival = 1,
+ /obj/item/device/flashlight = 1
+ )
+
+/datum/outfit/admin/masked_killer/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+
+ for(var/obj/item/I in H.contents)
+ if(!istype(I, /obj/item/weapon/implant))
+ I.add_blood(H)
+
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, list(access_maint_tunnels), "Masked Killer", "syndie")
+
+/datum/outfit/admin/singuloth_knight
+ name = "Singuloth Knight"
+
+ uniform = /obj/item/clothing/under/syndicate/combat
+ suit = /obj/item/clothing/suit/space/hardsuit/singuloth
+ back = /obj/item/weapon/twohanded/knighthammer
+ belt = /obj/item/weapon/claymore/ceremonial
+ gloves = /obj/item/clothing/gloves/combat
+ shoes = /obj/item/clothing/shoes/magboots
+ head = /obj/item/clothing/head/helmet/space/hardsuit/singuloth
+ mask = /obj/item/clothing/mask/breath
+ l_ear = /obj/item/device/radio/headset/ert
+ glasses = /obj/item/clothing/glasses/meson/cyber
+ id = /obj/item/weapon/card/id
+ suit_store = /obj/item/weapon/tank/oxygen
+
+/datum/outfit/admin/singuloth_knight/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_all_accesses(), "Singuloth Knight")
+
+/datum/outfit/admin/assassin
+ name = "Assassin"
+
+ uniform = /obj/item/clothing/under/suit_jacket
+ suit = /obj/item/clothing/suit/wcoat
+ back = /obj/item/weapon/storage/backpack
+ gloves = /obj/item/clothing/gloves/color/black
+ shoes = /obj/item/clothing/shoes/black
+ l_ear = /obj/item/device/radio/headset/syndicate
+ glasses = /obj/item/clothing/glasses/sunglasses
+ id = /obj/item/weapon/card/id/syndicate
+ l_pocket = /obj/item/weapon/melee/energy/sword/saber
+ l_hand = /obj/item/weapon/storage/secure/briefcase
+ pda = /obj/item/device/pda/heads
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/survival = 1,
+ /obj/item/device/flashlight = 1
+ )
+
+ var/briefcase_contents = list(
+ /obj/item/stack/spacecash/c1000 = 3,
+ /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow = 1,
+ /obj/item/weapon/gun/projectile/revolver/mateba = 1,
+ /obj/item/ammo_box/a357 = 1,
+ /obj/item/weapon/grenade/plastic/c4 = 1
+ )
+
+/datum/outfit/admin/assassin/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/storage/secure/briefcase/B = H.l_hand
+ if(istype(B))
+ for(var/obj/item/I in B)
+ qdel(I)
+ for(var/path in briefcase_contents)
+ var/number = backpack_contents[path]
+ for(var/i = 0, i < number, i++)
+ B.handle_item_insertion(new path(B), 1)
+
+ var/obj/item/weapon/implant/dust/D = new /obj/item/weapon/implant/dust(H)
+ D.implant(H)
+
+ var/obj/item/device/pda/PDA = H.wear_pda
+ if(istype(PDA))
+ PDA.owner = H.real_name
+ PDA.ownjob = "Reaper"
+ PDA.name = "PDA-[H.real_name] ([PDA.ownjob])"
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_all_accesses(), "Reaper", "syndie")
+
+/datum/outfit/admin/spy
+ name = "Spy"
+
+ uniform = /obj/item/clothing/under/suit_jacket/really_black
+ back = /obj/item/weapon/storage/backpack
+ gloves = /obj/item/clothing/gloves/combat
+ shoes = /obj/item/clothing/shoes/black
+ l_ear = /obj/item/device/radio/headset/syndicate
+ glasses = /obj/item/clothing/glasses/hud/security/chameleon
+ id = /obj/item/weapon/card/id/syndicate
+ l_pocket = /obj/item/weapon/melee/energy/sword/saber
+ r_pocket = /obj/item/weapon/pen/sleepy
+ pda = /obj/item/device/pda/heads
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/survival = 1,
+ /obj/item/weapon/gun/projectile/automatic/pistol = 1,
+ /obj/item/weapon/suppressor = 1,
+ /obj/item/weapon/card/emag = 1,
+ /obj/item/device/flashlight = 1,
+ /obj/item/weapon/implanter/storage = 1
+ )
+
+/datum/outfit/admin/spy/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/clothing/gloves/combat/G = H.gloves
+ if(istype(G))
+ G.name = "black gloves"
+
+ var/obj/item/weapon/implant/dust/D = new /obj/item/weapon/implant/dust(H)
+ D.implant(H)
+
+ var/obj/item/device/pda/PDA = H.wear_pda
+ if(istype(PDA))
+ PDA.owner = H.real_name
+ PDA.ownjob = "Spy"
+ PDA.name = "PDA-[H.real_name] ([PDA.ownjob])"
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, list(access_maint_tunnels), "Spy", "syndie")
+
+/datum/outfit/admin/dark_lord
+ name = "Dark Lord"
+
+ uniform = /obj/item/clothing/under/color/black
+ suit = /obj/item/clothing/suit/hooded/chaplain_hoodie
+ back = /obj/item/weapon/storage/backpack
+ gloves = /obj/item/clothing/gloves/color/black
+ shoes = /obj/item/clothing/shoes/black
+ l_ear = /obj/item/device/radio/headset/syndicate
+ id = /obj/item/weapon/card/id/syndicate
+ l_hand = /obj/item/weapon/twohanded/dualsaber/red
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/survival = 1,
+ /obj/item/device/flashlight = 1,
+ )
+
+/datum/outfit/admin/dark_lord/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/clothing/suit/hooded/chaplain_hoodie/C = H.wear_suit
+ if(istype(C))
+ C.name = "dark lord robes"
+ C.hood.name = "dark lord hood"
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_all_accesses(), "Dark Lord", "syndie")
+
+/datum/outfit/admin/wizard
+ uniform = /obj/item/clothing/under/color/lightpurple
+ suit = /obj/item/clothing/suit/wizrobe
+ back = /obj/item/weapon/storage/backpack
+ shoes = /obj/item/clothing/shoes/sandal
+ head = /obj/item/clothing/head/wizard
+ l_ear = /obj/item/device/radio/headset
+ id = /obj/item/weapon/card/id
+ r_pocket = /obj/item/weapon/teleportation_scroll
+ l_hand = /obj/item/weapon/twohanded/staff
+ r_hand = /obj/item/weapon/spellbook
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/engineer = 1
+ )
+
+/datum/outfit/admin/wizard/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/card/id/I = H.wear_id
+ if(istype(I))
+ apply_to_card(I, H, get_all_accesses(), "Wizard")
+
+/datum/outfit/admin/wizard/blue
+ name = "Blue Wizard"
+ // the default wizard clothes are blue
+
+/datum/outfit/admin/wizard/red
+ name = "Red Wizard"
+
+ suit = /obj/item/clothing/suit/wizrobe/red
+ head = /obj/item/clothing/head/wizard/red
+
+/datum/outfit/admin/wizard/marisa
+ name = "Marisa Wizard"
+
+ suit = /obj/item/clothing/suit/wizrobe/marisa
+ shoes = /obj/item/clothing/shoes/sandal/marisa
+ head = /obj/item/clothing/head/wizard/marisa
diff --git a/code/datums/ruins/space.dm b/code/datums/ruins/space.dm
index 45b0f5302f7..792dc4ea462 100644
--- a/code/datums/ruins/space.dm
+++ b/code/datums/ruins/space.dm
@@ -99,6 +99,13 @@
treasure in this disused warehouse, launch it into space, and then \
ignore it. Forever."
+/datum/map_template/ruin/space/listeningpost
+ id = "listeningpost"
+ suffix = "listeningpost.dmm"
+ name = "Syndie Listening Post"
+ description = "What happens to Nuclear Operatives that fail in their mission? \
+ Certainly not assignment to a backwater listening post..."
+
/datum/map_template/ruin/space/empty_shell
id = "empty-shell"
suffix = "emptyshell.dmm"
diff --git a/code/datums/spell.dm b/code/datums/spell.dm
index f48f6ca3fc7..d32d5bac058 100644
--- a/code/datums/spell.dm
+++ b/code/datums/spell.dm
@@ -100,7 +100,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
var/action_icon = 'icons/mob/actions.dmi'
var/action_icon_state = "spell_default"
var/action_background_icon_state = "bg_spell"
-
+
var/sound = null //The sound the spell makes when it is cast
/obj/effect/proc_holder/spell/proc/cast_check(skipcharge = 0, mob/living/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell
@@ -140,13 +140,13 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
var/obj/effect/proc_holder/spell/noclothes/clothes_spell = locate() in (user.mob_spell_list | (user.mind ? user.mind.spell_list : list()))
if((ishuman(user) && clothes_req) && !istype(clothes_spell))//clothes check
var/mob/living/carbon/human/H = user
- if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe) && !istype(H.wear_suit, /obj/item/clothing/suit/space/rig/wizard))
+ if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe) && !istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit/wizard))
to_chat(user, "I don't feel strong enough without my robe.")
return 0
if(!istype(H.shoes, /obj/item/clothing/shoes/sandal))
to_chat(user, "I don't feel strong enough without my sandals.")
return 0
- if(!istype(H.head, /obj/item/clothing/head/wizard) && !istype(H.head, /obj/item/clothing/head/helmet/space/rig/wizard))
+ if(!istype(H.head, /obj/item/clothing/head/wizard) && !istype(H.head, /obj/item/clothing/head/helmet/space/hardsuit/wizard))
to_chat(user, "I don't feel strong enough without my hat.")
return 0
else if(!ishuman(user))
@@ -184,8 +184,8 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
user.visible_message(invocation, invocation_emote_self) //same style as in mob/living/emote.dm
/obj/effect/proc_holder/spell/proc/playMagSound()
- playsound(get_turf(usr), sound,50,1)
-
+ playsound(get_turf(usr), sound,50,1)
+
/obj/effect/proc_holder/spell/New()
..()
action = new(src)
@@ -194,8 +194,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
charge_counter = charge_max
/obj/effect/proc_holder/spell/Destroy()
- qdel(action)
- action = null
+ QDEL_NULL(action)
return ..()
/obj/effect/proc_holder/spell/Click()
@@ -223,10 +222,10 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
spawn(0)
if(charge_type == "recharge" && recharge)
start_recharge()
-
+
if(sound)
- playMagSound()
-
+ playMagSound()
+
if(prob(critfailchance))
critfail(targets)
else
@@ -442,11 +441,11 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
var/clothcheck = locate(/obj/effect/proc_holder/spell/noclothes) in user.mob_spell_list
var/clothcheck2 = user.mind && (locate(/obj/effect/proc_holder/spell/noclothes) in user.mind.spell_list)
if(clothes_req && !clothcheck && !clothcheck2) //clothes check
- if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe) && !istype(H.wear_suit, /obj/item/clothing/suit/space/rig/wizard))
+ if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe) && !istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit/wizard))
return 0
if(!istype(H.shoes, /obj/item/clothing/shoes/sandal))
return 0
- if(!istype(H.head, /obj/item/clothing/head/wizard) && !istype(H.head, /obj/item/clothing/head/helmet/space/rig/wizard))
+ if(!istype(H.head, /obj/item/clothing/head/wizard) && !istype(H.head, /obj/item/clothing/head/helmet/space/hardsuit/wizard))
return 0
else
if(clothes_req || human_req)
diff --git a/code/datums/spells/charge.dm b/code/datums/spells/charge.dm
index 1551dbc3b68..7f9a02bc01a 100644
--- a/code/datums/spells/charge.dm
+++ b/code/datums/spells/charge.dm
@@ -26,9 +26,9 @@
if(M.mind)
for(var/obj/effect/proc_holder/spell/S in M.mind.spell_list)
S.charge_counter = S.charge_max
- to_chat(M, "you feel raw magic flowing through you, it feels good!")
+ to_chat(M, "You feel raw magical energy flowing through you, it feels good!")
else
- to_chat(M, "you feel very strange for a moment, but then it passes.")
+ to_chat(M, "You feel very strange for a moment, but then it passes.")
burnt_out = 1
charged_item = M
break
@@ -62,11 +62,12 @@
break
else if(istype(item, /obj/item/weapon/stock_parts/cell/))
var/obj/item/weapon/stock_parts/cell/C = item
- if(prob(80))
- C.maxcharge -= 200
- if(C.maxcharge <= 1) //Div by 0 protection
- C.maxcharge = 1
- burnt_out = 1
+ if(!C.self_recharge)
+ if(prob(80))
+ C.maxcharge -= 200
+ if(C.maxcharge <= 1) //Div by 0 protection
+ C.maxcharge = 1
+ burnt_out = 1
C.charge = C.maxcharge
charged_item = C
break
@@ -75,17 +76,18 @@
for(I in item.contents)
if(istype(I, /obj/item/weapon/stock_parts/cell/))
var/obj/item/weapon/stock_parts/cell/C = I
- if(prob(80))
- C.maxcharge -= 200
- if(C.maxcharge <= 1) //Div by 0 protection
- C.maxcharge = 1
- burnt_out = 1
+ if(!C.self_recharge)
+ if(prob(80))
+ C.maxcharge -= 200
+ if(C.maxcharge <= 1) //Div by 0 protection
+ C.maxcharge = 1
+ burnt_out = 1
C.charge = C.maxcharge
item.update_icon()
charged_item = item
break
if(!charged_item)
- to_chat(L, "you feel magical power surging to your hands, but the feeling rapidly fades...")
+ to_chat(L, "You feel magical power surging to your hands, but the feeling rapidly fades...")
else if(burnt_out)
to_chat(L, "[charged_item] doesn't seem to be reacting to the spell...")
else
diff --git a/code/datums/spells/conjure.dm b/code/datums/spells/conjure.dm
index fe0ffd9c1c0..ebf9fa59fe8 100644
--- a/code/datums/spells/conjure.dm
+++ b/code/datums/spells/conjure.dm
@@ -23,7 +23,7 @@
targets -= T
playsound(get_turf(src), cast_sound, 50, 1)
- if(do_after(user,delay, target = user))
+ if(do_after(user, delay, target = user))
for(var/i=0,iYou can't build things on shuttles!")
break
var/turf/O = spawn_place
var/N = summoned_object_type
diff --git a/code/datums/spells/lightning.dm b/code/datums/spells/lightning.dm
index bb2bb133d71..257e98346d2 100644
--- a/code/datums/spells/lightning.dm
+++ b/code/datums/spells/lightning.dm
@@ -15,13 +15,15 @@
var/image/halo = null
action_icon_state = "lightning"
var/sound/Snd // so far only way i can think of to stop a sound, thank MSO for the idea.
+ var/damaging = TRUE
/obj/effect/proc_holder/spell/targeted/lightning/lightnian
clothes_req = 0
invocation_type = "none"
+ damaging = 0
/obj/effect/proc_holder/spell/targeted/lightning/Click()
- if(!ready && start_time==0)
+ if(!ready && start_time == 0)
if(cast_check())
StartChargeup()
else
@@ -32,12 +34,12 @@
/obj/effect/proc_holder/spell/targeted/lightning/proc/StartChargeup(mob/user = usr)
ready = 1
to_chat(user, "You start gathering the power.")
- Snd = new/sound('sound/magic/lightning_chargeup.ogg',channel = 7)
+ Snd = new/sound('sound/magic/lightning_chargeup.ogg', channel = 7)
halo = image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = EFFECTS_LAYER)
user.overlays.Add(halo)
playsound(get_turf(user), Snd, 50, 0)
start_time = world.time
- if(do_mob(user,user,100,uninterruptible=1))
+ if(do_mob(user, user, 100, uninterruptible=1))
if(ready)
Discharge()
@@ -61,9 +63,9 @@ obj/effect/proc_holder/spell/targeted/lightning/proc/Reset(mob/user = usr)
/obj/effect/proc_holder/spell/targeted/lightning/cast(list/targets, mob/user = usr)
ready = 0
- var/mob/living/carbon/target = targets[1]
- Snd=sound(null, repeat = 0, wait = 1, channel = Snd.channel) //byond, why you suck?
- playsound(get_turf(user),Snd,50,0)// Sorry MrPerson, but the other ways just didn't do it the way i needed to work, this is the only way.
+ var/mob/living/target = targets[1]
+ Snd = sound(null, repeat = 0, wait = 1, channel = Snd.channel) //byond, why you suck?
+ playsound(get_turf(user), Snd, 50, 0)// Sorry MrPerson, but the other ways just didn't do it the way i needed to work, this is the only way.
if(get_dist(user,target)>range)
to_chat(user, "They are too far away!")
Reset(user)
@@ -73,17 +75,37 @@ obj/effect/proc_holder/spell/targeted/lightning/proc/Reset(mob/user = usr)
user.Beam(target,icon_state="lightning[rand(1,12)]",icon='icons/effects/effects.dmi',time=5)
var/energy = min(world.time - start_time,100)
- Bolt(user,target,max(15,energy/2),5,user) //5 bounces for energy/2 burn
+ if(damaging)
+ Bolt(user,target,max(15,energy/2),5,user) //5 bounces for energy/2 burn
+ else
+ var/bounces = round(energy/20)
+ Bolt(user,target,0,bounces,user)
Reset(user)
-/obj/effect/proc_holder/spell/targeted/lightning/proc/Bolt(mob/origin, mob/target, bolt_energy, bounces, mob/user = usr)
- origin.Beam(target,icon_state="lightning[rand(1,12)]",icon='icons/effects/effects.dmi',time=5)
- var/mob/living/carbon/current = target
+/obj/effect/proc_holder/spell/targeted/lightning/proc/Bolt(mob/origin, mob/living/target, bolt_energy, bounces, mob/user = usr)
+ origin.Beam(target,icon_state="lightning[rand(1,12)]", icon='icons/effects/effects.dmi', time=5)
+ var/mob/living/current = target
if(bounces < 1)
- current.electrocute_act(bolt_energy,"Lightning Bolt",safety=1)
+ if(damaging)
+ current.electrocute_act(bolt_energy,"Lightning Bolt",safety=1)
+ else
+ current.AdjustJitter(1000) //High numbers for violent convulsions
+ current.do_jitter_animation(current.jitteriness)
+ current.AdjustStuttering(2)
+ current.Slowed(3)
+ spawn(20)
+ current.AdjustJitter(-1000, bound_lower = 10) //Still jittery, but vastly less
playsound(get_turf(current), 'sound/magic/LightningShock.ogg', 50, 1, -1)
else
- current.electrocute_act(bolt_energy,"Lightning Bolt",safety=1)
+ if(damaging)
+ current.electrocute_act(bolt_energy,"Lightning Bolt",safety=1)
+ else
+ current.AdjustJitter(1000) //High numbers for violent convulsions
+ current.do_jitter_animation(current.jitteriness)
+ current.AdjustStuttering(2)
+ current.Slowed(3)
+ spawn(20)
+ current.AdjustJitter(-1000, bound_lower = 10) //Still jittery, but vastly less
playsound(get_turf(current), 'sound/magic/LightningShock.ogg', 50, 1, -1)
var/list/possible_targets = new
for(var/mob/living/M in view_or_range(range,target,"view"))
diff --git a/code/datums/spells/magnet.dm b/code/datums/spells/magnet.dm
index 100dd881dde..8a6e9c525c4 100644
--- a/code/datums/spells/magnet.dm
+++ b/code/datums/spells/magnet.dm
@@ -12,34 +12,37 @@
random_target = 1
var/energy = 0
var/ready = 0
+ var/start_time = 0
var/image/halo = null
+ var/sound/Snd // so far only way i can think of to stop a sound, thank MSO for the idea.
action_icon_state = "tech"
/obj/effect/proc_holder/spell/targeted/magnet/Click()
- if(!ready)
+ if(!ready && start_time == 0)
if(cast_check())
StartChargeup()
else
- if(cast_check(skipcharge=1))
+ if(ready && cast_check(skipcharge=1))
choose_targets()
return 1
/obj/effect/proc_holder/spell/targeted/magnet/proc/StartChargeup(mob/user = usr)
ready = 1
to_chat(user, "You start gathering the power.")
+ Snd = new/sound('sound/magic/lightning_chargeup.ogg', channel = 7)
halo = image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = EFFECTS_LAYER)
user.overlays.Add(halo)
- spawn(0)
- while(ready)
- sleep(1)
- energy++
- if(energy >= 100 && ready)
- Discharge()
+ playsound(get_turf(user), Snd, 50, 0)
+ start_time = world.time
+ if(do_mob(user, user, 100, uninterruptible=1))
+ if(ready)
+ Discharge()
obj/effect/proc_holder/spell/targeted/magnet/proc/Reset(mob/user = usr)
ready = 0
energy = 0
+ start_time = 0
if(halo)
user.overlays.Remove(halo)
@@ -50,16 +53,16 @@ obj/effect/proc_holder/spell/targeted/magnet/proc/Reset(mob/user = usr)
/obj/effect/proc_holder/spell/targeted/magnet/proc/Discharge(mob/user = usr)
var/mob/living/M = user
- //M.electrocute_act(25,"magnet Bolt")
to_chat(M, "You lose control over the power.")
Reset(user)
start_recharge()
/obj/effect/proc_holder/spell/targeted/magnet/cast(list/targets, mob/user = usr)
-
- var/mob/living/carbon/target = targets[1]
-
+ ready = 0
+ var/mob/living/target = targets[1]
+ Snd = sound(null, repeat = 0, wait = 1, channel = Snd.channel) //byond, why you suck?
+ playsound(get_turf(user), Snd, 50, 0)// Sorry MrPerson, but the other ways just didn't do it the way i needed to work, this is the only way.
if(get_dist(user,target)>range)
to_chat(user, "They are too far away!")
Reset(user)
@@ -88,13 +91,13 @@ obj/effect/proc_holder/spell/targeted/magnet/proc/Reset(mob/user = usr)
playsound(get_turf(target), 'sound/machines/defib_zap.ogg', 50, 1, -1)
if(75 to 100)
//CHAIN magnet
- Bolt(user,target,energy,user)
+ Bolt(user,target,energy,5,user)
Reset(user)
-/obj/effect/proc_holder/spell/targeted/magnet/proc/Bolt(mob/origin,mob/target,bolt_energy,mob/user = usr)
- origin.Beam(target,icon_state="lightning",icon='icons/effects/effects.dmi',time=5)
+/obj/effect/proc_holder/spell/targeted/magnet/proc/Bolt(mob/origin,mob/target,bolt_energy,bounces, mob/user = usr)
+ origin.Beam(target, icon_state="lightning", icon='icons/effects/effects.dmi', time=5)
var/mob/living/carbon/current = target
- if(bolt_energy < 75)
+ if(bounces < 1)
for(var/obj/item/I in target.l_hand)
if(I.flags & CONDUCT)
I.throw_at(user, I.throw_range, 4, target)
@@ -119,4 +122,4 @@ obj/effect/proc_holder/spell/targeted/magnet/proc/Reset(mob/user = usr)
return
var/mob/living/next = pick(possible_targets)
if(next)
- Bolt(current,next,bolt_energy-6,user) // 5 max bounces
\ No newline at end of file
+ Bolt(current,next,bolt_energy,bounces-1,user) // 5 max bounces
\ No newline at end of file
diff --git a/code/datums/spells/rod_form.dm b/code/datums/spells/rod_form.dm
index 004daf8969e..e51a994b7d2 100644
--- a/code/datums/spells/rod_form.dm
+++ b/code/datums/spells/rod_form.dm
@@ -11,10 +11,13 @@
invocation_type = "shout"
action_icon_state = "immrod"
+ sound = 'sound/effects/whoosh.ogg'
+ var/rod_delay = 2
+
/obj/effect/proc_holder/spell/targeted/rod_form/cast(list/targets,mob/user = usr)
for(var/mob/living/M in targets)
var/turf/start = get_turf(M)
- var/obj/effect/immovablerod/wizard/W = new(start, get_ranged_target_turf(M, M.dir, (15 + spell_level * 3)))
+ var/obj/effect/immovablerod/wizard/W = new(start, get_ranged_target_turf(M, M.dir, (15 + spell_level * 3)), rod_delay)
W.wizard = M
W.max_distance += spell_level * 3 //You travel farther when you upgrade the spell
W.start_turf = start
diff --git a/code/datums/spells/wizard.dm b/code/datums/spells/wizard.dm
index e3892baac2f..f8394771263 100644
--- a/code/datums/spells/wizard.dm
+++ b/code/datums/spells/wizard.dm
@@ -45,7 +45,7 @@
clothes_req = 1
invocation = "BIRUZ BENNAR"
invocation_type = "shout"
- message = "\blue You feel strong! You feel a pressure building behind your eyes!"
+ message = "You feel strong! You feel a pressure building behind your eyes!"
range = -1
include_user = 1
centcom_cancast = 0
@@ -235,7 +235,7 @@
clothes_req = 0
invocation = "STI KALY"
invocation_type = "whisper"
- message = "\blue Your eyes cry out in pain!"
+ message = "Your eyes cry out in pain!"
cooldown_min = 50 //12 deciseconds reduction per rank
starting_spells = list("/obj/effect/proc_holder/spell/targeted/inflict_handler/blind","/obj/effect/proc_holder/spell/targeted/genetic/blind")
diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm
index dab251125a7..4e624696a10 100644
--- a/code/datums/supplypacks.dm
+++ b/code/datums/supplypacks.dm
@@ -376,9 +376,9 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
/////// Implants & etc
-/datum/supply_packs/security/armory/loyalty
+/datum/supply_packs/security/armory/mindshield
name = "Mindshield Implants Crate"
- contains = list (/obj/item/weapon/storage/lockbox/loyalty)
+ contains = list (/obj/item/weapon/storage/lockbox/mindshield)
cost = 40
containername = "mindshield implant crate"
@@ -1149,6 +1149,13 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
cost = 10
containername = "glass sheets crate"
+/datum/supply_packs/materials/wood30
+ name = "30 Wood Planks Crate"
+ contains = list(/obj/item/stack/sheet/wood)
+ amount = 30
+ cost = 15
+ containername = "wood planks crate"
+
/datum/supply_packs/materials/cardboard50
name = "50 Cardboard Sheets Crate"
contains = list(/obj/item/stack/sheet/cardboard)
@@ -1166,7 +1173,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
/datum/supply_packs/materials/plastic30
name = "30 Plastic Sheets Crate"
- contains = list(/obj/item/stack/sheet/mineral/plastic)
+ contains = list(/obj/item/stack/sheet/plastic)
amount = 30
cost = 25
containername = "plastic sheets crate"
@@ -1408,6 +1415,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
/obj/item/clothing/head/collectable/flatcap,
/obj/item/clothing/head/collectable/pirate,
/obj/item/clothing/head/collectable/kitty,
+ /obj/item/clothing/head/crown/fancy,
/obj/item/clothing/head/collectable/rabbitears,
/obj/item/clothing/head/collectable/wizard,
/obj/item/clothing/head/collectable/hardhat,
@@ -1527,9 +1535,9 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
/obj/item/weapon/beach_ball)
cost = 20
containername = "polo supply crate"
-
-///////////// Station Goals
-
+
+///////////// Station Goals
+
/datum/supply_packs/misc/bsa
name = "Bluespace Artillery Parts"
cost = 150
diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm
index d54311921fd..1cf08abebd0 100644
--- a/code/datums/uplink_item.dm
+++ b/code/datums/uplink_item.dm
@@ -319,7 +319,7 @@ var/list/uplink_items = list()
cost = 6
job = list("Life Support Specialist")
-/datum/uplink_item/dangerous/energizedfireaxe
+/datum/uplink_item/jobspecific/energizedfireaxe
name = "Energized Fire Axe"
desc = "A fire axe with a massive electrical charge built into it. It can release this charge on its first victim and will be rather plain after that."
reference = "EFA"
@@ -347,6 +347,18 @@ var/list/uplink_items = list()
cost = 2
job = list("Research Director","Chief Medical Officer","Medical Doctor","Psychiatrist","Paramedic","Virologist","Bartender")
+// Paper contact poison pen
+
+/datum/uplink_item/jobspecific/poison_pen
+ name = "Poison Pen"
+ desc = "Cutting edge of deadly writing implements technology, this gadget will infuse any piece of paper with delayed contact poison."
+ reference = "PP"
+ item = /obj/item/weapon/pen/poison
+ cost = 2
+ excludefrom = list(/datum/game_mode/nuclear)
+ job = list("Head of Personnel", "Quartermaster", "Cargo Technician")
+
+
// DANGEROUS WEAPONS
/datum/uplink_item/dangerous
diff --git a/code/datums/vr.dm b/code/datums/vr.dm
new file mode 100644
index 00000000000..4d31b6a2072
--- /dev/null
+++ b/code/datums/vr.dm
@@ -0,0 +1,15 @@
+/datum/map_template/vr
+ name = null
+ var/id = null // For blacklisting purposes, all vr levels need an id
+ var/description = "This is a placeholder. Please contact your virtual adminsitrator if you see this."
+ var/outfit = null
+
+ var/prefix = null
+ var/suffix = null
+
+/datum/map_template/vr/New()
+ if(!name && id)
+ name = id
+
+ mappath = prefix + suffix
+ ..(path = mappath)
\ No newline at end of file
diff --git a/code/datums/vr/level.dm b/code/datums/vr/level.dm
new file mode 100644
index 00000000000..d3feca26ad9
--- /dev/null
+++ b/code/datums/vr/level.dm
@@ -0,0 +1,16 @@
+/datum/map_template/vr/level
+ prefix = "_maps/map_files/vr/"
+
+/datum/map_template/vr/level/lobby
+ id = "lobby"
+ suffix = "lobby.dmm"
+ name = "Virtual Hub Facility"
+ description = "This is the lobby. The hub for all things VR."
+ outfit = /datum/outfit/vr/vr_basic
+
+/datum/map_template/vr/level/roman
+ id = "roman"
+ suffix = "blood_and_sand.dmm"
+ name = "Blood and Sand Arena"
+ description = "To the Death!"
+ outfit = /datum/outfit/vr/roman
\ No newline at end of file
diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm
index 8fb989a8a4f..29bcf5a2160 100644
--- a/code/datums/wires/airlock.dm
+++ b/code/datums/wires/airlock.dm
@@ -6,24 +6,55 @@
/datum/wires/airlock
holder_type = /obj/machinery/door/airlock
wire_count = 12
+ window_x = 410
window_y = 570
var/const/AIRLOCK_WIRE_IDSCAN = 1
var/const/AIRLOCK_WIRE_MAIN_POWER1 = 2
-var/const/AIRLOCK_WIRE_MAIN_POWER2 = 4
-var/const/AIRLOCK_WIRE_DOOR_BOLTS = 8
-var/const/AIRLOCK_WIRE_BACKUP_POWER1 = 16
-var/const/AIRLOCK_WIRE_BACKUP_POWER2 = 32
-var/const/AIRLOCK_WIRE_OPEN_DOOR = 64
-var/const/AIRLOCK_WIRE_AI_CONTROL = 128
-var/const/AIRLOCK_WIRE_ELECTRIFY = 256
-var/const/AIRLOCK_WIRE_SAFETY = 512
-var/const/AIRLOCK_WIRE_SPEED = 1024
-var/const/AIRLOCK_WIRE_LIGHT = 2048
+var/const/AIRLOCK_WIRE_DOOR_BOLTS = 4
+var/const/AIRLOCK_WIRE_BACKUP_POWER1 = 8
+var/const/AIRLOCK_WIRE_OPEN_DOOR = 16
+var/const/AIRLOCK_WIRE_AI_CONTROL = 32
+var/const/AIRLOCK_WIRE_ELECTRIFY = 64
+var/const/AIRLOCK_WIRE_SAFETY = 128
+var/const/AIRLOCK_WIRE_SPEED = 256
+var/const/AIRLOCK_WIRE_LIGHT = 512
-/datum/wires/airlock/CanUse(var/mob/living/L)
+/datum/wires/airlock/GetWireName(index)
+ switch(index)
+ if(AIRLOCK_WIRE_IDSCAN)
+ return "ID Scan"
+
+ if(AIRLOCK_WIRE_MAIN_POWER1)
+ return "Primary Power"
+
+ if(AIRLOCK_WIRE_DOOR_BOLTS)
+ return "Door Bolts"
+
+ if(AIRLOCK_WIRE_BACKUP_POWER1)
+ return "Primary Backup Power"
+
+ if(AIRLOCK_WIRE_OPEN_DOOR)
+ return "Door State"
+
+ if(AIRLOCK_WIRE_AI_CONTROL)
+ return "AI Control"
+
+ if(AIRLOCK_WIRE_ELECTRIFY)
+ return "Electrification"
+
+ if(AIRLOCK_WIRE_ELECTRIFY)
+ return "Door Safeties"
+
+ if(AIRLOCK_WIRE_ELECTRIFY)
+ return "Door Timing"
+
+ if(AIRLOCK_WIRE_ELECTRIFY)
+ return "Bolt Lights"
+
+/datum/wires/airlock/CanUse(mob/living/L)
var/obj/machinery/door/airlock/A = holder
- if(!istype(L, /mob/living/silicon))
+ if(!issilicon(L))
if(A.isElectrified())
if(A.shock(L, 100))
return 0
@@ -31,26 +62,26 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
return 1
return 0
-/datum/wires/airlock/GetInteractWindow()
+/datum/wires/airlock/get_status()
+ . = ..()
var/obj/machinery/door/airlock/A = holder
var/haspower = A.arePowerSystemsOn()
- . += ..()
- . += text(" \n[] \n[] \n[] \n[] \n[] \n[] \n[]",
- (A.locked ? "The door bolts have fallen!" : "The door bolts look up."),
- ((A.lights && haspower) ? "The door bolt lights are on." : "The door bolt lights are off!"),
- ((haspower) ? "The test light is on." : "The test light is off!"),
- ((A.aiControlDisabled==0 && !A.emagged && haspower) ? "The 'AI control allowed' light is on." : "The 'AI control allowed' light is off."),
- ((A.safe==0 && haspower) ? "The 'Check Wiring' light is on." : "The 'Check Wiring' light is off."),
- ((A.normalspeed==0 && haspower) ? "The 'Check Timing Mechanism' light is on." : "The 'Check Timing Mechanism' light is off."),
- ((A.emergency && haspower) ? "The emergency lights are on." : "The emergency lights are off."))
-/datum/wires/airlock/UpdateCut(var/index, var/mended)
+ . += "The door bolts [A.locked ? "have fallen!" : "look up."]"
+ . += "The door bolt lights are [(A.lights && haspower) ? "on." : "off!"]"
+ . += "The test light is [haspower ? "on." : "off!"]"
+ . += "The 'AI control allowed' light is [(A.aiControlDisabled == 0 && !A.emagged && haspower) ? "on" : "off"]."
+ . += "The 'Check Wiring' light is [(A.safe == 0 && haspower) ? "on" : "off"]."
+ . += "The 'Check Timing Mechanism' light is [(A.normalspeed == 0 && haspower) ? "on" : "off"]."
+ . += "The emergency lights are [(A.emergency && haspower) ? "on" : "off"]."
+
+/datum/wires/airlock/UpdateCut(index, mended)
var/obj/machinery/door/airlock/A = holder
switch(index)
if(AIRLOCK_WIRE_IDSCAN)
A.aiDisabledIdScanner = !mended
- if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2)
+ if(AIRLOCK_WIRE_MAIN_POWER1)
if(!mended)
//Cutting either one disables the main door power, but unless backup power is also cut, the backup power re-powers the door in 10 seconds. While unpowered, the door may be crowbarred open, but bolts-raising will not work. Cutting these wires may electocute the user.
@@ -60,7 +91,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
A.regainMainPower()
A.shock(usr, 50)
- if(AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2)
+ if(AIRLOCK_WIRE_BACKUP_POWER1)
if(!mended)
//Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user.
@@ -113,8 +144,9 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
if(AIRLOCK_WIRE_LIGHT)
A.lights = mended
A.update_icon()
+ ..()
-/datum/wires/airlock/UpdatePulsed(var/index)
+/datum/wires/airlock/UpdatePulsed(index)
var/obj/machinery/door/airlock/A = holder
switch(index)
@@ -125,7 +157,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
if(A.emergency)
A.emergency = 0
A.update_icon()
- if(AIRLOCK_WIRE_MAIN_POWER1 || AIRLOCK_WIRE_MAIN_POWER2)
+ if(AIRLOCK_WIRE_MAIN_POWER1)
//Sending a pulse through either one causes a breaker to trip, disabling the door for 10 seconds if backup power is connected, or 1 minute if not (or until backup power comes back on, whichever is shorter).
A.loseMainPower()
if(AIRLOCK_WIRE_DOOR_BOLTS)
@@ -136,7 +168,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
else
A.unlock()
- if(AIRLOCK_WIRE_BACKUP_POWER1 || AIRLOCK_WIRE_BACKUP_POWER2)
+ if(AIRLOCK_WIRE_BACKUP_POWER1)
//two wires for backup power. Sending a pulse through either one causes a breaker to trip, but this does not disable it unless main power is down too (in which case it is disabled for 1 minute or however long it takes main power to come back, whichever is shorter).
A.loseBackupPower()
if(AIRLOCK_WIRE_AI_CONTROL)
@@ -176,4 +208,6 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
if(AIRLOCK_WIRE_LIGHT)
A.lights = !A.lights
- A.update_icon()
\ No newline at end of file
+ A.update_icon()
+
+ ..()
\ No newline at end of file
diff --git a/code/datums/wires/alarm.dm b/code/datums/wires/alarm.dm
index a31d075ecc7..f412e96b5ee 100644
--- a/code/datums/wires/alarm.dm
+++ b/code/datums/wires/alarm.dm
@@ -9,19 +9,37 @@ var/const/AALARM_WIRE_SYPHON = 4
var/const/AALARM_WIRE_AI_CONTROL = 8
var/const/AALARM_WIRE_AALARM = 16
+/datum/wires/alarm/GetWireName(index)
+ switch(index)
+ if(AALARM_WIRE_IDSCAN)
+ return "ID Scan"
+
+ if(AALARM_WIRE_POWER)
+ return "Power"
+
+ if(AALARM_WIRE_SYPHON)
+ return "Syphon"
+
+ if(AALARM_WIRE_AI_CONTROL)
+ return "AI Control"
+
+ if(AALARM_WIRE_AALARM)
+ return "Atmospherics Alarm"
-/datum/wires/alarm/CanUse(var/mob/living/L)
+/datum/wires/alarm/CanUse(mob/living/L)
var/obj/machinery/alarm/A = holder
if(A.wiresexposed)
return 1
return 0
-/datum/wires/alarm/GetInteractWindow()
+/datum/wires/alarm/get_status()
+ . = ..()
var/obj/machinery/alarm/A = holder
- . += ..()
- . += text(" \n[(A.locked ? "The Air Alarm is locked." : "The Air Alarm is unlocked.")] \n[((A.shorted || (A.stat & (NOPOWER|BROKEN))) ? "The Air Alarm is offline." : "The Air Alarm is working properly!")] \n[(A.aidisabled ? "The 'AI control allowed' light is off." : "The 'AI control allowed' light is on.")]")
+ . += "The Air Alarm is [A.locked ? "" : "un"]locked."
+ . += "The Air Alarm is [(A.shorted || (A.stat & (NOPOWER|BROKEN))) ? "offline." : "working properly!"]"
+ . += "The 'AI control allowed' light is [A.aidisabled ? "off" : "on"]."
-/datum/wires/alarm/UpdateCut(var/index, var/mended)
+/datum/wires/alarm/UpdateCut(index, mended)
var/obj/machinery/alarm/A = holder
switch(index)
if(AALARM_WIRE_IDSCAN)
@@ -50,8 +68,9 @@ var/const/AALARM_WIRE_AALARM = 16
if(A.alarm_area.atmosalert(2, A))
A.post_alert(2)
A.update_icon()
+ ..()
-/datum/wires/alarm/UpdatePulsed(var/index)
+/datum/wires/alarm/UpdatePulsed(index)
var/obj/machinery/alarm/A = holder
switch(index)
if(AALARM_WIRE_IDSCAN)
@@ -92,3 +111,4 @@ var/const/AALARM_WIRE_AALARM = 16
if(A.alarm_area.atmosalert(0, A))
A.post_alert(0)
A.update_icon()
+ ..()
diff --git a/code/datums/wires/apc.dm b/code/datums/wires/apc.dm
index ff566bb7e6d..a1ef61513fb 100644
--- a/code/datums/wires/apc.dm
+++ b/code/datums/wires/apc.dm
@@ -7,19 +7,35 @@ var/const/APC_WIRE_MAIN_POWER1 = 2
var/const/APC_WIRE_MAIN_POWER2 = 4
var/const/APC_WIRE_AI_CONTROL = 8
-/datum/wires/apc/GetInteractWindow()
+/datum/wires/apc/GetWireName(index)
+ switch(index)
+ if(APC_WIRE_IDSCAN)
+ return "ID Scan"
+
+ if(APC_WIRE_MAIN_POWER1)
+ return "Primary Power"
+
+ if(APC_WIRE_MAIN_POWER2)
+ return "Secondary Power"
+
+ if(APC_WIRE_AI_CONTROL)
+ return "AI Control"
+
+/datum/wires/apc/get_status()
+ . = ..()
var/obj/machinery/power/apc/A = holder
- . += ..()
- . += text(" \n[(A.locked ? "The APC is locked." : "The APC is unlocked.")] \n[(A.shorted ? "The APCs power has been shorted." : "The APC is working properly!")] \n[(A.aidisabled ? "The 'AI control allowed' light is off." : "The 'AI control allowed' light is on.")]")
+ . += "The APC is [A.locked ? "" : "un"]locked."
+ . += A.shorted ? "The APCs power has been shorted." : "The APC is working properly!"
+ . += "The 'AI control allowed' light is [A.aidisabled ? "off" : "on"]."
-/datum/wires/apc/CanUse(var/mob/living/L)
+/datum/wires/apc/CanUse(mob/living/L)
var/obj/machinery/power/apc/A = holder
if(A.wiresexposed)
return 1
return 0
-/datum/wires/apc/UpdatePulsed(var/index)
+/datum/wires/apc/UpdatePulsed(index)
var/obj/machinery/power/apc/A = holder
@@ -51,9 +67,9 @@ var/const/APC_WIRE_AI_CONTROL = 8
A.aidisabled = 0
A.updateDialog()
- A.updateDialog()
+ ..()
-/datum/wires/apc/UpdateCut(var/index, var/mended)
+/datum/wires/apc/UpdateCut(index, mended)
var/obj/machinery/power/apc/A = holder
switch(index)
@@ -75,4 +91,4 @@ var/const/APC_WIRE_AI_CONTROL = 8
else
if(A.aidisabled == 1)
A.aidisabled = 0
- A.updateDialog()
\ No newline at end of file
+ ..()
\ No newline at end of file
diff --git a/code/datums/wires/autolathe.dm b/code/datums/wires/autolathe.dm
index 77a8ce6c03c..644a472acf3 100644
--- a/code/datums/wires/autolathe.dm
+++ b/code/datums/wires/autolathe.dm
@@ -1,5 +1,4 @@
/datum/wires/autolathe
-
holder_type = /obj/machinery/autolathe
wire_count = 10
@@ -7,10 +6,23 @@ var/const/AUTOLATHE_HACK_WIRE = 1
var/const/AUTOLATHE_SHOCK_WIRE = 2
var/const/AUTOLATHE_DISABLE_WIRE = 4
-/datum/wires/autolathe/GetInteractWindow()
+/datum/wires/autolathe/GetWireName(index)
+ switch(index)
+ if(AUTOLATHE_HACK_WIRE)
+ return "Hack"
+
+ if(AUTOLATHE_SHOCK_WIRE)
+ return "Shock"
+
+ if(AUTOLATHE_DISABLE_WIRE)
+ return "Disable"
+
+/datum/wires/autolathe/get_status()
+ . = ..()
var/obj/machinery/autolathe/A = holder
- . += ..()
- . += text(" The red light is [A.disabled ? "off" : "on"]. The green light is [A.shocked ? "off" : "on"]. The blue light is [A.hacked ? "off" : "on"]. ")
+ . += "The red light is [A.disabled ? "off" : "on"]."
+ . += "The green light is [A.shocked ? "off" : "on"]."
+ . += "The blue light is [A.hacked ? "off" : "on"]."
/datum/wires/autolathe/CanUse()
var/obj/machinery/autolathe/A = holder
@@ -18,11 +30,6 @@ var/const/AUTOLATHE_DISABLE_WIRE = 4
return 1
return 0
-/datum/wires/autolathe/Interact(var/mob/living/user)
- if(CanUse(user))
- var/obj/machinery/autolathe/V = holder
- V.attack_hand(user)
-
/datum/wires/autolathe/UpdateCut(index, mended)
var/obj/machinery/autolathe/A = holder
switch(index)
@@ -32,6 +39,7 @@ var/const/AUTOLATHE_DISABLE_WIRE = 4
A.shocked = !mended
if(AUTOLATHE_DISABLE_WIRE)
A.disabled = !mended
+ ..()
/datum/wires/autolathe/UpdatePulsed(index)
if(IsIndexCut(index))
@@ -40,19 +48,27 @@ var/const/AUTOLATHE_DISABLE_WIRE = 4
switch(index)
if(AUTOLATHE_HACK_WIRE)
A.adjust_hacked(!A.hacked)
+ updateUIs()
spawn(50)
if(A && !IsIndexCut(index))
A.adjust_hacked(0)
- Interact(usr)
+ updateUIs()
if(AUTOLATHE_SHOCK_WIRE)
A.shocked = !A.shocked
+ updateUIs()
spawn(50)
if(A && !IsIndexCut(index))
A.shocked = 0
- Interact(usr)
+ updateUIs()
if(AUTOLATHE_DISABLE_WIRE)
A.disabled = !A.disabled
+ updateUIs()
spawn(50)
if(A && !IsIndexCut(index))
A.disabled = 0
- Interact(usr)
\ No newline at end of file
+ updateUIs()
+
+/datum/wires/autolathe/proc/updateUIs()
+ nanomanager.update_uis(src)
+ if(holder)
+ nanomanager.update_uis(holder)
\ No newline at end of file
diff --git a/code/datums/wires/camera.dm b/code/datums/wires/camera.dm
index f6ffd2ed427..ee25f8c3898 100644
--- a/code/datums/wires/camera.dm
+++ b/code/datums/wires/camera.dm
@@ -5,17 +5,15 @@
holder_type = /obj/machinery/camera
wire_count = 6
-/datum/wires/camera/GetInteractWindow()
-
+/datum/wires/camera/get_status()
. = ..()
var/obj/machinery/camera/C = holder
- . += " \n[(C.view_range == initial(C.view_range) ? "The focus light is on." : "The focus light is off.")]"
- . += " \n[(C.can_use() ? "The power link light is on." : "The power link light is off.")]"
- . += " \n[(C.light_disabled ? "The camera light is off." : "The camera light is on.")]"
- . += " \n[(C.alarm_on ? "The alarm light is on." : "The alarm light is off.")]"
- return .
+ . += "The focus light is [(C.view_range == initial(C.view_range)) ? "on" : "off"]."
+ . += "The power link light is [C.can_use() ? "on" : "off"]."
+ . += "The camera light is [C.light_disabled ? "off" : "on"]."
+ . += "The alarm light is [C.alarm_on ? "on" : "off"]."
-/datum/wires/camera/CanUse(var/mob/living/L)
+/datum/wires/camera/CanUse(mob/living/L)
var/obj/machinery/camera/C = holder
if(!C.panel_open)
return 0
@@ -28,7 +26,27 @@ var/const/CAMERA_WIRE_ALARM = 8
var/const/CAMERA_WIRE_NOTHING1 = 16
var/const/CAMERA_WIRE_NOTHING2 = 32
-/datum/wires/camera/UpdateCut(var/index, var/mended)
+/datum/wires/camera/GetWireName(index)
+ switch(index)
+ if(CAMERA_WIRE_FOCUS)
+ return "Focus"
+
+ if(CAMERA_WIRE_POWER)
+ return "Power"
+
+ if(CAMERA_WIRE_LIGHT)
+ return "Light"
+
+ if(CAMERA_WIRE_ALARM)
+ return "Alarm"
+
+ if(CAMERA_WIRE_NOTHING1)
+ return "Nothing"
+
+ if(CAMERA_WIRE_NOTHING2)
+ return "Nothing"
+
+/datum/wires/camera/UpdateCut(index, mended)
var/obj/machinery/camera/C = holder
switch(index)
@@ -48,9 +66,9 @@ var/const/CAMERA_WIRE_NOTHING2 = 32
C.triggerCameraAlarm()
else
C.cancelCameraAlarm()
- return
+ ..()
-/datum/wires/camera/UpdatePulsed(var/index)
+/datum/wires/camera/UpdatePulsed(index)
var/obj/machinery/camera/C = holder
if(IsIndexCut(index))
return
@@ -67,7 +85,7 @@ var/const/CAMERA_WIRE_NOTHING2 = 32
if(CAMERA_WIRE_ALARM)
C.visible_message("[bicon(C)] *beep*", "[bicon(C)] *beep*")
- return
+ ..()
/datum/wires/camera/proc/CanDeconstruct()
if(IsIndexCut(CAMERA_WIRE_POWER) && IsIndexCut(CAMERA_WIRE_FOCUS) && IsIndexCut(CAMERA_WIRE_LIGHT) && IsIndexCut(CAMERA_WIRE_NOTHING1) && IsIndexCut(CAMERA_WIRE_NOTHING2))
diff --git a/code/datums/wires/explosive.dm b/code/datums/wires/explosive.dm
index d653729dfd3..db397d63d42 100644
--- a/code/datums/wires/explosive.dm
+++ b/code/datums/wires/explosive.dm
@@ -3,27 +3,34 @@
var/const/WIRE_EXPLODE = 1
+/datum/wires/explosive/GetWireName(index)
+ switch(index)
+ if(WIRE_EXPLODE)
+ return "Explode"
+
/datum/wires/explosive/proc/explode()
return
-/datum/wires/explosive/UpdatePulsed(var/index)
+/datum/wires/explosive/UpdatePulsed(index)
switch(index)
if(WIRE_EXPLODE)
explode()
+ ..()
-/datum/wires/explosive/UpdateCut(var/index, var/mended)
+/datum/wires/explosive/UpdateCut(index, mended)
switch(index)
if(WIRE_EXPLODE)
if(!mended)
explode()
+ ..()
/datum/wires/explosive/gibtonite
holder_type = /obj/item/weapon/twohanded/required/gibtonite
-/datum/wires/explosive/gibtonite/CanUse(var/mob/living/L)
+/datum/wires/explosive/gibtonite/CanUse(mob/L)
return 1
-/datum/wires/explosive/gibtonite/UpdateCut(var/index, var/mended)
+/datum/wires/explosive/gibtonite/UpdateCut(index, mended)
return
/datum/wires/explosive/gibtonite/explode()
diff --git a/code/datums/wires/mulebot.dm b/code/datums/wires/mulebot.dm
index 7b59479720d..cbc92497f33 100644
--- a/code/datums/wires/mulebot.dm
+++ b/code/datums/wires/mulebot.dm
@@ -2,6 +2,7 @@
random = 1
holder_type = /mob/living/simple_animal/bot/mulebot
wire_count = 10
+ window_x = 410
var/const/WIRE_POWER1 = 1 // power connections
var/const/WIRE_POWER2 = 2
@@ -13,30 +14,54 @@ var/const/WIRE_REMOTE_RX = 64 // remote recv functions
var/const/WIRE_REMOTE_TX = 128 // remote trans status
var/const/WIRE_BEACON_RX = 256 // beacon ping recv
-/datum/wires/mulebot/CanUse(var/mob/living/L)
+/datum/wires/mulebot/GetWireName(index)
+ switch(index)
+ if(WIRE_POWER1)
+ return "Primary Power"
+
+ if(WIRE_POWER2)
+ return "Secondary Power"
+
+ if(WIRE_AVOIDANCE)
+ return "Mob Avoidance"
+
+ if(WIRE_LOADCHECK)
+ return "Load Checking"
+
+ if(WIRE_MOTOR1)
+ return "Primary Motor"
+
+ if(WIRE_MOTOR2)
+ return "Secondary Motor"
+
+ if(WIRE_REMOTE_RX)
+ return "Remote Signal Receiver"
+
+ if(WIRE_REMOTE_TX)
+ return "Remote Signal Sender"
+
+ if(WIRE_BEACON_RX)
+ return "Navigation Beacon Receiver"
+
+/datum/wires/mulebot/CanUse(mob/living/L)
var/mob/living/simple_animal/bot/mulebot/M = holder
if(M.open)
return 1
return 0
-// So the wires do not open a new window, handle the interaction ourselves.
-/datum/wires/mulebot/Interact(var/mob/living/user)
- if(CanUse(user))
- var/mob/living/simple_animal/bot/mulebot/M = holder
- M.interact(user)
-
-/datum/wires/mulebot/UpdatePulsed(var/index)
+/datum/wires/mulebot/UpdatePulsed(index)
switch(index)
if(WIRE_POWER1, WIRE_POWER2)
- holder.visible_message("\blue [bicon(holder)] The charge light flickers.")
+ holder.visible_message("[bicon(holder)] The charge light flickers.")
if(WIRE_AVOIDANCE)
- holder.visible_message("\blue [bicon(holder)] The external warning lights flash briefly.")
+ holder.visible_message("[bicon(holder)] The external warning lights flash briefly.")
if(WIRE_LOADCHECK)
- holder.visible_message("\blue [bicon(holder)] The load platform clunks.")
+ holder.visible_message("[bicon(holder)] The load platform clunks.")
if(WIRE_MOTOR1, WIRE_MOTOR2)
- holder.visible_message("\blue [bicon(holder)] The drive motor whines briefly.")
+ holder.visible_message("[bicon(holder)] The drive motor whines briefly.")
else
- holder.visible_message("\blue [bicon(holder)] You hear a radio crackle.")
+ holder.visible_message("[bicon(holder)] You hear a radio crackle.")
+ ..()
// HELPER PROCS
diff --git a/code/datums/wires/nuclearbomb.dm b/code/datums/wires/nuclearbomb.dm
index 0297bea8508..2034c59576b 100644
--- a/code/datums/wires/nuclearbomb.dm
+++ b/code/datums/wires/nuclearbomb.dm
@@ -7,53 +7,66 @@ var/const/NUCLEARBOMB_WIRE_LIGHT = 1
var/const/NUCLEARBOMB_WIRE_TIMING = 2
var/const/NUCLEARBOMB_WIRE_SAFETY = 4
-/datum/wires/nuclearbomb/CanUse(var/mob/living/L)
+/datum/wires/nuclearbomb/GetWireName(index)
+ switch(index)
+ if(NUCLEARBOMB_WIRE_LIGHT)
+ return "Bomb Light"
+
+ if(NUCLEARBOMB_WIRE_TIMING)
+ return "Bomb Timing"
+
+ if(NUCLEARBOMB_WIRE_SAFETY)
+ return "Bomb Safety"
+
+/datum/wires/nuclearbomb/CanUse(mob/living/L)
var/obj/machinery/nuclearbomb/N = holder
if(N.panel_open)
return 1
return 0
-/datum/wires/nuclearbomb/GetInteractWindow()
+/datum/wires/nuclearbomb/get_status()
+ . = ..()
var/obj/machinery/nuclearbomb/N = holder
- . += ..()
- . += " The device is [N.timing ? "shaking!" : "still."] "
- . += "The device is is [N.safety ? "quiet" : "whirring"]. "
- . += "The lights are [N.lighthack ? "static" : "functional"]. "
+ . += "The device is [N.timing ? "shaking!" : "still."]"
+ . += "The device is is [N.safety ? "quiet" : "whirring"]."
+ . += "The lights are [N.lighthack ? "static" : "functional"]."
-/datum/wires/nuclearbomb/UpdatePulsed(var/index)
+/datum/wires/nuclearbomb/UpdatePulsed(index)
var/obj/machinery/nuclearbomb/N = holder
switch(index)
if(NUCLEARBOMB_WIRE_LIGHT)
N.lighthack = !N.lighthack
+ updateUIs()
spawn(100)
N.lighthack = !N.lighthack
+ updateUIs()
if(NUCLEARBOMB_WIRE_TIMING)
if(N.timing)
- spawn
- message_admins("[key_name_admin(usr)] pulsed a nuclear bomb's detonation wire, causing it to explode (JMP)")
- N.explode()
+ message_admins("[key_name_admin(usr)] pulsed a nuclear bomb's detonation wire, causing it to explode (JMP)")
+ N.explode()
if(NUCLEARBOMB_WIRE_SAFETY)
N.safety = !N.safety
+ updateUIs()
spawn(100)
N.safety = !N.safety
if(N.safety == 1)
if(!N.is_syndicate)
set_security_level(N.previous_level)
- N.visible_message("\blue The [N] quiets down.")
+ N.visible_message("The [N] quiets down.")
if(!N.lighthack)
if(N.icon_state == "nuclearbomb2")
N.icon_state = "nuclearbomb1"
else
- N.visible_message("\blue The [N] emits a quiet whirling noise!")
-
-/datum/wires/nuclearbomb/UpdateCut(var/index, var/mended)
+ N.visible_message("The [N] emits a quiet whirling noise!")
+ updateUIs()
+
+/datum/wires/nuclearbomb/UpdateCut(index, mended)
var/obj/machinery/nuclearbomb/N = holder
switch(index)
if(NUCLEARBOMB_WIRE_SAFETY)
if(N.timing)
- spawn
- message_admins("[key_name_admin(usr)] cut a nuclear bomb's timing wire, causing it to explode (JMP)")
- N.explode()
+ message_admins("[key_name_admin(usr)] cut a nuclear bomb's timing wire, causing it to explode (JMP)")
+ N.explode()
if(NUCLEARBOMB_WIRE_TIMING)
if(!N.lighthack)
if(N.icon_state == "nuclearbomb2")
@@ -62,3 +75,8 @@ var/const/NUCLEARBOMB_WIRE_SAFETY = 4
bomb_set = 0
if(NUCLEARBOMB_WIRE_LIGHT)
N.lighthack = !N.lighthack
+
+/datum/wires/nuclearbomb/proc/updateUIs()
+ nanomanager.update_uis(src)
+ if(holder)
+ nanomanager.update_uis(holder)
\ No newline at end of file
diff --git a/code/datums/wires/particle_accelerator.dm b/code/datums/wires/particle_accelerator.dm
index 53a166a79e7..1ed68b799f4 100644
--- a/code/datums/wires/particle_accelerator.dm
+++ b/code/datums/wires/particle_accelerator.dm
@@ -6,15 +6,28 @@ var/const/PARTICLE_TOGGLE_WIRE = 1 // Toggles whether the PA is on or not.
var/const/PARTICLE_STRENGTH_WIRE = 2 // Determines the strength of the PA.
var/const/PARTICLE_INTERFACE_WIRE = 4 // Determines the interface showing up.
var/const/PARTICLE_LIMIT_POWER_WIRE = 8 // Determines how strong the PA can be.
-//var/const/PARTICLE_NOTHING_WIRE = 16 // Blank wire
-/datum/wires/particle_acc/control_box/CanUse(var/mob/living/L)
+/datum/wires/particle_acc/control_box/GetWireName(index)
+ switch(index)
+ if(PARTICLE_TOGGLE_WIRE)
+ return "Power Toggle"
+
+ if(PARTICLE_STRENGTH_WIRE)
+ return "Strength"
+
+ if(PARTICLE_INTERFACE_WIRE)
+ return "Interface"
+
+ if(PARTICLE_LIMIT_POWER_WIRE)
+ return "Maximum Power"
+
+/datum/wires/particle_acc/control_box/CanUse(mob/living/L)
var/obj/machinery/particle_accelerator/control_box/C = holder
if(C.construction_state == 2)
return 1
return 0
-/datum/wires/particle_acc/control_box/UpdatePulsed(var/index)
+/datum/wires/particle_acc/control_box/UpdatePulsed(index)
var/obj/machinery/particle_accelerator/control_box/C = holder
switch(index)
@@ -29,8 +42,9 @@ var/const/PARTICLE_LIMIT_POWER_WIRE = 8 // Determines how strong the PA can be.
if(PARTICLE_LIMIT_POWER_WIRE)
C.visible_message("[bicon(C)][C] makes a large whirring noise.")
+ ..()
-/datum/wires/particle_acc/control_box/UpdateCut(var/index, var/mended)
+/datum/wires/particle_acc/control_box/UpdateCut(index, mended)
var/obj/machinery/particle_accelerator/control_box/C = holder
switch(index)
@@ -49,4 +63,5 @@ var/const/PARTICLE_LIMIT_POWER_WIRE = 8 // Determines how strong the PA can be.
if(PARTICLE_LIMIT_POWER_WIRE)
C.strength_upper_limit = (mended ? 2 : 3)
if(C.strength_upper_limit < C.strength)
- C.remove_strength()
\ No newline at end of file
+ C.remove_strength()
+ ..()
\ No newline at end of file
diff --git a/code/datums/wires/radio.dm b/code/datums/wires/radio.dm
index 6c2fb9713da..ffbff381060 100644
--- a/code/datums/wires/radio.dm
+++ b/code/datums/wires/radio.dm
@@ -6,13 +6,24 @@ var/const/WIRE_SIGNAL = 1
var/const/WIRE_RECEIVE = 2
var/const/WIRE_TRANSMIT = 4
-/datum/wires/radio/CanUse(var/mob/living/L)
+/datum/wires/radio/GetWireName(index)
+ switch(index)
+ if(WIRE_SIGNAL)
+ return "Signal"
+
+ if(WIRE_RECEIVE)
+ return "Receiver"
+
+ if(WIRE_TRANSMIT)
+ return "Transmitter"
+
+/datum/wires/radio/CanUse(mob/living/L)
var/obj/item/device/radio/R = holder
if(R.b_stat)
return 1
return 0
-/datum/wires/radio/UpdatePulsed(var/index)
+/datum/wires/radio/UpdatePulsed(index)
var/obj/item/device/radio/R = holder
switch(index)
if(WIRE_SIGNAL)
@@ -24,8 +35,9 @@ var/const/WIRE_TRANSMIT = 4
if(WIRE_TRANSMIT)
R.broadcasting = !R.broadcasting && !IsIndexCut(WIRE_SIGNAL)
+ ..()
-/datum/wires/radio/UpdateCut(var/index, var/mended)
+/datum/wires/radio/UpdateCut(index, mended)
var/obj/item/device/radio/R = holder
switch(index)
if(WIRE_SIGNAL)
@@ -37,3 +49,4 @@ var/const/WIRE_TRANSMIT = 4
if(WIRE_TRANSMIT)
R.broadcasting = mended && !IsIndexCut(WIRE_SIGNAL)
+ ..()
diff --git a/code/datums/wires/robot.dm b/code/datums/wires/robot.dm
index 082cdd9d6d6..bc03e80c327 100644
--- a/code/datums/wires/robot.dm
+++ b/code/datums/wires/robot.dm
@@ -19,16 +19,32 @@ var/const/BORG_WIRE_CAMERA = 4
var/const/BORG_WIRE_AI_CONTROL = 8 // Not used on MoMMIs
var/const/BORG_WIRE_LAWCHECK = 16 // Not used on MoMMIs
-/datum/wires/robot/GetInteractWindow()
+/datum/wires/robot/GetWireName(index)
+ switch(index)
+ if(BORG_WIRE_MAIN_POWER)
+ return "Main Power"
+
+ if(BORG_WIRE_LOCKED_DOWN)
+ return "Lockdown"
+
+ if(BORG_WIRE_CAMERA)
+ return "Camera"
+
+ if(BORG_WIRE_AI_CONTROL)
+ return "AI Control"
+
+ if(BORG_WIRE_LAWCHECK)
+ return "Law Check"
+/datum/wires/robot/get_status()
. = ..()
var/mob/living/silicon/robot/R = holder
- . += text(" \n[(R.lawupdate ? "The LawSync light is on." : "The LawSync light is off.")] \n[(R.connected_ai ? "The AI link light is on." : "The AI link light is off.")]")
- . += text(" \n[((!isnull(R.camera) && R.camera.status == 1) ? "The Camera light is on." : "The Camera light is off.")] \n")
- . += text(" \n[(R.lockcharge ? "The lockdown light is on." : "The lockdown light is off.")]")
- return .
+ . += "The LawSync light is [R.lawupdate ? "on" : "off"]."
+ . += "The AI link light is [R.connected_ai ? "on" : "off"]."
+ . += "The Camera light is [(R.camera && R.camera.status == 1) ? "on" : "off"]."
+ . += "The lockdown light is [R.lockcharge ? "on" : "off"]."
-/datum/wires/robot/UpdateCut(var/index, var/mended)
+/datum/wires/robot/UpdateCut(index, mended)
var/mob/living/silicon/robot/R = holder
switch(index)
@@ -57,9 +73,10 @@ var/const/BORG_WIRE_LAWCHECK = 16 // Not used on MoMMIs
if(BORG_WIRE_LOCKED_DOWN)
R.SetLockdown(!mended)
+ ..()
-/datum/wires/robot/UpdatePulsed(var/index)
+/datum/wires/robot/UpdatePulsed(index)
var/mob/living/silicon/robot/R = holder
switch(index)
@@ -76,8 +93,9 @@ var/const/BORG_WIRE_LAWCHECK = 16 // Not used on MoMMIs
if(BORG_WIRE_LOCKED_DOWN)
R.SetLockdown(!R.lockcharge) // Toggle
+ ..()
-/datum/wires/robot/CanUse(var/mob/living/L)
+/datum/wires/robot/CanUse(mob/living/L)
var/mob/living/silicon/robot/R = holder
if(R.wiresexposed)
return 1
diff --git a/code/datums/wires/smartfridge.dm b/code/datums/wires/smartfridge.dm
index b611497e796..53b33e0fd72 100644
--- a/code/datums/wires/smartfridge.dm
+++ b/code/datums/wires/smartfridge.dm
@@ -10,9 +10,20 @@ var/const/SMARTFRIDGE_WIRE_ELECTRIFY = 1
var/const/SMARTFRIDGE_WIRE_THROW = 2
var/const/SMARTFRIDGE_WIRE_IDSCAN = 4
-/datum/wires/smartfridge/CanUse(var/mob/living/L)
+/datum/wires/smartfridge/GetWireName(index)
+ switch(index)
+ if(SMARTFRIDGE_WIRE_ELECTRIFY)
+ return "Electrification"
+
+ if(SMARTFRIDGE_WIRE_THROW)
+ return "Item Throw"
+
+ if(SMARTFRIDGE_WIRE_IDSCAN)
+ return "ID Scan"
+
+/datum/wires/smartfridge/CanUse(mob/living/L)
var/obj/machinery/smartfridge/S = holder
- if(!istype(L, /mob/living/silicon))
+ if(!issilicon(L))
if(S.seconds_electrified)
if(S.shock(L, 100))
return 0
@@ -20,14 +31,14 @@ var/const/SMARTFRIDGE_WIRE_IDSCAN = 4
return 1
return 0
-/datum/wires/smartfridge/GetInteractWindow()
+/datum/wires/smartfridge/get_status()
+ . = ..()
var/obj/machinery/smartfridge/S = holder
- . += ..()
- . += " The orange light is [S.seconds_electrified ? "off" : "on"]. "
- . += "The red light is [S.shoot_inventory ? "off" : "blinking"]. "
- . += "A [S.scan_id ? "purple" : "yellow"] light is on. "
+ . += "The orange light is [S.seconds_electrified ? "off" : "on"]."
+ . += "The red light is [S.shoot_inventory ? "off" : "blinking"]."
+ . += "A [S.scan_id ? "purple" : "yellow"] light is on."
-/datum/wires/smartfridge/UpdatePulsed(var/index)
+/datum/wires/smartfridge/UpdatePulsed(index)
var/obj/machinery/smartfridge/S = holder
switch(index)
if(SMARTFRIDGE_WIRE_THROW)
@@ -36,8 +47,9 @@ var/const/SMARTFRIDGE_WIRE_IDSCAN = 4
S.seconds_electrified = 30
if(SMARTFRIDGE_WIRE_IDSCAN)
S.scan_id = !S.scan_id
+ ..()
-/datum/wires/smartfridge/UpdateCut(var/index, var/mended)
+/datum/wires/smartfridge/UpdateCut(index, mended)
var/obj/machinery/smartfridge/S = holder
switch(index)
if(SMARTFRIDGE_WIRE_THROW)
@@ -49,3 +61,4 @@ var/const/SMARTFRIDGE_WIRE_IDSCAN = 4
S.seconds_electrified = -1
if(SMARTFRIDGE_WIRE_IDSCAN)
S.scan_id = 1
+ ..()
diff --git a/code/datums/wires/syndicatebomb.dm b/code/datums/wires/syndicatebomb.dm
index 3fa81883fce..d1fe6217058 100644
--- a/code/datums/wires/syndicatebomb.dm
+++ b/code/datums/wires/syndicatebomb.dm
@@ -9,14 +9,30 @@ var/const/WIRE_DELAY = 4 // Raises the timer on pulse, does nothing on cut
var/const/WIRE_PROCEED = 8 // Lowers the timer, explodes if cut while the bomb is active
var/const/WIRE_ACTIVATE = 16 // Will start a bombs timer if pulsed, will hint if pulsed while already active, will stop a timer a bomb on cut
+/datum/wires/syndicatebomb/GetWireName(index)
+ switch(index)
+ if(WIRE_BOOM)
+ return "Explode"
+
+ if(WIRE_UNBOLT)
+ return "Unbolt"
+
+ if(WIRE_DELAY)
+ return "Delay"
+
+ if(WIRE_PROCEED)
+ return "Proceed"
+
+ if(WIRE_ACTIVATE)
+ return "Activate"
-/datum/wires/syndicatebomb/CanUse(var/mob/living/L)
+/datum/wires/syndicatebomb/CanUse(mob/living/L)
var/obj/machinery/syndicatebomb/P = holder
if(P.open_panel)
return 1
return 0
-/datum/wires/syndicatebomb/UpdatePulsed(var/index)
+/datum/wires/syndicatebomb/UpdatePulsed(index)
var/obj/machinery/syndicatebomb/P = holder
switch(index)
if(WIRE_BOOM)
@@ -47,8 +63,9 @@ var/const/WIRE_ACTIVATE = 16 // Will start a bombs timer if pulsed, will hint if
else
P.loc.visible_message("[bicon(holder)] The bomb seems to hesitate for a moment.")
P.timer += 5
+ ..()
-/datum/wires/syndicatebomb/UpdateCut(var/index, var/mended)
+/datum/wires/syndicatebomb/UpdateCut(index, mended)
var/obj/machinery/syndicatebomb/P = holder
switch(index)
if(WIRE_EXPLODE)
@@ -58,7 +75,7 @@ var/const/WIRE_ACTIVATE = 16 // Will start a bombs timer if pulsed, will hint if
P.timer = 0
else
P.defused = 1
- if(mended)
+ else
P.defused = 0 //cutting and mending all the wires of an inactive bomb will thus cure any sabotage
if(WIRE_UNBOLT)
if(!mended && P.anchored)
@@ -74,4 +91,5 @@ var/const/WIRE_ACTIVATE = 16 // Will start a bombs timer if pulsed, will hint if
P.loc.visible_message("[bicon(holder)] The timer stops! The bomb has been defused!")
P.icon_state = "[initial(P.icon_state)]-inactive[P.open_panel ? "-wires" : ""]"
P.active = 0
- P.defused = 1
\ No newline at end of file
+ P.defused = 1
+ ..()
\ No newline at end of file
diff --git a/code/datums/wires/tesla_coil.dm b/code/datums/wires/tesla_coil.dm
new file mode 100644
index 00000000000..ed60e927f45
--- /dev/null
+++ b/code/datums/wires/tesla_coil.dm
@@ -0,0 +1,23 @@
+/datum/wires/tesla_coil
+ wire_count = 1
+ holder_type = /obj/machinery/power/tesla_coil
+
+var/const/WIRE_ZAP = 1
+
+/datum/wires/tesla_coil/GetWireName(index)
+ switch(index)
+ if(WIRE_ZAP)
+ return "Zap"
+
+/datum/wires/tesla_coil/CanUse(mob/living/L)
+ var/obj/machinery/power/tesla_coil/T = holder
+ if(T && T.panel_open)
+ return 1
+ return 0
+
+/datum/wires/tesla_coil/UpdatePulsed(index)
+ var/obj/machinery/power/tesla_coil/T = holder
+ switch(index)
+ if(WIRE_ZAP)
+ T.zap()
+ ..()
\ No newline at end of file
diff --git a/code/datums/wires/vending.dm b/code/datums/wires/vending.dm
index 574c7961e09..286ac454efc 100644
--- a/code/datums/wires/vending.dm
+++ b/code/datums/wires/vending.dm
@@ -9,7 +9,21 @@ var/const/VENDING_WIRE_CONTRABAND = 2
var/const/VENDING_WIRE_ELECTRIFY = 4
var/const/VENDING_WIRE_IDSCAN = 8
-/datum/wires/vending/CanUse(var/mob/living/L)
+/datum/wires/vending/GetWireName(index)
+ switch(index)
+ if(VENDING_WIRE_THROW)
+ return "Item Throw"
+
+ if(VENDING_WIRE_CONTRABAND)
+ return "Contraband"
+
+ if(VENDING_WIRE_ELECTRIFY)
+ return "Electrification"
+
+ if(VENDING_WIRE_IDSCAN)
+ return "ID Scan"
+
+/datum/wires/vending/CanUse(mob/living/L)
var/obj/machinery/vending/V = holder
if(!istype(L, /mob/living/silicon))
if(V.seconds_electrified)
@@ -19,15 +33,15 @@ var/const/VENDING_WIRE_IDSCAN = 8
return 1
return 0
-/datum/wires/vending/GetInteractWindow()
+/datum/wires/vending/get_status()
+ . = ..()
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.categories & CAT_HIDDEN) ? "on" : "off"]. "
- . += "A [V.scan_id ? "purple" : "yellow"] light is on. "
+ . += "The orange light is [V.seconds_electrified ? "on" : "off"]."
+ . += "The red light is [V.shoot_inventory ? "off" : "blinking"]."
+ . += "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)
+/datum/wires/vending/UpdatePulsed(index)
var/obj/machinery/vending/V = holder
switch(index)
if(VENDING_WIRE_THROW)
@@ -38,8 +52,9 @@ var/const/VENDING_WIRE_IDSCAN = 8
V.seconds_electrified = 30
if(VENDING_WIRE_IDSCAN)
V.scan_id = !V.scan_id
+ ..()
-/datum/wires/vending/UpdateCut(var/index, var/mended)
+/datum/wires/vending/UpdateCut(index, mended)
var/obj/machinery/vending/V = holder
switch(index)
if(VENDING_WIRE_THROW)
@@ -52,4 +67,5 @@ var/const/VENDING_WIRE_IDSCAN = 8
else
V.seconds_electrified = -1
if(VENDING_WIRE_IDSCAN)
- V.scan_id = 1
\ No newline at end of file
+ V.scan_id = 1
+ ..()
\ No newline at end of file
diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm
index 6d8866640e4..a8baf7ad2fb 100644
--- a/code/datums/wires/wires.dm
+++ b/code/datums/wires/wires.dm
@@ -26,7 +26,7 @@ var/list/wireColours = list("red", "blue", "green", "black", "orange", "brown",
var/window_x = 370
var/window_y = 470
-/datum/wires/New(var/atom/holder)
+/datum/wires/New(atom/holder)
..()
src.holder = holder
if(!istype(holder, holder_type))
@@ -68,106 +68,110 @@ var/list/wireColours = list("red", "blue", "green", "black", "orange", "brown",
src.wires[colour] = index
//wires = shuffle(wires)
+/datum/wires/proc/get_status()
+ return list()
-/datum/wires/proc/Interact(var/mob/living/user)
+/datum/wires/proc/Interact(mob/user)
+ if(user && istype(user) && holder && CanUse(user))
+ ui_interact(user)
- var/html = null
- if(holder && CanUse(user))
- html = GetInteractWindow()
- if(html)
- user.set_machine(holder)
- 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))
- popup.open()
+/datum/wires/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "wires.tmpl", holder.name, window_x, window_y)
+ ui.open()
-/datum/wires/proc/GetInteractWindow()
- var/html = "
"
- html += "
Exposed Wires
"
- html += "
"
+/datum/wires/ui_data(mob/user, ui_key = "main", datum/topic_state/state = physical_state)
+ var/data[0]
+ var/list/W[0]
for(var/colour in wires)
- html += "
"
+ W[++W.len] = list("colour" = capitalize(colour), "cut" = IsColourCut(colour), "index" = can_see_wire_index(user) ? GetWireName(GetIndex(colour)) : null, "attached" = IsAttached(colour))
- return html
+ if(W.len > 0)
+ data["wires"] = W
+
+ var/list/status = get_status()
+ data["status_len"] = status.len
+ data["status"] = status
+
+ return data
+
+/datum/wires/nano_host()
+ return holder
+
+/datum/wires/proc/can_see_wire_index(mob/user)
+ if(user.can_admin_interact())
+ return TRUE
+ else if(istype(user.get_active_hand(), /obj/item/device/multitool))
+ var/obj/item/device/multitool/M = user.get_active_hand()
+ if(M.shows_wire_information)
+ return TRUE
+
+ return FALSE
/datum/wires/Topic(href, href_list)
- ..()
- if(in_range(holder, usr) && isliving(usr))
+ if(..())
+ return 1
- var/mob/living/L = usr
- if(CanUse(L) && href_list["action"])
- var/obj/item/I = L.get_active_hand()
- holder.add_hiddenprint(L)
- if(href_list["cut"]) // Toggles the cut/mend status
- if(istype(I, /obj/item/weapon/wirecutters))
- playsound(holder, 'sound/items/Wirecutter.ogg', 20, 1)
- var/colour = href_list["cut"]
+ var/mob/L = usr
+ if(CanUse(L) && href_list["action"])
+ var/obj/item/I = L.get_active_hand()
+ var/colour = lowertext(href_list["wire"])
+ holder.add_hiddenprint(L)
+ switch(href_list["action"])
+ if("cut") // Toggles the cut/mend status
+ if(istype(I, /obj/item/weapon/wirecutters) || L.can_admin_interact())
+ if(istype(I))
+ playsound(holder, I.usesound, 20, 1)
CutWireColour(colour)
else
to_chat(L, "You need wirecutters!")
-
- else if(href_list["pulse"])
- if(istype(I, /obj/item/device/multitool))
+ if("pulse")
+ if(istype(I, /obj/item/device/multitool) || L.can_admin_interact())
playsound(holder, 'sound/weapons/empty.ogg', 20, 1)
- var/colour = href_list["pulse"]
PulseColour(colour)
else
to_chat(L, "You need a multitool!")
-
- else if(href_list["attach"])
- var/colour = href_list["attach"]
- // Detach
+ if("attach")
if(IsAttached(colour))
var/obj/item/O = Detach(colour)
if(O)
L.put_in_hands(O)
-
- // Attach
else
if(istype(I, /obj/item/device/assembly/signaler))
- L.drop_item()
- Attach(colour, I)
+ if(L.drop_item())
+ Attach(colour, I)
+ else
+ to_chat(L, "[L.get_active_hand()] is stuck to your hand!")
else
to_chat(L, "You need a remote signaller!")
-
-
-
- // Update Window
- Interact(usr)
-
- if(href_list["close"])
- usr << browse(null, "window=wires")
- usr.unset_machine(holder)
+ nanomanager.update_uis(src)
+ return 1
//
// Overridable Procs
//
// Called when wires cut/mended.
-/datum/wires/proc/UpdateCut(var/index, var/mended)
- return
+/datum/wires/proc/UpdateCut(index, mended)
+ if(holder)
+ nanomanager.update_uis(holder)
// Called when wire pulsed. Add code here.
-/datum/wires/proc/UpdatePulsed(var/index)
- return
+/datum/wires/proc/UpdatePulsed(index)
+ if(holder)
+ nanomanager.update_uis(holder)
-/datum/wires/proc/CanUse(var/mob/living/L)
+/datum/wires/proc/CanUse(mob/L)
return 1
+/datum/wires/CanUseTopic(mob/user, datum/topic_state/state)
+ if(!CanUse(user))
+ return STATUS_CLOSE
+ return ..()
+
// Example of use:
/*
@@ -194,47 +198,50 @@ var/const/POWER = 8
// Helper Procs
//
-/datum/wires/proc/PulseColour(var/colour)
+/datum/wires/proc/PulseColour(colour)
PulseIndex(GetIndex(colour))
-/datum/wires/proc/PulseIndex(var/index)
+/datum/wires/proc/PulseIndex(index)
if(IsIndexCut(index))
return
UpdatePulsed(index)
-/datum/wires/proc/GetIndex(var/colour)
+/datum/wires/proc/GetIndex(colour)
if(wires[colour])
var/index = wires[colour]
return index
else
CRASH("[colour] is not a key in wires.")
+
+/datum/wires/proc/GetWireName(index)
+ return
//
// Is Index/Colour Cut procs
//
-/datum/wires/proc/IsColourCut(var/colour)
+/datum/wires/proc/IsColourCut(colour)
var/index = GetIndex(colour)
return IsIndexCut(index)
-/datum/wires/proc/IsIndexCut(var/index)
+/datum/wires/proc/IsIndexCut(index)
return (index & wires_status)
//
// Signaller Procs
//
-/datum/wires/proc/IsAttached(var/colour)
+/datum/wires/proc/IsAttached(colour)
if(signallers[colour])
return 1
return 0
-/datum/wires/proc/GetAttached(var/colour)
+/datum/wires/proc/GetAttached(colour)
if(signallers[colour])
return signallers[colour]
return null
-/datum/wires/proc/Attach(var/colour, var/obj/item/device/assembly/signaler/S)
+/datum/wires/proc/Attach(colour, obj/item/device/assembly/signaler/S)
if(colour && S)
if(!IsAttached(colour))
signallers[colour] = S
@@ -242,7 +249,7 @@ var/const/POWER = 8
S.connected = src
return S
-/datum/wires/proc/Detach(var/colour)
+/datum/wires/proc/Detach(colour)
if(colour)
var/obj/item/device/assembly/signaler/S = GetAttached(colour)
if(S)
@@ -252,7 +259,7 @@ var/const/POWER = 8
return S
-/datum/wires/proc/Pulse(var/obj/item/device/assembly/signaler/S)
+/datum/wires/proc/Pulse(obj/item/device/assembly/signaler/S)
for(var/colour in signallers)
if(S == signallers[colour])
@@ -264,11 +271,11 @@ var/const/POWER = 8
// Cut Wire Colour/Index procs
//
-/datum/wires/proc/CutWireColour(var/colour)
+/datum/wires/proc/CutWireColour(colour)
var/index = GetIndex(colour)
CutWireIndex(index)
-/datum/wires/proc/CutWireIndex(var/index)
+/datum/wires/proc/CutWireIndex(index)
if(IsIndexCut(index))
wires_status &= ~index
UpdateCut(index, 1)
diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm
index 8ec413450b0..e814bc9081f 100644
--- a/code/game/area/Space Station 13 areas.dm
+++ b/code/game/area/Space Station 13 areas.dm
@@ -17,7 +17,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area
var/fire = null
- var/atmosalm = 0
+ var/atmosalm = ATMOS_ALARM_NONE
var/poweralm = 1
var/party = null
var/radalert = 0
@@ -57,7 +57,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
var/tele_proof = 0
var/no_teleportlocs = 0
-
+
var/outdoors = 0 //For space, the asteroid, lavaland, etc. Used with blueprints to determine if we are adding a new area (vs editing a station room)
/*Adding a wizard area teleport list because motherfucking lag -- Urist*/
@@ -1039,7 +1039,7 @@ var/list/ghostteleportlocs = list()
/area/bridge/meeting_room
name = "\improper Heads of Staff Meeting Room"
- icon_state = "bridge"
+ icon_state = "meeting"
music = null
/area/crew_quarters/captain
@@ -1875,6 +1875,10 @@ area/security/podbay
name = "\improper Toxins Mixing Room"
icon_state = "toxmix"
+/area/toxins/launch
+ name = "Toxins Launch Room"
+ icon_state = "toxlaunch"
+
/area/toxins/misc_lab
name = "\improper Research Testing Lab"
icon_state = "toxmisc"
@@ -2466,11 +2470,6 @@ area/security/podbay
/area/awaymission/spacebattle/secret
name = "\improper Hidden Chamber"
-/area/awaymission/listeningpost
- name = "\improper Listening Post"
- icon_state = "away"
- requires_power = 0
-
/area/awaymission/beach
name = "Beach"
icon_state = "beach"
@@ -2583,6 +2582,22 @@ area/security/podbay
/area/awaycontent/a30
icon_state = "awaycontent30"
+////////////////////////VR AREAS///////////////////////////////////
+
+/area/vr
+ name = "VR"
+ requires_power = 0
+ dynamic_lighting = 0
+ no_teleportlocs = 1
+
+
+/area/vr/lobby
+ name = "VR Lobby"
+
+/area/vr/roman
+ name = "Roman Arena"
+
+
/////////////////////////////////////////////////////////////////////
/*
Lists of areas to be used with is_type_in_list.
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index ec70d50c504..eb743afad62 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -53,7 +53,7 @@
/area/proc/atmosalert(danger_level, var/alarm_source)
- if(danger_level == 0)
+ if(danger_level == ATMOS_ALARM_NONE)
atmosphere_alarm.clearAlarm(src, alarm_source)
else
atmosphere_alarm.triggerAlarm(src, alarm_source, severity = danger_level)
@@ -64,10 +64,10 @@
danger_level = max(danger_level, AA.danger_level)
if(danger_level != atmosalm)
- if(danger_level < 1 && atmosalm >= 1)
+ if(danger_level < ATMOS_ALARM_WARNING && atmosalm >= ATMOS_ALARM_WARNING)
//closing the doors on red and opening on green provides a bit of hysteresis that will hopefully prevent fire doors from opening and closing repeatedly due to noise
air_doors_open()
- else if(danger_level >= 2 && atmosalm < 2)
+ else if(danger_level >= ATMOS_ALARM_DANGER && atmosalm < ATMOS_ALARM_DANGER)
air_doors_close()
atmosalm = danger_level
@@ -81,9 +81,10 @@
/area/proc/air_doors_close()
if(!air_doors_activated)
- air_doors_activated = 1
+ air_doors_activated = TRUE
for(var/obj/machinery/door/firedoor/D in src)
if(!D.welded)
+ D.activate_alarm()
if(D.operating)
D.nextstate = CLOSED
else if(!D.density)
@@ -92,9 +93,10 @@
/area/proc/air_doors_open()
if(air_doors_activated)
- air_doors_activated = 0
+ air_doors_activated = FALSE
for(var/obj/machinery/door/firedoor/D in src)
if(!D.welded)
+ D.deactivate_alarm()
if(D.operating)
D.nextstate = OPEN
else if(D.density)
diff --git a/code/game/asteroid.dm b/code/game/asteroid.dm
index 77c3179adf5..25e9f43b588 100644
--- a/code/game/asteroid.dm
+++ b/code/game/asteroid.dm
@@ -115,7 +115,7 @@ var/global/max_secret_rooms = 6
floortypes = list(/turf/simulated/floor,/turf/simulated/floor/wood)
treasureitems = list(/obj/item/weapon/melee/energy/sword/pirate=1,/obj/item/weapon/gun/projectile/revolver/doublebarrel=1,/obj/item/weapon/storage/backpack/satchel_flat=1,
/obj/machinery/reagentgrinder=2, /obj/machinery/computer/security/wooden_tv=4, /obj/machinery/vending/coffee=3)
- fluffitems = list(/obj/structure/table/woodentable=2,/obj/structure/reagent_dispensers/beerkeg=1,/obj/item/weapon/spacecash/c500=4,
+ fluffitems = list(/obj/structure/table/woodentable=2,/obj/structure/reagent_dispensers/beerkeg=1,/obj/item/stack/spacecash/c500=4,
/obj/item/weapon/reagent_containers/food/drinks/shaker=1,/obj/item/weapon/reagent_containers/food/drinks/bottle/wine=3,
/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey=3,/obj/item/clothing/shoes/laceup=2)
@@ -124,7 +124,7 @@ var/global/max_secret_rooms = 6
treasureitems = list(/obj/item/weapon/gun/energy/floragun=1,/obj/item/seeds/ambrosia/deus=2,/obj/item/seeds/tomato/blue/bluespace=2,/obj/item/seeds/tomato/blue=2,
/obj/item/seeds/coffee/robusta=2, /obj/item/seeds/tobacco/space=2)
fluffitems = list(/obj/item/weapon/twohanded/required/kirbyplants=1,/obj/structure/table/reinforced=2,/obj/machinery/hydroponics=1,
- /obj/effect/glowshroom/single=2,/obj/item/weapon/reagent_containers/syringe/charcoal=2,
+ /obj/structure/glowshroom/single=2,/obj/item/weapon/reagent_containers/syringe/charcoal=2,
/obj/item/weapon/reagent_containers/glass/bottle/diethylamine=3,/obj/item/weapon/reagent_containers/glass/bottle/ammonia=3)
/*if("poly")
@@ -194,7 +194,7 @@ var/global/max_secret_rooms = 6
A.fullUpdateMineralOverlays()
T = pick(emptyturfs)
if(T)
- new /obj/effect/glowshroom/single(T) //Just to make it a little more visible
+ new /obj/structure/glowshroom/single(T) //Just to make it a little more visible
var/surprise = null
surprise = pickweight(treasureitems)
new surprise(T)//here's the prize
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index a7d464fb9db..b5d25c7f5a1 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -76,12 +76,10 @@
qdel(AA)
alternate_appearances = null
- if(reagents)
- qdel(reagents)
- reagents = null
+ QDEL_NULL(reagents)
invisibility = 101
return ..()
-
+
//Hook for running code when a dir change occurs
/atom/proc/setDir(newdir)
dir = newdir
diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm
index 240c53b0025..2a6aa2b3a39 100644
--- a/code/game/data_huds.dm
+++ b/code/game/data_huds.dm
@@ -41,7 +41,7 @@
hud_icons = list(ID_HUD)
/datum/atom_hud/data/human/security/advanced
- hud_icons = list(ID_HUD, IMPTRACK_HUD, IMPLOYAL_HUD, IMPCHEM_HUD, WANTED_HUD)
+ hud_icons = list(ID_HUD, IMPTRACK_HUD, IMPMINDSHIELD_HUD, IMPCHEM_HUD, WANTED_HUD)
/datum/atom_hud/data/diagnostic
hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD)
@@ -172,7 +172,7 @@
/mob/living/carbon/human/proc/sec_hud_set_implants()
var/image/holder
- for(var/i in list(IMPTRACK_HUD, IMPLOYAL_HUD, IMPCHEM_HUD))
+ for(var/i in list(IMPTRACK_HUD, IMPMINDSHIELD_HUD, IMPCHEM_HUD))
holder = hud_list[i]
holder.icon_state = null
for(var/obj/item/weapon/implant/I in src)
@@ -180,8 +180,8 @@
if(istype(I,/obj/item/weapon/implant/tracking))
holder = hud_list[IMPTRACK_HUD]
holder.icon_state = "hud_imp_tracking"
- else if(istype(I,/obj/item/weapon/implant/loyalty))
- holder = hud_list[IMPLOYAL_HUD]
+ else if(istype(I,/obj/item/weapon/implant/mindshield))
+ holder = hud_list[IMPMINDSHIELD_HUD]
holder.icon_state = "hud_imp_loyal"
else if(istype(I,/obj/item/weapon/implant/chem))
holder = hud_list[IMPCHEM_HUD]
diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm
index 82f7ffb2e93..a9e0c49a122 100644
--- a/code/game/dna/dna2.dm
+++ b/code/game/dna/dna2.dm
@@ -20,37 +20,43 @@
#define DNA_UI_HAIR_R 1
#define DNA_UI_HAIR_G 2
#define DNA_UI_HAIR_B 3
-#define DNA_UI_BEARD_R 4
-#define DNA_UI_BEARD_G 5
-#define DNA_UI_BEARD_B 6
-#define DNA_UI_SKIN_TONE 7
-#define DNA_UI_SKIN_R 8
-#define DNA_UI_SKIN_G 9
-#define DNA_UI_SKIN_B 10
-#define DNA_UI_HACC_R 11
-#define DNA_UI_HACC_G 12
-#define DNA_UI_HACC_B 13
-#define DNA_UI_HEAD_MARK_R 14
-#define DNA_UI_HEAD_MARK_G 15
-#define DNA_UI_HEAD_MARK_B 16
-#define DNA_UI_BODY_MARK_R 17
-#define DNA_UI_BODY_MARK_G 18
-#define DNA_UI_BODY_MARK_B 19
-#define DNA_UI_TAIL_MARK_R 20
-#define DNA_UI_TAIL_MARK_G 21
-#define DNA_UI_TAIL_MARK_B 22
-#define DNA_UI_EYES_R 23
-#define DNA_UI_EYES_G 24
-#define DNA_UI_EYES_B 25
-#define DNA_UI_GENDER 26
-#define DNA_UI_BEARD_STYLE 27
-#define DNA_UI_HAIR_STYLE 28
+#define DNA_UI_HAIR2_R 4
+#define DNA_UI_HAIR2_G 5
+#define DNA_UI_HAIR2_B 6
+#define DNA_UI_BEARD_R 7
+#define DNA_UI_BEARD_G 8
+#define DNA_UI_BEARD_B 9
+#define DNA_UI_BEARD2_R 10
+#define DNA_UI_BEARD2_G 11
+#define DNA_UI_BEARD2_B 12
+#define DNA_UI_SKIN_TONE 13
+#define DNA_UI_SKIN_R 14
+#define DNA_UI_SKIN_G 15
+#define DNA_UI_SKIN_B 16
+#define DNA_UI_HACC_R 17
+#define DNA_UI_HACC_G 18
+#define DNA_UI_HACC_B 19
+#define DNA_UI_HEAD_MARK_R 20
+#define DNA_UI_HEAD_MARK_G 21
+#define DNA_UI_HEAD_MARK_B 22
+#define DNA_UI_BODY_MARK_R 23
+#define DNA_UI_BODY_MARK_G 24
+#define DNA_UI_BODY_MARK_B 25
+#define DNA_UI_TAIL_MARK_R 26
+#define DNA_UI_TAIL_MARK_G 27
+#define DNA_UI_TAIL_MARK_B 28
+#define DNA_UI_EYES_R 29
+#define DNA_UI_EYES_G 30
+#define DNA_UI_EYES_B 31
+#define DNA_UI_GENDER 32
+#define DNA_UI_BEARD_STYLE 33
+#define DNA_UI_HAIR_STYLE 34
/*#define DNA_UI_BACC_STYLE 23*/
-#define DNA_UI_HACC_STYLE 29
-#define DNA_UI_HEAD_MARK_STYLE 30
-#define DNA_UI_BODY_MARK_STYLE 31
-#define DNA_UI_TAIL_MARK_STYLE 32
-#define DNA_UI_LENGTH 32 // Update this when you add something, or you WILL break shit.
+#define DNA_UI_HACC_STYLE 35
+#define DNA_UI_HEAD_MARK_STYLE 36
+#define DNA_UI_BODY_MARK_STYLE 37
+#define DNA_UI_TAIL_MARK_STYLE 38
+#define DNA_UI_LENGTH 38 // Update this when you add something, or you WILL break shit.
#define DNA_SE_LENGTH 55 // Was STRUCDNASIZE, size 27. 15 new blocks added = 42, plus room to grow.
@@ -135,6 +141,7 @@ var/global/list/bad_blocks[0]
// FIXME: Species-specific defaults pls
var/obj/item/organ/external/head/H = character.get_organ("head")
var/obj/item/organ/internal/eyes/eyes_organ = character.get_int_organ(/obj/item/organ/internal/eyes)
+ var/datum/species/S = character.species
/*// Body Accessory
if(!character.body_accessory)
@@ -170,7 +177,11 @@ var/global/list/bad_blocks[0]
SetUIValueRange(DNA_UI_SKIN_TONE, 35-character.s_tone, 220, 1) // Value can be negative.
- SetUIState(DNA_UI_GENDER, character.gender!=MALE, 1)
+ if(S.has_gender)
+ SetUIState(DNA_UI_GENDER, character.gender!=MALE, 1)
+ else
+ SetUIState(DNA_UI_GENDER, pick(0,1), 1)
+
/*SetUIValueRange(DNA_UI_BACC_STYLE, bodyacc, facial_hair_styles_list.len, 1)*/
SetUIValueRange(DNA_UI_HEAD_MARK_STYLE, head_marks, marking_styles_list.len, 1)
SetUIValueRange(DNA_UI_BODY_MARK_STYLE, body_marks, marking_styles_list.len, 1)
@@ -426,3 +437,7 @@ var/global/list/bad_blocks[0]
species = data["species"]
b_type = data["b_type"]
real_name = data["real_name"]
+
+// a nice hook for if/when we refactor species on dna
+/datum/dna/proc/get_species_name()
+ return species
diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm
index e5af89c3d25..c5f9ce2b7fe 100644
--- a/code/game/dna/dna2_helpers.dm
+++ b/code/game/dna/dna2_helpers.dm
@@ -22,27 +22,27 @@
// Give Random Bad Mutation to M
/proc/randmutb(var/mob/living/M)
- if(!M) return
+ if(!M || !M.dna) return
M.dna.check_integrity()
var/block = pick(bad_blocks)
M.dna.SetSEState(block, 1)
// Give Random Good Mutation to M
/proc/randmutg(var/mob/living/M)
- if(!M) return
+ if(!M || !M.dna) return
M.dna.check_integrity()
var/block = pick(good_blocks)
M.dna.SetSEState(block, 1)
// Random Appearance Mutation
/proc/randmuti(var/mob/living/M)
- if(!M) return
+ if(!M || !M.dna) return
M.dna.check_integrity()
M.dna.SetUIValue(rand(1,DNA_UI_LENGTH),rand(1,4095))
// Scramble UI or SE.
/proc/scramble(var/UI, var/mob/M, var/prob)
- if(!M) return
+ if(!M || !M.dna) return
M.dna.check_integrity()
if(UI)
for(var/i = 1, i <= DNA_UI_LENGTH-1, i++)
@@ -132,7 +132,11 @@
dna.check_integrity()
var/mob/living/carbon/human/H = src
var/obj/item/organ/external/head/head_organ = H.get_organ("head")
+ var/obj/item/organ/internal/eyes/eye_organ = H.get_int_organ(/obj/item/organ/internal/eyes)
+ var/datum/species/S = H.species
dna.write_head_attributes(head_organ)
+ dna.write_eyes_attributes(eye_organ)
+ H.update_eyes()
H.r_skin = dna.GetUIValueRange(DNA_UI_SKIN_R, 255)
H.g_skin = dna.GetUIValueRange(DNA_UI_SKIN_G, 255)
@@ -144,10 +148,11 @@
H.s_tone = 35 - dna.GetUIValueRange(DNA_UI_SKIN_TONE, 220) // Value can be negative.
- if(dna.GetUIState(DNA_UI_GENDER))
- H.change_gender(FEMALE, 0)
- else
- H.change_gender(MALE, 0)
+ if(S.has_gender)
+ if(dna.GetUIState(DNA_UI_GENDER))
+ H.change_gender(FEMALE, 0)
+ else
+ H.change_gender(MALE, 0)
//Head Markings
var/head_marks = dna.GetUIValueRange(DNA_UI_HEAD_MARK_STYLE, marking_styles_list.len)
@@ -188,6 +193,10 @@
head_organ.g_hair = GetUIValueRange(DNA_UI_HAIR_G, 255)
head_organ.b_hair = GetUIValueRange(DNA_UI_HAIR_B, 255)
+ head_organ.r_hair_sec = GetUIValueRange(DNA_UI_HAIR2_R, 255)
+ head_organ.g_hair_sec = GetUIValueRange(DNA_UI_HAIR2_G, 255)
+ head_organ.b_hair_sec = GetUIValueRange(DNA_UI_HAIR2_B, 255)
+
//Facial Hair
var/beard = GetUIValueRange(DNA_UI_BEARD_STYLE,facial_hair_styles_list.len)
if((beard > 0) && (beard <= facial_hair_styles_list.len))
@@ -197,6 +206,10 @@
head_organ.g_facial = GetUIValueRange(DNA_UI_BEARD_G, 255)
head_organ.b_facial = GetUIValueRange(DNA_UI_BEARD_B, 255)
+ head_organ.r_facial_sec = GetUIValueRange(DNA_UI_BEARD2_R, 255)
+ head_organ.g_facial_sec = GetUIValueRange(DNA_UI_BEARD2_G, 255)
+ head_organ.b_facial_sec = GetUIValueRange(DNA_UI_BEARD2_B, 255)
+
//Head Accessories
var/headacc = GetUIValueRange(DNA_UI_HACC_STYLE,head_accessory_styles_list.len)
if((headacc > 0) && (headacc <= head_accessory_styles_list.len))
@@ -254,10 +267,18 @@
SetUIValueRange(DNA_UI_HAIR_G, H.g_hair, 255, 1)
SetUIValueRange(DNA_UI_HAIR_B, H.b_hair, 255, 1)
+ SetUIValueRange(DNA_UI_HAIR2_R, H.r_hair_sec, 255, 1)
+ SetUIValueRange(DNA_UI_HAIR2_G, H.g_hair_sec, 255, 1)
+ SetUIValueRange(DNA_UI_HAIR2_B, H.b_hair_sec, 255, 1)
+
SetUIValueRange(DNA_UI_BEARD_R, H.r_facial, 255, 1)
SetUIValueRange(DNA_UI_BEARD_G, H.g_facial, 255, 1)
SetUIValueRange(DNA_UI_BEARD_B, H.b_facial, 255, 1)
+ SetUIValueRange(DNA_UI_BEARD2_R, H.r_facial_sec, 255, 1)
+ SetUIValueRange(DNA_UI_BEARD2_G, H.g_facial_sec, 255, 1)
+ SetUIValueRange(DNA_UI_BEARD2_B, H.b_facial_sec, 255, 1)
+
SetUIValueRange(DNA_UI_HACC_R, H.r_headacc, 255, 1)
SetUIValueRange(DNA_UI_HACC_G, H.g_headacc, 255, 1)
SetUIValueRange(DNA_UI_HACC_B, H.b_headacc, 255, 1)
diff --git a/code/game/dna/genes/goon_powers.dm b/code/game/dna/genes/goon_powers.dm
index e4c09aeac17..49a5ac8b016 100644
--- a/code/game/dna/genes/goon_powers.dm
+++ b/code/game/dna/genes/goon_powers.dm
@@ -180,7 +180,7 @@
C.adjustFireLoss(10)
C.ExtinguishMob()
- C.visible_message("\red [user] sprays a cloud of fine ice crystals, engulfing [C]!")
+ C.visible_message("[user] sprays a cloud of fine ice crystals, engulfing [C]!")
log_admin("[key_name(user)] has used cryokinesis on [key_name(C)] without internals or a suit")
msg_admin_attack("[key_name_admin(user)] has cast cryokinesis on [key_name_admin(C)]")
diff --git a/code/game/gamemodes/autotraitor/autotraitor.dm b/code/game/gamemodes/autotraitor/autotraitor.dm
index 7c307295dc7..6a7fa32c5c3 100644
--- a/code/game/gamemodes/autotraitor/autotraitor.dm
+++ b/code/game/gamemodes/autotraitor/autotraitor.dm
@@ -91,7 +91,7 @@
if(player.current) // Remove mindshield-implanted mobs from the list
if(ishuman(player.current))
var/mob/living/carbon/human/H = player.current
- for(var/obj/item/weapon/implant/loyalty/I in H.contents)
+ for(var/obj/item/weapon/implant/mindshield/I in H.contents)
if(I && I.implanted)
possible_traitors -= player
@@ -141,7 +141,7 @@
set_antag_hud(newtraitor, "hudsyndicate")
var/obj_count = 1
- to_chat(newtraitor, "\blue Your current objectives:")
+ to_chat(newtraitor, "Your current objectives:")
for(var/datum/objective/objective in newtraitor.mind.objectives)
to_chat(newtraitor, "Objective #[obj_count]: [objective.explanation_text]")
obj_count++
diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm
index 16f98927e17..336d66b8df8 100644
--- a/code/game/gamemodes/blob/blob.dm
+++ b/code/game/gamemodes/blob/blob.dm
@@ -135,7 +135,7 @@ var/list/blob_nodes = list()
else if(blob_client && location)
burst++
C.gib()
- var/obj/effect/blob/core/core = new(location, 200, blob_client, blob_point_rate)
+ var/obj/structure/blob/core/core = new(location, 200, blob_client, blob_point_rate)
if(core.overmind && core.overmind.mind)
core.overmind.mind.name = blob.name
infected_crew -= blob
diff --git a/code/game/gamemodes/blob/blob_report.dm b/code/game/gamemodes/blob/blob_report.dm
index b937c16e74c..e1ac73a36ed 100644
--- a/code/game/gamemodes/blob/blob_report.dm
+++ b/code/game/gamemodes/blob/blob_report.dm
@@ -81,8 +81,10 @@
for(var/obj/O in T.contents)
if(istype(O, /obj/structure/window))
src.window += 1
- else if(istype(O, /obj/structure/grille) && (!O:destroyed))
- src.grille += 1
+ else if(istype(O, /obj/structure/grille))
+ var/obj/structure/grille/GR = O
+ if(!GR.broken)
+ grille += 1
else if(istype(O, /obj/machinery/door))
src.door += 1
else if(istype(O, /obj/machinery))
diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm
index 67229b51a1a..71a6b5be37f 100644
--- a/code/game/gamemodes/blob/blobs/blob_mobs.dm
+++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm
@@ -37,7 +37,7 @@
attacktext = "hits"
attack_sound = 'sound/weapons/genhit1.ogg'
speak_emote = list("pulses")
- var/obj/effect/blob/factory/factory = null
+ var/obj/structure/blob/factory/factory = null
var/list/human_overlays = list()
var/is_zombie = 0
gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE
@@ -48,11 +48,11 @@
/mob/living/simple_animal/hostile/blob/blobspore/CanPass(atom/movable/mover, turf/target, height=0)
- if(istype(mover, /obj/effect/blob))
+ if(istype(mover, /obj/structure/blob))
return 1
return ..()
-/mob/living/simple_animal/hostile/blob/blobspore/New(loc, var/obj/effect/blob/factory/linked_node)
+/mob/living/simple_animal/hostile/blob/blobspore/New(loc, var/obj/structure/blob/factory/linked_node)
if(istype(linked_node))
factory = linked_node
factory.spores += src
diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm
index 0142d198cc3..9dcb5b7e3eb 100644
--- a/code/game/gamemodes/blob/blobs/core.dm
+++ b/code/game/gamemodes/blob/blobs/core.dm
@@ -1,4 +1,4 @@
-/obj/effect/blob/core
+/obj/structure/blob/core
name = "blob core"
icon = 'icons/mob/blob.dmi'
icon_state = "blank_blob"
@@ -11,7 +11,7 @@
var/is_offspring = null
var/selecting = 0
-/obj/effect/blob/core/New(loc, var/h = 200, var/client/new_overmind = null, var/new_rate = 2, offspring)
+/obj/structure/blob/core/New(loc, var/h = 200, var/client/new_overmind = null, var/new_rate = 2, offspring)
blob_cores += src
processing_objects.Add(src)
poi_list |= src
@@ -26,7 +26,7 @@
..(loc, h)
-/obj/effect/blob/core/adjustcolors(var/a_color)
+/obj/structure/blob/core/adjustcolors(var/a_color)
overlays.Cut()
color = null
var/image/I = new('icons/mob/blob.dmi', "blob")
@@ -36,7 +36,7 @@
overlays += C
-/obj/effect/blob/core/Destroy()
+/obj/structure/blob/core/Destroy()
blob_cores -= src
if(overmind)
overmind.blob_core = null
@@ -45,10 +45,10 @@
poi_list.Remove(src)
return ..()
-/obj/effect/blob/core/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/blob/core/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return
-/obj/effect/blob/core/update_icon()
+/obj/structure/blob/core/update_icon()
if(health <= 0)
qdel(src)
return
@@ -57,10 +57,10 @@
overmind.update_health()
return
-/obj/effect/blob/core/RegenHealth()
+/obj/structure/blob/core/RegenHealth()
return // Don't regen, we handle it in Life()
-/obj/effect/blob/core/Life()
+/obj/structure/blob/core/Life()
if(!overmind)
create_overmind()
else
@@ -79,9 +79,9 @@
for(var/b_dir in alldirs)
if(!prob(5))
continue
- var/obj/effect/blob/normal/B = locate() in get_step(src, b_dir)
+ var/obj/structure/blob/normal/B = locate() in get_step(src, b_dir)
if(B)
- B.change_to(/obj/effect/blob/shield)
+ B.change_to(/obj/structure/blob/shield)
if(B && overmind)
B.color = overmind.blob_reagent_datum.color
else
@@ -90,7 +90,7 @@
..()
-/obj/effect/blob/core/proc/create_overmind(var/client/new_overmind, var/override_delay)
+/obj/structure/blob/core/proc/create_overmind(var/client/new_overmind, var/override_delay)
if(overmind_get_delay > world.time && !override_delay)
return
diff --git a/code/game/gamemodes/blob/blobs/factory.dm b/code/game/gamemodes/blob/blobs/factory.dm
index 5ea20b49e58..81d3ab47493 100644
--- a/code/game/gamemodes/blob/blobs/factory.dm
+++ b/code/game/gamemodes/blob/blobs/factory.dm
@@ -1,4 +1,4 @@
-/obj/effect/blob/factory
+/obj/structure/blob/factory
name = "factory blob"
icon = 'icons/mob/blob.dmi'
icon_state = "blob_factory"
@@ -9,18 +9,18 @@
var/spore_delay = 0
var/mob/camera/blob/overmind
-/obj/effect/blob/factory/update_icon()
+/obj/structure/blob/factory/update_icon()
if(health <= 0)
qdel(src)
-/obj/effect/blob/factory/Destroy()
+/obj/structure/blob/factory/Destroy()
for(var/mob/living/simple_animal/hostile/blob/blobspore/spore in spores)
if(spore.factory == src)
spore.factory = null
spores = null
return ..()
-/obj/effect/blob/factory/run_action()
+/obj/structure/blob/factory/run_action()
if(spores.len >= max_spores)
return 0
if(spore_delay > world.time)
diff --git a/code/game/gamemodes/blob/blobs/node.dm b/code/game/gamemodes/blob/blobs/node.dm
index f9a89391ee7..232511744ea 100644
--- a/code/game/gamemodes/blob/blobs/node.dm
+++ b/code/game/gamemodes/blob/blobs/node.dm
@@ -1,4 +1,4 @@
-/obj/effect/blob/node
+/obj/structure/blob/node
name = "blob node"
icon = 'icons/mob/blob.dmi'
icon_state = "blank_blob"
@@ -6,12 +6,12 @@
fire_resist = 2
var/mob/camera/blob/overmind
-/obj/effect/blob/node/New(loc, var/h = 100)
+/obj/structure/blob/node/New(loc, var/h = 100)
blob_nodes += src
processing_objects.Add(src)
..(loc, h)
-/obj/effect/blob/node/adjustcolors(var/a_color)
+/obj/structure/blob/node/adjustcolors(var/a_color)
overlays.Cut()
color = null
var/image/I = new('icons/mob/blob.dmi', "blob")
@@ -20,15 +20,15 @@
var/image/C = new('icons/mob/blob.dmi', "blob_node_overlay")
src.overlays += C
-/obj/effect/blob/node/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/blob/node/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return
-/obj/effect/blob/node/Destroy()
+/obj/structure/blob/node/Destroy()
blob_nodes -= src
processing_objects.Remove(src)
return ..()
-/obj/effect/blob/node/Life()
+/obj/structure/blob/node/Life()
if(overmind)
for(var/i = 1; i < 8; i += i)
Pulse(5, i, overmind.blob_reagent_datum.color)
@@ -38,7 +38,7 @@
health = min(initial(health), health + 1)
color = null
-/obj/effect/blob/node/update_icon()
+/obj/structure/blob/node/update_icon()
if(health <= 0)
qdel(src)
return
diff --git a/code/game/gamemodes/blob/blobs/resource.dm b/code/game/gamemodes/blob/blobs/resource.dm
index d5b867e96c0..f5d838fd0a2 100644
--- a/code/game/gamemodes/blob/blobs/resource.dm
+++ b/code/game/gamemodes/blob/blobs/resource.dm
@@ -1,4 +1,4 @@
-/obj/effect/blob/resource
+/obj/structure/blob/resource
name = "resource blob"
icon = 'icons/mob/blob.dmi'
icon_state = "blob_resource"
@@ -7,11 +7,11 @@
var/mob/camera/blob/overmind = null
var/resource_delay = 0
-/obj/effect/blob/resource/update_icon()
+/obj/structure/blob/resource/update_icon()
if(health <= 0)
qdel(src)
-/obj/effect/blob/resource/run_action()
+/obj/structure/blob/resource/run_action()
if(resource_delay > world.time)
return 0
diff --git a/code/game/gamemodes/blob/blobs/shield.dm b/code/game/gamemodes/blob/blobs/shield.dm
index 1c145f4404f..5ae1a040ab6 100644
--- a/code/game/gamemodes/blob/blobs/shield.dm
+++ b/code/game/gamemodes/blob/blobs/shield.dm
@@ -1,4 +1,4 @@
-/obj/effect/blob/shield
+/obj/structure/blob/shield
name = "strong blob"
icon = 'icons/mob/blob.dmi'
icon_state = "blob_idle"
@@ -7,15 +7,15 @@
fire_resist = 2
-/obj/effect/blob/shield/update_icon()
+/obj/structure/blob/shield/update_icon()
if(health <= 0)
qdel(src)
return
return
-/obj/effect/blob/shield/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/blob/shield/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return
-/obj/effect/blob/shield/CanPass(atom/movable/mover, turf/target, height=0)
+/obj/structure/blob/shield/CanPass(atom/movable/mover, turf/target, height=0)
if(istype(mover) && mover.checkpass(PASSBLOB)) return 1
return 0
diff --git a/code/game/gamemodes/blob/blobs/storage.dm b/code/game/gamemodes/blob/blobs/storage.dm
index b6c993f82fe..f29fb9af405 100644
--- a/code/game/gamemodes/blob/blobs/storage.dm
+++ b/code/game/gamemodes/blob/blobs/storage.dm
@@ -1,4 +1,4 @@
-/obj/effect/blob/storage
+/obj/structure/blob/storage
name = "storage blob"
icon = 'icons/mob/blob.dmi'
icon_state = "blob_resource"
@@ -6,11 +6,11 @@
fire_resist = 2
var/mob/camera/blob/overmind = null
-/obj/effect/blob/storage/update_icon()
+/obj/structure/blob/storage/update_icon()
if(health <= 0)
overmind.max_blob_points -= 50
qdel(src)
-/obj/effect/blob/storage/proc/update_max_blob_points(var/new_point_increase)
+/obj/structure/blob/storage/proc/update_max_blob_points(var/new_point_increase)
if(overmind)
overmind.max_blob_points += new_point_increase
\ No newline at end of file
diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm
index e6bb0e76be9..87d2fd2b99c 100644
--- a/code/game/gamemodes/blob/overmind.dm
+++ b/code/game/gamemodes/blob/overmind.dm
@@ -11,7 +11,7 @@
pass_flags = PASSBLOB
faction = list("blob")
- var/obj/effect/blob/core/blob_core = null // The blob overmind's core
+ var/obj/structure/blob/core/blob_core = null // The blob overmind's core
var/blob_points = 0
var/max_blob_points = 100
var/last_attack = 0
@@ -117,7 +117,7 @@
stat(null, "Power Stored: [blob_points]/[max_blob_points]")
/mob/camera/blob/Move(var/NewLoc, var/Dir = 0)
- var/obj/effect/blob/B = locate() in range("3x3", NewLoc)
+ var/obj/structure/blob/B = locate() in range("3x3", NewLoc)
if(B)
loc = NewLoc
else
diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm
index cfd72f71a7e..dfae19f5135 100644
--- a/code/game/gamemodes/blob/powers.dm
+++ b/code/game/gamemodes/blob/powers.dm
@@ -27,7 +27,7 @@
for(var/i = 1; i <= blob_nodes.len; i++)
nodes["Blob Node #[i]"] = blob_nodes[i]
var/node_name = input(src, "Choose a node to jump to.", "Node Jump") in nodes
- var/obj/effect/blob/node/chosen_node = nodes[node_name]
+ var/obj/structure/blob/node/chosen_node = nodes[node_name]
if(chosen_node)
src.loc = chosen_node.loc
@@ -41,13 +41,13 @@
/mob/camera/blob/proc/create_shield(var/turf/T)
- var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
+ var/obj/structure/blob/B = (locate(/obj/structure/blob) in T)
if(!B)//We are on a blob
to_chat(src, "There is no blob here!")
return
- if(!istype(B, /obj/effect/blob/normal))
+ if(!istype(B, /obj/structure/blob/normal))
to_chat(src, "Unable to use this blob, find a normal one.")
return
@@ -55,7 +55,7 @@
return
B.color = blob_reagent_datum.color
- B.change_to(/obj/effect/blob/shield)
+ B.change_to(/obj/structure/blob/shield)
return
@@ -72,17 +72,17 @@
if(!T)
return
- var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
+ var/obj/structure/blob/B = (locate(/obj/structure/blob) in T)
if(!B)//We are on a blob
to_chat(src, "There is no blob here!")
return
- if(!istype(B, /obj/effect/blob/normal))
+ if(!istype(B, /obj/structure/blob/normal))
to_chat(src, "Unable to use this blob, find a normal one.")
return
- for(var/obj/effect/blob/resource/blob in orange(4, T))
+ for(var/obj/structure/blob/resource/blob in orange(4, T))
to_chat(src, "There is a resource blob nearby, move more than 4 tiles away from it!")
return
@@ -90,8 +90,8 @@
return
B.color = blob_reagent_datum.color
- B.change_to(/obj/effect/blob/resource)
- var/obj/effect/blob/resource/R = locate() in T
+ B.change_to(/obj/structure/blob/resource)
+ var/obj/structure/blob/resource/R = locate() in T
if(R)
R.overmind = src
@@ -108,25 +108,25 @@
if(!T)
return
- var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
+ var/obj/structure/blob/B = (locate(/obj/structure/blob) in T)
if(!B)//We are on a blob
to_chat(src, "There is no blob here!")
return
- if(!istype(B, /obj/effect/blob/normal))
+ if(!istype(B, /obj/structure/blob/normal))
to_chat(src, "Unable to use this blob, find a normal one.")
return
- for(var/obj/effect/blob/node/blob in orange(5, T))
+ for(var/obj/structure/blob/node/blob in orange(5, T))
to_chat(src, "There is another node nearby, move more than 5 tiles away from it!")
return
if(!can_buy(60))
return
- B.change_to(/obj/effect/blob/node)
- var/obj/effect/blob/node/R = locate() in T
+ B.change_to(/obj/structure/blob/node)
+ var/obj/structure/blob/node/R = locate() in T
if(R)
R.adjustcolors(blob_reagent_datum.color)
R.overmind = src
@@ -144,25 +144,25 @@
if(!T)
return
- var/obj/effect/blob/B = locate(/obj/effect/blob) in T
+ var/obj/structure/blob/B = locate(/obj/structure/blob) in T
if(!B)
to_chat(src, "You must be on a blob!")
return
- if(!istype(B, /obj/effect/blob/normal))
+ if(!istype(B, /obj/structure/blob/normal))
to_chat(src, "Unable to use this blob, find a normal one.")
return
- for(var/obj/effect/blob/factory/blob in orange(7, T))
+ for(var/obj/structure/blob/factory/blob in orange(7, T))
to_chat(src, "There is a factory blob nearby, move more than 7 tiles away from it!")
return
if(!can_buy(60))
return
- B.change_to(/obj/effect/blob/factory)
+ B.change_to(/obj/structure/blob/factory)
B.color = blob_reagent_datum.color
- var/obj/effect/blob/factory/R = locate() in T
+ var/obj/structure/blob/factory/R = locate() in T
if(R)
R.overmind = src
return
@@ -178,12 +178,12 @@
if(!T)
return
- var/obj/effect/blob/B = locate(/obj/effect/blob) in T
+ var/obj/structure/blob/B = locate(/obj/structure/blob) in T
if(!B)
to_chat(src, "You must be on a blob!")
return
- if(!istype(B, /obj/effect/blob/factory))
+ if(!istype(B, /obj/structure/blob/factory))
to_chat(src, "Unable to use this blob, find a factory blob.")
return
@@ -210,7 +210,7 @@
if(!T)
return
- var/obj/effect/blob/node/B = locate(/obj/effect/blob/node) in T
+ var/obj/structure/blob/node/B = locate(/obj/structure/blob/node) in T
if(!B)
to_chat(src, "You must be on a blob node!")
return
@@ -234,12 +234,12 @@
if(!T)
return
- var/obj/effect/blob/B = locate(/obj/effect/blob) in T
+ var/obj/structure/blob/B = locate(/obj/structure/blob) in T
if(!B)
to_chat(src, "You must be on a blob!")
return
- if(istype(B, /obj/effect/blob/core))
+ if(istype(B, /obj/structure/blob/core))
to_chat(src, "Unable to remove this blob.")
return
@@ -261,12 +261,12 @@
if(!can_attack())
return
- var/obj/effect/blob/B = locate() in T
+ var/obj/structure/blob/B = locate() in T
if(B)
to_chat(src, "There is a blob here!")
return
- var/obj/effect/blob/OB = locate() in circlerange(T, 1)
+ var/obj/structure/blob/OB = locate() in circlerange(T, 1)
if(!OB)
to_chat(src, "There is no blob adjacent to you.")
return
@@ -319,7 +319,7 @@
if(!blob_nodes || !blob_nodes.len)
to_chat(src, "A node is required to birth your offspring...")
return
- var/obj/effect/blob/node/N = locate(/obj/effect/blob) in blob_nodes
+ var/obj/structure/blob/node/N = locate(/obj/structure/blob) in blob_nodes
if(!N)
to_chat(src, "A node is required to birth your offspring...")
return
@@ -328,7 +328,7 @@
return
verbs -= /mob/camera/blob/verb/split_consciousness //we've used our split_consciousness
- new /obj/effect/blob/core/ (get_turf(N), 200, null, blob_core.point_rate, "offspring")
+ new /obj/structure/blob/core/ (get_turf(N), 200, null, blob_core.point_rate, "offspring")
qdel(N)
if(ticker && ticker.mode.name == "blob")
@@ -362,17 +362,17 @@
if(!T)
return
- var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
+ var/obj/structure/blob/B = (locate(/obj/structure/blob) in T)
if(!B)//We are on a blob
to_chat(src, "There is no blob here!")
return
- if(!istype(B, /obj/effect/blob/normal))
+ if(!istype(B, /obj/structure/blob/normal))
to_chat(src, "Unable to use this blob, find a normal one.")
return
- for(var/obj/effect/blob/storage/blob in orange(3, T))
+ for(var/obj/structure/blob/storage/blob in orange(3, T))
to_chat(src, "There is a storage blob nearby, move more than 4 tiles away from it!")
return
@@ -380,8 +380,8 @@
return
B.color = blob_reagent_datum.color
- B.change_to(/obj/effect/blob/storage)
- var/obj/effect/blob/storage/R = locate() in T
+ B.change_to(/obj/structure/blob/storage)
+ var/obj/structure/blob/storage/R = locate() in T
if(R)
R.overmind = src
R.update_max_blob_points(50)
@@ -400,7 +400,7 @@
var/datum/reagent/blob/B = pick((subtypesof(/datum/reagent/blob) - blob_reagent_datum.type))
blob_reagent_datum = new B
- for(var/obj/effect/blob/BL in blobs)
+ for(var/obj/structure/blob/BL in blobs)
BL.adjustcolors(blob_reagent_datum.color)
for(var/mob/living/simple_animal/hostile/blob/BLO)
diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm
index 1de939c40e7..b7558d0c9cf 100644
--- a/code/game/gamemodes/blob/theblob.dm
+++ b/code/game/gamemodes/blob/theblob.dm
@@ -1,5 +1,5 @@
//I will need to recode parts of this but I am way too tired atm
-/obj/effect/blob
+/obj/structure/blob
name = "blob"
icon = 'icons/mob/blob.dmi'
light_range = 3
@@ -13,7 +13,7 @@
var/fire_resist = 1
-/obj/effect/blob/New(loc)
+/obj/structure/blob/New(loc)
blobs += src
src.dir = pick(1, 2, 4, 8)
src.update_icon()
@@ -23,37 +23,40 @@
return
-/obj/effect/blob/Destroy()
+/obj/structure/blob/Destroy()
blobs -= src
if(isturf(loc)) //Necessary because Expand() is retarded and spawns a blob and then deletes it
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
return ..()
-/obj/effect/blob/CanPass(atom/movable/mover, turf/target, height=0)
+/obj/structure/blob/CanPass(atom/movable/mover, turf/target, height=0)
if(height==0) return 1
if(istype(mover) && mover.checkpass(PASSBLOB)) return 1
return 0
-/obj/effect/blob/CanAStarPass(ID, dir, caller)
+/obj/structure/blob/CanAStarPass(ID, dir, caller)
. = 0
if(ismovableatom(caller))
var/atom/movable/mover = caller
. = . || mover.checkpass(PASSBLOB)
-/obj/effect/blob/process()
+/obj/structure/blob/process()
Life()
return
-/obj/effect/blob/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/blob/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
..()
var/damage = Clamp(0.01 * exposed_temperature, 0, 4)
take_damage(damage, BURN)
-/obj/effect/blob/proc/Life()
+/obj/structure/blob/blob_act()
return
-/obj/effect/blob/proc/RegenHealth()
+/obj/structure/blob/proc/Life()
+ return
+
+/obj/structure/blob/proc/RegenHealth()
// All blobs heal over time when pulsed, but it has a cool down
if(health_timestamp > world.time)
return 0
@@ -63,7 +66,7 @@
health_timestamp = world.time + 10 // 1 seconds
-/obj/effect/blob/proc/Pulse(var/pulse = 0, var/origin_dir = 0, var/a_color)//Todo: Fix spaceblob expand
+/obj/structure/blob/proc/Pulse(var/pulse = 0, var/origin_dir = 0, var/a_color)//Todo: Fix spaceblob expand
set background = BACKGROUND_ENABLED
@@ -83,7 +86,7 @@
var/dirn = pick(dirs)
dirs.Remove(dirn)
var/turf/T = get_step(src, dirn)
- var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
+ var/obj/structure/blob/B = (locate(/obj/structure/blob) in T)
if(!B)
expand(T,1,a_color)//No blob here so try and expand
return
@@ -94,11 +97,11 @@
return
-/obj/effect/blob/proc/run_action()
+/obj/structure/blob/proc/run_action()
return 0
-/obj/effect/blob/proc/expand(var/turf/T = null, var/prob = 1, var/a_color)
+/obj/structure/blob/proc/expand(var/turf/T = null, var/prob = 1, var/a_color)
if(prob && !prob(health)) return
if(istype(T, /turf/space) && prob(75)) return
if(!T)
@@ -107,11 +110,11 @@
var/dirn = pick(dirs)
dirs.Remove(dirn)
T = get_step(src, dirn)
- if(!(locate(/obj/effect/blob) in T)) break
+ if(!(locate(/obj/structure/blob) in T)) break
else T = null
if(!T) return 0
- var/obj/effect/blob/normal/B = new /obj/effect/blob/normal(src.loc, min(src.health, 30))
+ var/obj/structure/blob/normal/B = new /obj/structure/blob/normal(src.loc, min(src.health, 30))
B.color = a_color
B.density = 1
if(T.Enter(B,src))//Attempt to move into the tile
@@ -126,22 +129,25 @@
A.blob_act()
return 1
-/obj/effect/blob/ex_act(severity)
+/obj/structure/blob/ex_act(severity)
..()
var/damage = 150 - 20 * severity
take_damage(damage, BRUTE)
-/obj/effect/blob/bullet_act(var/obj/item/projectile/Proj)
+/obj/structure/blob/bullet_act(var/obj/item/projectile/Proj)
..()
take_damage(Proj.damage, Proj.damage_type)
return 0
-/obj/effect/blob/Crossed(var/mob/living/L)
+/obj/structure/blob/Crossed(var/mob/living/L)
..()
L.blob_act()
+/obj/structure/blob/tesla_act(power)
+ ..()
+ take_damage(power/400, BURN)
-/obj/effect/blob/attackby(var/obj/item/weapon/W, var/mob/living/user, params)
+/obj/structure/blob/attackby(var/obj/item/weapon/W, var/mob/living/user, params)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
@@ -150,7 +156,7 @@
playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
take_damage(W.force, W.damtype)
-/obj/effect/blob/attack_animal(mob/living/simple_animal/M as mob)
+/obj/structure/blob/attack_animal(mob/living/simple_animal/M as mob)
M.changeNext_move(CLICK_CD_MELEE)
M.do_attack_animation(src)
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
@@ -159,7 +165,7 @@
take_damage(damage, BRUTE)
return
-/obj/effect/blob/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
+/obj/structure/blob/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
M.changeNext_move(CLICK_CD_MELEE)
M.do_attack_animation(src)
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
@@ -168,7 +174,7 @@
take_damage(damage, BRUTE)
return
-/obj/effect/blob/proc/take_damage(damage, damage_type)
+/obj/structure/blob/proc/take_damage(damage, damage_type)
if(!damage || damage_type == STAMINA) // Avoid divide by zero errors
return
switch(damage_type)
@@ -179,38 +185,38 @@
health -= damage
update_icon()
-/obj/effect/blob/proc/change_to(var/type)
+/obj/structure/blob/proc/change_to(var/type)
if(!ispath(type))
error("[type] is an invalid type for the blob.")
- var/obj/effect/blob/B = new type(src.loc)
- if(!istype(type, /obj/effect/blob/core) || !istype(type, /obj/effect/blob/node))
+ var/obj/structure/blob/B = new type(src.loc)
+ if(!istype(type, /obj/structure/blob/core) || !istype(type, /obj/structure/blob/node))
B.color = color
else
B.adjustcolors(color)
qdel(src)
-/obj/effect/blob/proc/adjustcolors(var/a_color)
+/obj/structure/blob/proc/adjustcolors(var/a_color)
if(a_color)
color = a_color
return
-/obj/effect/blob/examine(mob/user)
+/obj/structure/blob/examine(mob/user)
..(user)
to_chat(user, "It looks like it's of a [get_chem_name()] kind.")
-/obj/effect/blob/proc/get_chem_name()
+/obj/structure/blob/proc/get_chem_name()
for(var/mob/camera/blob/B in mob_list)
if(lowertext(B.blob_reagent_datum.color) == lowertext(src.color)) // Goddamit why we use strings for these
return B.blob_reagent_datum.name
return "unknown"
-/obj/effect/blob/normal
+/obj/structure/blob/normal
icon_state = "blob"
light_range = 0
health = 21
-/obj/effect/blob/normal/update_icon()
+/obj/structure/blob/normal/update_icon()
if(health <= 0)
qdel(src)
else if(health <= 15)
diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index 1e67760322c..5c3f94a44a3 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -108,11 +108,11 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
if(identity_theft.target && identity_theft.target.current)
identity_theft.target_real_name = kill_objective.target.current.real_name //Whoops, forgot this.
var/mob/living/carbon/human/H = identity_theft.target.current
- if(check_species_absorb(H.species)) // For species that can't be absorbed - should default to an escape objective
- return
- else
+ if(can_absorb_species(H.species)) // For species that can't be absorbed - should default to an escape objective
identity_theft.explanation_text = "Escape on the shuttle or an escape pod with the identity of [identity_theft.target_real_name], the [identity_theft.target.assigned_role] while wearing their identification card."
- changeling.objectives += identity_theft
+ changeling.objectives += identity_theft
+ else
+ qdel(identity_theft)
if(!(locate(/datum/objective/escape) in changeling.objectives))
if(prob(70))
@@ -316,5 +316,5 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
return 1
-/proc/check_species_absorb(datum/species/S)
+/proc/can_absorb_species(datum/species/S)
return !(S.flags & NO_DNA)
diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm
index 4219032fb96..9a6438853c0 100644
--- a/code/game/gamemodes/changeling/powers/mutations.dm
+++ b/code/game/gamemodes/changeling/powers/mutations.dm
@@ -279,7 +279,7 @@
name = "flesh mass"
icon_state = "lingspacehelmet"
desc = "A covering of pressure and temperature-resistant organic tissue with a glass-like chitin front."
- flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | NODROP
+ flags = BLOCKHAIR | STOPSPRESSUREDMAGE | NODROP
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
/obj/item/clothing/head/helmet/space/changeling/dropped()
@@ -330,7 +330,7 @@
name = "chitinous mass"
desc = "A tough, hard covering of black chitin with transparent chitin in front."
icon_state = "lingarmorhelmet"
- flags = HEADCOVERSEYES | BLOCKHAIR | NODROP
+ flags = BLOCKHAIR | NODROP
armor = list(melee = 30, bullet = 30, laser = 40, energy = 20, bomb = 10, bio = 4, rad = 0)
flags_inv = HIDEEARS
diff --git a/code/game/gamemodes/changeling/powers/panacea.dm b/code/game/gamemodes/changeling/powers/panacea.dm
index 4b8e002d576..8ae82a0e788 100644
--- a/code/game/gamemodes/changeling/powers/panacea.dm
+++ b/code/game/gamemodes/changeling/powers/panacea.dm
@@ -14,7 +14,7 @@
var/mob/living/simple_animal/borer/B = user.has_brain_worms()
if(B)
if(B.controlling)
- B.detatch()
+ B.detach()
B.leave_host()
if(iscarbon(user))
var/mob/living/carbon/C = user
diff --git a/code/game/gamemodes/changeling/powers/spiders.dm b/code/game/gamemodes/changeling/powers/spiders.dm
index 135fd92479c..348924c7d7b 100644
--- a/code/game/gamemodes/changeling/powers/spiders.dm
+++ b/code/game/gamemodes/changeling/powers/spiders.dm
@@ -9,7 +9,7 @@
//Makes some spiderlings. Good for setting traps and causing general trouble.
/obj/effect/proc_holder/changeling/spiders/sting_action(var/mob/user)
for(var/i=0, i<2, i++)
- var/obj/effect/spider/spiderling/S = new(user.loc)
+ var/obj/structure/spider/spiderling/S = new(user.loc)
S.grow_as = /mob/living/simple_animal/hostile/poison/giant_spider/hunter
feedback_add_details("changeling_powers","SI")
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index 3af75d1f14d..ff7c74a6fbb 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -19,7 +19,7 @@ var/global/list/all_cults = list()
return 0
if(ishuman(mind.current))
var/mob/living/carbon/human/H = mind.current
- if(isloyal(H))
+ if(ismindshielded(H))
return 0
if(issilicon(mind.current))
return 0 //can't convert machines, that's ratvar's thing
@@ -176,8 +176,8 @@ var/global/list/all_cults = list()
var/datum/action/innate/cultcomm/C = new()
C.Grant(cult_mind.current)
cult_mind.current.create_attack_log("Has been converted to the cult!")
- if(jobban_isbanned(cult_mind.current, ROLE_CULTIST))
- replace_jobbaned_player(cult_mind.current, ROLE_CULTIST)
+ if(jobban_isbanned(cult_mind.current, ROLE_CULTIST) || jobban_isbanned(cult_mind.current, ROLE_SYNDICATE))
+ replace_jobbanned_player(cult_mind.current, ROLE_CULTIST)
update_cult_icons_added(cult_mind)
if(GAMEMODE_IS_CULT)
var/datum/game_mode/cult/cult_mode = ticker.mode
@@ -339,10 +339,10 @@ var/global/list/all_cults = list()
if("harvest")
if(harvested > harvest_target)
- explanation = "Offer [harvest_target] humans for [ticker.mode.cultdat.entity_name]'s first meal of the day. ([harvested] eaten) Success!"
+ explanation = "Offer [harvest_target] humans for [ticker.mode.cultdat.entity_name]'s first meal of the day. ([harvested] sacrificed) Success!"
feedback_add_details("cult_objective","cult_harvest|SUCCESS")
else
- explanation = "Offer [harvest_target] humans for [ticker.mode.cultdat.entity_name]'s first meal of the day. ([harvested] eaten) Fail!"
+ explanation = "Offer [harvest_target] humans for [ticker.mode.cultdat.entity_name]'s first meal of the day. ([harvested] sacrificed) Fail!"
feedback_add_details("cult_objective","cult_harvest|FAIL")
if("hijack")
diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm
index f7bdc478466..6ab24e1d8b4 100644
--- a/code/game/gamemodes/cult/cult_items.dm
+++ b/code/game/gamemodes/cult/cult_items.dm
@@ -64,7 +64,7 @@
icon_state = "culthood"
desc = "A hood worn by the followers of a cult."
flags_inv = HIDEFACE
- flags = HEADCOVERSEYES
+ flags_cover = HEADCOVERSEYES
armor = list(melee = 30, bullet = 10, laser = 5, energy = 5, bomb = 0, bio = 0, rad = 0)
cold_protection = HEAD
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
@@ -96,8 +96,9 @@
icon_state = "magus"
item_state = "magus"
desc = "A helm worn by the followers of Nar-Sie."
+ flags = BLOCKHAIR
flags_inv = HIDEFACE
- flags = HEADCOVERSEYES | HEADCOVERSMOUTH | BLOCKHAIR
+ flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
armor = list(melee = 30, bullet = 30, laser = 30, energy = 20, bomb = 0, bio = 0, rad = 0)
/obj/item/clothing/suit/magusred
@@ -145,8 +146,9 @@
icon_state = "cult_hoodalt"
armor = list(melee = 50, bullet = 40, laser = 50, energy = 30, bomb = 50, bio = 30, rad = 30)
body_parts_covered = HEAD
+ flags = NODROP
flags_inv = HIDEFACE
- flags = NODROP | HEADCOVERSEYES
+ flags_cover = HEADCOVERSEYES
/obj/item/clothing/suit/hooded/cultrobes/cult_shield/equipped(mob/living/user, slot)
..()
@@ -171,8 +173,8 @@
/obj/item/clothing/suit/hooded/cultrobes/berserker
name = "flagellant's robes"
desc = "Blood-soaked robes infused with dark magic; allows the user to move at inhuman speeds, but at the cost of increased damage."
- icon_state = "hardsuit-beserker"
- item_state = "hardsuit-beserker"
+ icon_state = "hardsuit-berserker"
+ item_state = "hardsuit-berserker"
flags_inv = HIDEJUMPSUIT
allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade)
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
@@ -186,7 +188,7 @@
desc = "Blood-soaked garb infused with dark magic; allows the user to move at inhuman speeds, but at the cost of increased damage."
icon_state = "culthood"
flags_inv = HIDEFACE
- flags = HEADCOVERSEYES
+ flags_cover = HEADCOVERSEYES
armor = list(melee = -100, bullet = -100, laser = -100, energy = -100, bomb = -100, bio = -100, rad = -100)
/obj/item/weapon/whetstone/cult
@@ -298,7 +300,7 @@
var/turf/mobloc = get_turf(C)
var/list/turfs = new/list()
for(var/turf/T in range(user, outer_tele_radius))
- if(!is_teleport_allowed(T))
+ if(!is_teleport_allowed(T.z))
continue
if(get_dir(C, T) != C.dir)
continue
@@ -331,4 +333,4 @@
playsound(destination, "sparks", 50, 1)
else
- to_chat(C, "The veil cannot be torn here!")
\ No newline at end of file
+ to_chat(C, "The veil cannot be torn here!")
diff --git a/code/game/gamemodes/cult/cult_objectives.dm b/code/game/gamemodes/cult/cult_objectives.dm
index 2fe00023c20..4b30bbd37b0 100644
--- a/code/game/gamemodes/cult/cult_objectives.dm
+++ b/code/game/gamemodes/cult/cult_objectives.dm
@@ -145,6 +145,19 @@
message_admins("Last Cult Objective: [last_objective]")
log_admin("Last Cult Objective: [last_objective]")
+/datum/game_mode/cult/proc/get_possible_sac_targets()
+ var/list/possible_sac_targets = list()
+ for(var/mob/living/carbon/human/player in player_list)
+ if(player.mind && !is_convertable_to_cult(player.mind) && (player.stat != DEAD))
+ possible_sac_targets += player.mind
+ if(!possible_sac_targets.len)
+ //There are no living Unconvertables on the station. Looking for a Sacrifice Target among the ordinary crewmembers
+ for(var/mob/living/carbon/human/player in player_list)
+ if(is_secure_level(player.z)) //We can't sacrifice people that are on the centcom z-level
+ continue
+ if(player.mind && !(player.mind in cult) && (player.stat != DEAD))//make DAMN sure they are not dead
+ possible_sac_targets += player.mind
+ return possible_sac_targets
/datum/game_mode/cult/proc/pick_objective()
var/list/possible_objectives = list()
@@ -153,19 +166,7 @@
possible_objectives |= "bloodspill"
if(!sacrificed.len)
- var/list/possible_targets = list()
- for(var/mob/living/carbon/human/player in player_list)
- if(player.mind && !is_convertable_to_cult(player.mind) && (player.stat != DEAD))
- possible_targets += player.mind
-
- if(!possible_targets.len)
- //There are no living Unconvertables on the station. Looking for a Sacrifice Target among the ordinary crewmembers
- for(var/mob/living/carbon/human/player in player_list)
- if(is_secure_level(player.z)) //We can't sacrifice people that are on the centcom z-level
- continue
- if(player.mind && !(player.mind in cult) && (player.stat != DEAD))//make DAMN sure they are not dead
- possible_targets += player.mind
-
+ var/list/possible_targets = get_possible_sac_targets()
if(possible_targets.len > 0)
sacrifice_target = pick(possible_targets)
possible_objectives |= "sacrifice"
diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm
index 752e8e353d0..e0be012f328 100644
--- a/code/game/gamemodes/cult/ritual.dm
+++ b/code/game/gamemodes/cult/ritual.dm
@@ -8,7 +8,7 @@
else
usr.whisper(pick("Hakkrutju gopoenjim.", "Nherasai pivroiashan.", "Firjji prhiv mazenhor.", "Tanah eh wakantahe.", "Obliyae na oraie.", "Miyf hon vnor'c.", "Wakabai hij fen juswix."))
for (var/mob/V in viewers(src))
- V.show_message("\red The markings pulse with a small burst of light, then fall dark.", 3, "\red You hear a faint fizzle.", 2)
+ V.show_message("The markings pulse with a small burst of light, then fall dark.", 3, "You hear a faint fizzle.", 2)
return
/obj/effect/rune/proc/check_icon()
@@ -102,7 +102,7 @@
If any are found, the user can choose which rune to send to. Upon activation, the rune teleports everything above it to the selected rune.
"
text += "Rite of Enlightenment This rune is critical to the success of the cult. It will allow you to convert normal crew members into cultists. \
- To do this, simply place the crew member upon the rune and invoke it. This rune requires two invokers to use. If the target to be converted is loyalty-implanted or a certain assignment, they will \
+ To do this, simply place the crew member upon the rune and invoke it. This rune requires two invokers to use. If the target to be converted is mindshielded or a certain assignment, they will \
be unable to be converted. People [ticker.mode.cultdat.entity_title3] wishes sacrificed will also be ineligible for conversion, and anyone with a shielding presence like the null rod will not be converted. \
Successful conversions will produce a tome for the new cultist.
"
@@ -158,8 +158,8 @@
text += "Talisman of Stunning Attacking a target will knock them down for a long duration in addition to inhibiting their speech. \
Robotic lifeforms will suffer the effects of a heavy electromagnetic pulse instead.
"
- text += "Talisman of Armaments The Talisman of Arming will equip the user with armored robes, a backpack, an eldritch longsword, an empowered bola. Any items that cannot \
- be equipped will not be summoned. Attacking a fellow cultist with it will instead equip them.
"
+ text += "Talisman of Armaments The Talisman of Arming will equip the user with armored robes, a backpack, shoes, an eldritch longsword, and an empowered bola. Any equipment that cannot \
+ be equipped will not be summoned, weaponary will be put on the floor below the user. Attacking a fellow cultist with it will instead equip them.
"
text += "Talisman of Horrors The Talisman of Horror must be applied directly to the victim, it will shatter your victim's mind with visions of the endtimes that may incapitate them.
"
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index d4e78501639..14fe620cc3c 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -323,7 +323,7 @@ var/list/teleport_runes = list()
//Rite of Enlightenment: Converts a normal crewmember to the cult. Faster for every cultist nearby.
/obj/effect/rune/convert
cultist_name = "Rite of Enlightenment"
- cultist_desc = "converts a normal crewmember on top of it to the cult. Does not work on loyalty-implanted crew."
+ cultist_desc = "converts a normal crewmember on top of it to the cult. Does not work on mindshielded crew."
invocation = "Mah'weyh pleggh at e'ntrath!"
icon_state = "3"
req_cultists = 2
@@ -336,7 +336,7 @@ var/list/teleport_runes = list()
var/turf/T = get_turf(src)
for(var/mob/living/M in T.contents)
- if(!iscultist(M) && !isloyal(M))
+ if(!iscultist(M) && !ismindshielded(M))
convertees.Add(M)
if(!convertees.len)
fail_invoke()
@@ -427,6 +427,9 @@ var/list/teleport_runes = list()
if(is_sacrifice_target(T.mind))
sacrifice_fulfilled = 1
new /obj/effect/overlay/temp/cult/sac(loc)
+ if(ticker && ticker.mode && ticker.mode.name == "cult")
+ var/datum/game_mode/cult/cult_mode = ticker.mode
+ cult_mode.harvested++
for(var/M in invokers)
if(sacrifice_fulfilled)
to_chat(M, "\"Yes! This is the one I desire! You have done well.\"")
@@ -934,6 +937,7 @@ var/list/teleport_runes = list()
icon_state = "6"
construct_invoke = 0
color = rgb(200, 0, 0)
+ var/list/summoned_guys = list()
/obj/effect/rune/manifest/New(loc)
..()
@@ -949,7 +953,7 @@ var/list/teleport_runes = list()
return list()
var/list/ghosts_on_rune = list()
for(var/mob/dead/observer/O in get_turf(src))
- if(O.client && !jobban_isbanned(O, ROLE_CULTIST))
+ if(O.client && !jobban_isbanned(O, ROLE_CULTIST) && !jobban_isbanned(O, ROLE_SYNDICATE))
ghosts_on_rune |= O
if(!ghosts_on_rune.len)
to_chat(user, "There are no spirits near [src]!")
@@ -962,7 +966,7 @@ var/list/teleport_runes = list()
var/mob/living/user = invokers[1]
var/list/ghosts_on_rune = list()
for(var/mob/dead/observer/O in get_turf(src))
- if(O.client && !jobban_isbanned(O, ROLE_CULTIST))
+ if(O.client && !jobban_isbanned(O, ROLE_CULTIST) && !jobban_isbanned(O, ROLE_SYNDICATE))
ghosts_on_rune |= O
var/mob/dead/observer/ghost_to_spawn = pick(ghosts_on_rune)
var/mob/living/carbon/human/new_human = new(get_turf(src))
@@ -980,6 +984,7 @@ var/list/teleport_runes = list()
N.mouse_opacity = 0
new_human.key = ghost_to_spawn.key
ticker.mode.add_cultist(new_human.mind, 0)
+ summoned_guys |= new_human
to_chat(new_human, "You are a servant of [ticker.mode.cultdat.entity_title3]. You have been made semi-corporeal by the cult of [ticker.mode.cultdat.entity_name], and you are to serve them at all costs.")
while(user in get_turf(src))
@@ -994,4 +999,13 @@ var/list/teleport_runes = list()
"Your link to the world fades. Your form breaks apart.")
for(var/obj/I in new_human)
new_human.unEquip(I)
+ summoned_guys -= new_human
new_human.dust()
+
+/obj/effect/rune/manifest/Destroy()
+ for(var/mob/living/carbon/human/guy in summoned_guys)
+ for(var/obj/I in guy)
+ guy.unEquip(I)
+ guy.dust()
+ summoned_guys.Cut()
+ return ..()
diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm
index 1b7d1bee5a9..9e86a091625 100644
--- a/code/game/gamemodes/cult/talisman.dm
+++ b/code/game/gamemodes/cult/talisman.dm
@@ -59,6 +59,7 @@
dat += "Please choose the chant to be imbued into the fabric of reality. "
dat += ""
dat += "N'ath reth sh'yro eth d'raggathnor! - Summons an arcane tome, used to scribe runes and communicate with other cultists. "
+ dat += "Bar'tea eas! - Provides 5 runed metal. "
dat += "Sas'so c'arta forbici! - Allows you to move to a selected teleportation rune. "
dat += "Ta'gh fara'qha fel d'amar det! - Allows you to destroy technology in a short range. "
dat += "Fuu ma'jin! - Allows you to stun a person by attacking them with the talisman. "
@@ -79,6 +80,12 @@
if("newtome")
var/obj/item/weapon/tome/T = new(usr)
usr.put_in_hands(T)
+ if("metal")
+ if(istype(src, /obj/item/weapon/paper/talisman/supply/weak))
+ usr.visible_message("Lesser supply talismans lack the strength to materialize runed metal!")
+ return
+ var/obj/item/stack/sheet/runed_metal/R = new(usr,5)
+ usr.put_in_hands(R)
if("teleport")
var/obj/item/weapon/paper/talisman/teleport/T = new(usr)
usr.put_in_hands(T)
@@ -270,8 +277,9 @@
var/mob/living/carbon/human/H = user
user.visible_message("Otherworldly armor suddenly appears on [user]!", \
"You speak the words of the talisman, arming yourself!")
- H.equip_or_collect(new /obj/item/clothing/suit/hooded/cultrobes/alt(user), slot_wear_suit)
- H.equip_or_collect(new /obj/item/weapon/storage/backpack/cultpack(user), slot_back)
+ H.equip_to_slot_or_del(new /obj/item/clothing/suit/hooded/cultrobes/alt(user), slot_wear_suit)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/cultpack(user), slot_back)
+ H.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult(user), slot_shoes)
H.put_in_hands(new /obj/item/weapon/melee/cultblade(user))
H.put_in_hands(new /obj/item/weapon/restraints/legcuffs/bola/cult(user))
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 2a9c9851478..fc2ad7d62f9 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -37,8 +37,9 @@
var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds)
var/list/player_draft_log = list()
var/list/datum/mind/xenos = list()
-
+
var/list/datum/station_goal/station_goals = list() // A list of all station goals for this game mode
+ var/list/chumps = list()
/datum/game_mode/proc/announce() //to be calles when round starts
to_chat(world, "Notice: [src] did not define announce()")
@@ -71,6 +72,8 @@
///post_setup()
///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things
/datum/game_mode/proc/post_setup()
+ setup_chumps()
+
spawn (ROUNDSTART_LOGOUT_REPORT_TIME)
display_roundstart_logout_report()
@@ -85,6 +88,40 @@
start_state.count()
return 1
+//setup_chumps()
+//Prepares fake potential collaborators to cut down on metagaming the round type as being a traitor subtype. Overriden in traitor game modes since they have real collaborators
+/datum/game_mode/proc/setup_chumps()
+ var/max_chumps = 1
+ if(config.traitor_scaling)
+ max_chumps = max(1, round((num_players())/(5)))
+ else
+ max_chumps = max(1, min(num_players(), 5))
+ var/tries_left = 5 //limits the number of tries so we don't get stuck looping indefinitely. resets on successfully finding a new chump
+ while(chumps.len < max_chumps)
+ if(!tries_left) //ran out of unique chumps (or just bad luck with the pick() in get_nt_opposed()) so there may end up being fewer chumps in some rounds.
+ break
+ var/mob/living/carbon/human/chump = get_nt_opposed()
+ if(isnull(chump)) //no possible chumps so just end it here.
+ break
+ if(chump in chumps)
+ tries_left-- //this chump already was picked, try again!
+ else
+ chumps += chump
+ tries_left = 5 //reset our tries since we found a new chump
+ //make sure we have chumps before we try misinforming them. if we don't make a note of it.
+ if(!chumps.len)
+ message_admins("Game mode failed to find ANY chumps. Possible causes: no one is opposed/skeptical, or FalseIncarnate can't code.")
+ log_admin("Game mode failed to find ANY chumps. Possible causes: no one is opposed/skeptical, or FalseIncarnate can't code.")
+ return 0
+ //we've got chumps! misinform them!
+ for(var/mob/living/carbon/human/chump in chumps)
+ if(prob(33))
+ spawn(rand(3000, 18000)) //5-30 minute delay to throw off would-be autotraitor metagamers
+ inform_collab(chump)
+ else
+ spawn(rand(10, 100)) //same delay as if the mode were traitor
+ inform_collab(chump)
+ return 1
///process()
///Called by the gameticker
@@ -225,7 +262,7 @@
/datum/game_mode/proc/check_win() //universal trigger to be called at mob death, nuke explosion, etc. To be called from everywhere.
return 0
-
+
/datum/game_mode/proc/get_players_for_role(var/role, override_jobbans=0)
var/list/players = list()
var/list/candidates = list()
@@ -400,15 +437,20 @@ proc/display_roundstart_logout_report()
to_chat(M, msg)
-proc/get_nt_opposed()
+/proc/get_nt_opposed()
var/list/dudes = list()
for(var/mob/living/carbon/human/man in player_list)
if(man.client)
+ //don't try picking someone like the captain or a security officer for potential collaborators, even if they ARE opposed to Nanotrasen for some reason
+ if(man.mind && man.mind.assigned_role)
+ if((man.mind.assigned_role in ticker.mode.protected_jobs) || (man.mind.assigned_role in ticker.mode.restricted_jobs))
+ continue
if(man.client.prefs.nanotrasen_relation == "Opposed")
dudes += man
else if(man.client.prefs.nanotrasen_relation == "Skeptical" && prob(50))
dudes += man
- if(dudes.len == 0) return null
+ if(dudes.len == 0)
+ return null
return pick(dudes)
//Announces objectives/generic antag text.
@@ -425,7 +467,7 @@ proc/get_nt_opposed()
if(!player || !player.current) return
var/obj_count = 1
- to_chat(player.current, "\blue Your current objectives:")
+ to_chat(player.current, "Your current objectives:")
for(var/datum/objective/objective in player.objectives)
to_chat(player.current, "Objective #[obj_count]: [objective.explanation_text]")
obj_count++
@@ -440,7 +482,7 @@ proc/get_nt_opposed()
nukecode = bomb.r_code
return nukecode
-/datum/game_mode/proc/replace_jobbaned_player(mob/living/M, role_type)
+/datum/game_mode/proc/replace_jobbanned_player(mob/living/M, role_type)
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as a [role_type]?", role_type, 0, 100)
var/mob/dead/observer/theghost = null
if(candidates.len)
@@ -491,10 +533,10 @@ proc/get_nt_opposed()
var/datum/station_goal/picked = pick_n_take(possible)
goal_weights += initial(picked.weight)
station_goals += new picked
-
- if(station_goals.len)
+
+ if(station_goals.len)
send_station_goals_message()
-
+
/datum/game_mode/proc/send_station_goals_message()
var/message_text = "
"
message_text += "
[command_name()] Orders
"
@@ -504,10 +546,34 @@ proc/get_nt_opposed()
G.on_report()
message_text += G.get_report()
message_text += ""
-
+
print_command_report(message_text, "[command_name()] Orders")
/datum/game_mode/proc/declare_station_goal_completion()
for(var/V in station_goals)
var/datum/station_goal/G = V
- G.print_result()
\ No newline at end of file
+ G.print_result()
+
+
+/datum/game_mode/proc/inform_collab(mob/living/carbon/human/M)
+ if(!M)
+ return
+ //Mad-libs for their message
+ var/adjective = pick("strange", "mysterious", "sinister", "un-assuming", "unexpected")
+ var/action_words = pick("aid the fight against Nanotrasen", "repay a debt", "partake in some mischief", "help overthrow the system", "stick it to the man")
+ var/organization = pick("Anti-Fascist Movement", "Syndicate", "Spessmen for the Protesting of Nanotrasen", "Greytider's Union", "Illuminati (in space)")
+ //Stuff to give them a single set of code-words
+ var/list/possible_words = splittext(syndicate_code_phrase, ", ")
+ var/list/possible_reply = splittext(syndicate_code_response, ", ")
+ var/index = rand(1, possible_words.len)
+ var/my_word = possible_words[index]
+ var/my_reply
+ if(possible_reply.len < index) //just in case we had a longer code word list than the response list
+ my_reply = pick(possible_reply)
+ else
+ my_reply = possible_reply[index]
+
+ to_chat(M, "You suddenly remember \an [adjective] note you received earlier informing you that a chance to [action_words] may present itself today. An agent of the [organization] may contact you for help.")
+ to_chat(M, "The note had the words \"[my_word]\" and \"[my_reply]\" written at the bottom, which you memorized just in case.")
+ to_chat(M, "You are NOT an antagonist, so self-antagging rules still apply to you. Use your good judgement and ahelp if you are unsure of what you are allowed to do.")
+ M.mind.store_memory("Important Words: \"[my_word]\", \"[my_reply]\"")
diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index 8067aabe719..006c0642202 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -259,12 +259,16 @@ var/round_start_time = 0
else //nuke kills everyone on z-level 1 to prevent "hurr-durr I survived"
for(var/mob/M in mob_list)
M.buckled = temp_buckle
- if(M.client)
- M.client.screen += cinematic
if(M.stat != DEAD)
var/turf/T = get_turf(M)
- if(T && is_station_level(T.z))
- M.death(0) //no mercy
+ if(T && is_station_level(T.z) && !istype(M.loc, /obj/structure/closet/secure_closet/freezer))
+ var/mob/ghost = M.ghostize()
+ M.dust() //no mercy
+ if(ghost && ghost.client) //Play the victims an uninterrupted cinematic.
+ ghost.client.screen += cinematic
+ CHECK_TICK
+ if(M && M.client) //Play the survivors a cinematic.
+ M.client.screen += cinematic
//Now animate the cinematic
switch(station_missed)
@@ -472,7 +476,7 @@ var/round_start_time = 0
// Declare the completion of the station goals
mode.declare_station_goal_completion()
-
+
//Ask the event manager to print round end information
event_manager.RoundEnd()
diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm
index 4819ab20671..d36ac55a4c0 100644
--- a/code/game/gamemodes/heist/heist.dm
+++ b/code/game/gamemodes/heist/heist.dm
@@ -178,10 +178,10 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind'
/datum/game_mode/proc/greet_vox(var/datum/mind/raider)
to_chat(raider.current, "You are a Vox Raider, fresh from the Shoal!")
- to_chat(raider.current, "\blue The Vox are a race of cunning, sharp-eyed nomadic raiders and traders endemic to the frontier and much of the unexplored galaxy. You and the crew have come to the [station_name()] for plunder, trade or both.")
- to_chat(raider.current, "\blue Vox are cowardly and will flee from larger groups, but corner one or find them en masse and they are vicious.")
- to_chat(raider.current, "\blue Use :V to voxtalk, :H to talk on your encrypted channel, and don't forget to turn on your nitrogen internals!")
- to_chat(raider.current, "\blue Choose to accomplish your objectives by either raiding the crew and taking what you need, or by attempting to trade with them.")
+ to_chat(raider.current, "The Vox are a race of cunning, sharp-eyed nomadic raiders and traders endemic to the frontier and much of the unexplored galaxy. You and the crew have come to the [station_name()] for plunder, trade or both.")
+ to_chat(raider.current, "Vox are cowardly and will flee from larger groups, but corner one or find them en masse and they are vicious.")
+ to_chat(raider.current, "Use :V to voxtalk, :H to talk on your encrypted channel, and don't forget to turn on your nitrogen internals!")
+ to_chat(raider.current, "Choose to accomplish your objectives by either raiding the crew and taking what you need, or by attempting to trade with them.")
spawn(25)
show_objectives(raider)
@@ -235,7 +235,7 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind'
else
win_msg += "The Vox Raiders were repelled!"
- to_chat(world, "\red [win_type] [win_group] victory!")
+ to_chat(world, "[win_type] [win_group] victory!")
to_chat(world, "[win_msg]")
feedback_set_details("round_end_result","heist - [win_type] [win_group]")
diff --git a/code/game/gamemodes/intercept_report.dm b/code/game/gamemodes/intercept_report.dm
index cd6dd80876b..6cb2956d3ee 100644
--- a/code/game/gamemodes/intercept_report.dm
+++ b/code/game/gamemodes/intercept_report.dm
@@ -109,8 +109,16 @@
/datum/intercept_text/proc/get_suspect()
var/list/dudes = list()
- for(var/mob/living/carbon/human/man in player_list) if(man.client && man.client.prefs.nanotrasen_relation == "Opposed")
- dudes += man
+ for(var/mob/living/carbon/human/man in player_list)
+ if(man.client && man.client.prefs.nanotrasen_relation == "Opposed")
+ //don't include suspects who can't possibly be the antag based on their job (no suspecting the captain of being a damned dirty tator)
+ if(man.mind && man.mind.assigned_role)
+ if((man.mind.assigned_role in ticker.mode.protected_jobs) || (man.mind.assigned_role in ticker.mode.restricted_jobs))
+ return
+ //don't include suspects who can't possibly be the antag based on their species (no suspecting the machines of being sneaky changelings)
+ if(man.get_species() in ticker.mode.protected_species)
+ return
+ dudes += man
for(var/i = 0, i < max(player_list.len/10,2), i++)
dudes += pick(player_list)
return pick(dudes)
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm
index a41f86020d5..e644af03f3c 100644
--- a/code/game/gamemodes/malfunction/Malf_Modules.dm
+++ b/code/game/gamemodes/malfunction/Malf_Modules.dm
@@ -163,9 +163,7 @@
D.hostile_lockdown(src)
addtimer(D, "disable_lockdown", 900)
- var/obj/machinery/computer/communications/C = locate() in machines
- if(C)
- C.post_status("alert", "lockdown")
+ post_status("alert", "lockdown")
verbs -= /mob/living/silicon/ai/proc/lockdown
minor_announcement.Announce("Hostile runtime detected in door controllers. Isolation lockdown protocols are now in effect. Please remain calm.", "Network Alert")
diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm
index e634a47c590..4377a0038eb 100644
--- a/code/game/gamemodes/meteor/meteors.dm
+++ b/code/game/gamemodes/meteor/meteors.dm
@@ -133,7 +133,7 @@
playsound(src.loc, meteorsound, 40, 1)
get_hit()
-/obj/effect/meteor/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+/obj/effect/meteor/CanPass(atom/movable/mover, turf/target, height=0)
return istype(mover, /obj/effect/meteor) ? 1 : ..()
/obj/effect/meteor/proc/ram_turf(var/turf/T)
diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm
index db86c482f03..0d04c3ee615 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction.dm
@@ -116,6 +116,8 @@
H.mind.abductor.agent = 1
H.mind.abductor.team = team_number
H.real_name = team_name + " Agent"
+ H.reagents.add_reagent("mutadone", 1) //No fat/blind/colourblind/epileptic/whatever ayys.
+ H.overeatduration = 0
equip_common(H,team_number)
equip_agent(H,team_number)
greet_agent(agent,team_number)
@@ -130,6 +132,8 @@
H.mind.abductor.scientist = 1
H.mind.abductor.team = team_number
H.real_name = team_name + " Scientist"
+ H.reagents.add_reagent("mutadone", 1) //No fat/blind/colourblind/epileptic/whatever ayys.
+ H.overeatduration = 0
equip_common(H,team_number)
equip_scientist(H,team_number)
greet_scientist(scientist,team_number)
@@ -223,6 +227,7 @@
var/obj/item/device/radio/R = new /obj/item/device/radio/headset/syndicate/alt(agent)
R.set_frequency(radio_freq)
+ R.name = "alien headset"
agent.equip_to_slot_or_del(R, slot_l_ear)
agent.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(agent), slot_shoes)
agent.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey(agent), slot_w_uniform) //they're greys gettit
@@ -247,9 +252,10 @@
V.flags |= NODROP
agent.equip_to_slot_or_del(V, slot_wear_suit)
agent.equip_to_slot_or_del(new /obj/item/weapon/abductor_baton(agent), slot_in_backpack)
- agent.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/decloner/alien(agent), slot_belt)
+ agent.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/alien(agent), slot_in_backpack)
agent.equip_to_slot_or_del(new /obj/item/device/abductor/silencer(agent), slot_in_backpack)
agent.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/abductor(agent), slot_head)
+ agent.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/military/abductor/full(agent), slot_belt)
agent.update_icons()
@@ -286,7 +292,7 @@
var/datum/objective/objective = team_objectives[team_number]
var/team_name = team_names[team_number]
if(console.experiment.points >= objective.target_amount)
- to_chat(world, "[team_name] team fullfilled its mission!")
+ to_chat(world, "[team_name] team fulfilled its mission!")
else
to_chat(world, "[team_name] team failed its mission.")
..()
@@ -370,9 +376,23 @@
explanation_text = "Steal all"
/datum/objective/abductee/steal/New()
- var/target = pick(list("pets","lights","monkeys","fruits","shoes","bars of soap"))
+ var/target = pick(list("pets","lights","monkeys","fruits","shoes","bars of soap", "weapons", "computers", "organs"))
explanation_text+=" [target]."
+/datum/objective/abductee/paint
+ explanation_text = "The station is hideous. You must color it all"
+
+/datum/objective/abductee/paint/New()
+ var/color = pick(list("red", "blue", "green", "yellow", "orange", "purple", "black", "in rainbows", "in blood"))
+ explanation_text+= " [color]!"
+
+/datum/objective/abductee/speech
+ explanation_text = "Your brain is broken... you can only communicate in"
+
+/datum/objective/abductee/speech/New()
+ var/style = pick(list("pantomime", "rhyme", "haiku", "extended metaphors", "riddles", "extremely literal terms", "sound effects", "military jargon"))
+ explanation_text+= " [style]."
+
/datum/objective/abductee/capture
explanation_text = "Capture"
@@ -412,16 +432,16 @@
explanation_text = "Start a collection of corpses. Don't kill people to get these corpses."
/datum/objective/abductee/floors
- explanation_text = "Replace all the floor tiles with carpeting, wooden boards, or grass."
+ explanation_text = "Replace all the floor tiles with wood, carpeting, grass or bling."
/datum/objective/abductee/POWERUNLIMITED
explanation_text = "Flood the station's powernet with as much electricity as you can."
/datum/objective/abductee/pristine
- explanation_text = "Ensure the station is in absolutely pristine condition."
+ explanation_text = "The CEO of Nanotrasen is coming! Ensure the station is in absolutely pristine condition."
-/datum/objective/abductee/window
- explanation_text = "Replace all normal windows with reinforced windows."
+/datum/objective/abductee/nowalls
+ explanation_text = "The crew must get to know one another better. Break down the walls inside the station!"
/datum/objective/abductee/nations
explanation_text = "Ensure your department prospers over all else."
@@ -429,17 +449,11 @@
/datum/objective/abductee/abductception
explanation_text = "You have been changed forever. Find the ones that did this to you and give them a taste of their own medicine."
-/datum/objective/abductee/ghosts
- explanation_text = "Conduct a seance with the spirits of the afterlife."
-
/datum/objective/abductee/summon
- explanation_text = "Conduct a ritual to summon an elder god."
+ explanation_text = "The elder gods hunger. Gather a cult and conduct a ritual to summon one."
/datum/objective/abductee/machine
- explanation_text = "You are secretly an android. Interface with as many machines as you can to boost your own power."
-
-/datum/objective/abductee/prevent
- explanation_text = "You have been enlightened. This knowledge must not escape. Ensure nobody else can become enlightened."
+ explanation_text = "You are secretly an android. Interface with as many machines as you can to boost your own power so the AI may acknowledge you at last."
/datum/objective/abductee/calling
explanation_text = "Call forth a spirit from the other side."
@@ -447,7 +461,7 @@
/datum/objective/abductee/calling/New()
var/mob/dead/D = pick(dead_mob_list)
if(D)
- explanation_text = "You know that [D] has perished. Call them from the spirit realm."
+ explanation_text = "You know that [D] has perished. Hold a seance to call them from the spirit realm."
/datum/objective/abductee/social_experiment
explanation_text = "This is a secret social experiment conducted by Nanotrasen. Convince the crew that this is the truth."
@@ -459,7 +473,7 @@
explanation_text = "Nanotrasen is abusing the animals! Save as many as you can!"
/datum/objective/abductee/defect
- explanation_text = "Defect from your employer."
+ explanation_text = "Fuck the system! Defect from the station and start an independent colony in space, Mining Outpost or the derelict. Recruit crewmates if you can."
/datum/objective/abductee/promote
explanation_text = "Climb the corporate ladder all the way to the top!"
@@ -472,3 +486,33 @@
/datum/objective/abductee/pragnant
explanation_text = "You are pregnant and soon due. Find a safe place to deliver your baby."
+
+/datum/objective/abductee/engine
+ explanation_text = "Go have a good conversation with the singularity/tesla/supermatter crystal. Bonus points if it responds."
+
+/datum/objective/abductee/music
+ explanation_text = "You burn with passion for music. Share your vision. If anyone hates it, beat them on the head with your instrument!"
+
+/datum/objective/abductee/clown
+ explanation_text = "The clown is not funny. You can do better! Steal his audience and make the crew laugh!"
+
+/datum/objective/abductee/party
+ explanation_text = "You're throwing a huge rager. Make it as awesome as possible so the whole crew comes... OR ELSE!"
+
+/datum/objective/abductee/pets
+ explanation_text = "All the pets around here suck. You need to make them cooler. Replace them with exotic beasts!"
+
+/datum/objective/abductee/conspiracy
+ explanation_text = "The leaders of this station are hiding a grand, evil conspiracy. Only you can learn what it is, and expose it to the people!"
+
+/datum/objective/abductee/stalker
+ explanation_text = "The Syndicate has hired you to compile dossiers on all important members of the crew. Be sure they don't know you're doing it."
+
+/datum/objective/abductee/narrator
+ explanation_text = "You're the narrator of this tale. Follow around the protagonists to tell their story."
+
+/datum/objective/abductee/lurve
+ explanation_text = "You are doomed to feel woefully incomplete forever... until you find your true love on this station. They're waiting for you!"
+
+/datum/objective/abductee/sixthsense
+ explanation_text = "You died back there and went to heaven... or is it hell? No one here seems to know they're dead. Convince them, and maybe you can escape this limbo."
\ No newline at end of file
diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
index 29f217b44bc..2a72c4a9b9b 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
@@ -11,7 +11,7 @@
icon_state = "vest_stealth"
item_state = "armor"
blood_overlay_type = "armor"
- origin_tech = "materials=5;biotech=4;powerstorage=5;abductor=3"
+ origin_tech = "magnets=7;biotech=4;powerstorage=4;abductor=4"
armor = list(melee = 15, bullet = 15, laser = 15, energy = 15, bomb = 15, bio = 15, rad = 15)
actions_types = list(/datum/action/item_action/hands_free/activate)
var/mode = VEST_STEALTH
@@ -34,7 +34,6 @@
mode = VEST_STEALTH
armor = stealth_armor
icon_state = "vest_stealth"
-
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
H.update_inv_wear_suit()
@@ -64,7 +63,6 @@
M.overlays = disguise.overlays
M.update_inv_r_hand()
M.update_inv_l_hand()
- return
/obj/item/clothing/suit/armor/abductor/vest/proc/DeactivateStealth()
if(!stealth_active)
@@ -77,7 +75,6 @@
M.name_override = null
M.overlays.Cut()
M.regenerate_icons()
- return
/obj/item/clothing/suit/armor/abductor/vest/hit_reaction()
DeactivateStealth()
@@ -115,19 +112,11 @@
if(combat_cooldown==initial(combat_cooldown))
processing_objects.Remove(src)
-/obj/item/device/abductor/proc/IsAbductor(user)
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- if(H.get_species() != "Abductor")
- return 0
- return 1
- return 0
-
/obj/item/device/abductor/proc/AbductorCheck(user)
- if(IsAbductor(user))
- return 1
+ if(isabductor(user))
+ return TRUE
to_chat(user, "You can't figure how this works!")
- return 0
+ return FALSE
/obj/item/device/abductor/proc/ScientistCheck(user)
var/mob/living/carbon/human/H = user
@@ -140,7 +129,7 @@
icon = 'icons/obj/abductor.dmi'
icon_state = "gizmo_scan"
item_state = "gizmo"
- origin_tech = "materials=5;magnets=5;bluespace=6;abductor=4"
+ origin_tech = "engineering=7;magnets=4;bluespace=4;abductor=3"
var/mode = GIZMO_SCAN
var/mob/living/marked = null
var/obj/machinery/abductor/console/console
@@ -187,7 +176,7 @@
mark(target, user)
/obj/item/device/abductor/gizmo/proc/scan(atom/target, mob/living/user)
- if(istype(target,/mob/living/carbon/human))
+ if(ishuman(target))
if(console!=null)
console.AddSnapshot(target)
to_chat(user, "You scan [target] and add them to the database.")
@@ -196,8 +185,8 @@
if(marked == target)
to_chat(user, "This specimen is already marked!")
return
- if(istype(target,/mob/living/carbon/human))
- if(IsAbductor(target))
+ if(ishuman(target))
+ if(isabductor(target))
marked = target
to_chat(user, "You mark [target] for future retrieval.")
else
@@ -221,7 +210,7 @@
icon = 'icons/obj/abductor.dmi'
icon_state = "silencer"
item_state = "silencer"
- origin_tech = "materials=5;magnets=5;abductor=3"
+ origin_tech = "materials=4;programming=7;abductor=3"
/obj/item/device/abductor/silencer/attack(mob/living/M, mob/user)
if(!AbductorCheck(user))
@@ -258,61 +247,15 @@
if(!istype(I,/obj/item/device/radio/headset))
r.broadcasting = 0 //goddamned headset hacks
-
-/obj/item/weapon/implant/abductor
- name = "recall implant"
- desc = "Returns you to the mothership."
- icon = 'icons/obj/abductor.dmi'
- icon_state = "implant"
- activated = 1
- origin_tech = "materials=2;biotech=3;magnets=4;bluespace=5;abductor=5"
- var/obj/machinery/abductor/pad/home
- var/cooldown = 30
-
-/obj/item/weapon/implant/abductor/activate()
- if(cooldown == initial(cooldown))
- home.Retrieve(imp_in,1)
- cooldown = 0
- processing_objects.Add(src)
- else
- to_chat(imp_in, "You must wait [30 - cooldown] seconds to use [src] again!")
- return
-
-/obj/item/weapon/implant/abductor/process()
- if(cooldown < initial(cooldown))
- cooldown++
- if(cooldown == initial(cooldown))
- processing_objects.Remove(src)
-
-/obj/item/weapon/implant/abductor/implant(var/mob/source, var/mob/user)
- if(..())
- var/obj/machinery/abductor/console/console
- if(ishuman(source))
- var/mob/living/carbon/human/H = source
- if(H.get_species() == "Abductor")
- console = get_team_console(H.mind.abductor.team)
- home = console.pad
-
- if(!home)
- console = get_team_console(pick(1, 2, 3, 4))
- home = console.pad
- return 1
-
-/obj/item/weapon/implant/abductor/proc/get_team_console(var/team)
- var/obj/machinery/abductor/console/console
- for(var/obj/machinery/abductor/console/c in abductor_equipment)
- if(c.team == team)
- console = c
- break
- return console
-
-/obj/item/weapon/gun/energy/decloner/alien
+/obj/item/weapon/gun/energy/alien
name = "alien pistol"
desc = "A complicated gun that fires bursts of high-intensity radiation."
+ ammo_type = list(/obj/item/ammo_casing/energy/declone)
+ restricted_species = list("Abductor")
icon_state = "alienpistol"
item_state = "alienpistol"
- origin_tech = "combat=5;materials=4;powerstorage=3;abductor=3"
- restricted_species = list("Abductor")
+ origin_tech = "combat=4;magnets=7;powerstorage=3;abductor=3"
+ trigger_guard = TRIGGER_GUARD_ALLOW_ALL
/obj/item/weapon/paper/abductor
name = "Dissection Guide"
@@ -321,25 +264,29 @@
1.Acquire fresh specimen.
- 2.Put the specimen on operating table
- 3.Apply scalpel to the chest, preparing for dissection
- 4.Apply scalpel to specimen torso
- 5.Clamp bleeders on the specimen's torso
- 6.Retract skin from specimen's torso
- 7.Saw through the specimen's torso
- 8.Retract skin from specimen's torso again
- 9.Search through the specimen's torso with your hands to remove their heart
- 10.Insert replacement gland (Retrieve one from gland storage)
- 11.Cauterize the patient's torso
- 12.Consider dressing the specimen back to not disturb the habitat
- 13.Put the specimen in the experiment machinery
- 14.Choose one of the machine options and follow displayed instructions
+ 2.Put the specimen on operating table.
+ 3.Apply scalpel to the chest, preparing for experimental dissection.
+ 4.Apply scalpel to specimen's torso.
+ 5.Clamp bleeders on specimen's torso with a hemostat.
+ 6.Retract skin of specimen's torso with a retractor.
+ 7.Saw through the specimen's torso with a saw.
+ 8.Apply retractor again to specimen's torso.
+ 9.Search through the specimen's torso with your hands to remove any superfluous organs.
+ 10.Insert replacement gland (Retrieve one from gland storage).
+ 11.Cauterize the patient's torso with a cautery.
+ 12.Consider dressing the specimen back to not disturb the habitat.
+ 13.Put the specimen in the experiment machinery.
+ 14.Choose one of the machine options. The target will be analyzed and teleported to the selected drop-off point.
+ 15.You will receive one supply credit, and the subject will be counted towards your quota.
-Congratulations! You are now trained for xenobiology research!"}
+Congratulations! You are now trained for invasive xenobiology research!"}
/obj/item/weapon/paper/abductor/update_icon()
return
+/obj/item/weapon/paper/abductor/AltClick()
+ return
+
#define BATON_STUN 0
#define BATON_SLEEP 1
#define BATON_CUFF 2
@@ -354,9 +301,9 @@ Congratulations! You are now trained for xenobiology research!"}
icon_state = "wonderprodStun"
item_state = "wonderprod"
slot_flags = SLOT_BELT
- origin_tech = "materials=6;combat=5;biotech=7;abductor=4"
+ origin_tech = "materials=4;combat=4;biotech=7;abductor=4"
force = 7
- w_class = 3
+ w_class = WEIGHT_CLASS_NORMAL
actions_types = list(/datum/action/item_action/toggle_mode)
/obj/item/weapon/abductor_baton/proc/toggle(mob/living/user=usr)
@@ -393,16 +340,8 @@ Congratulations! You are now trained for xenobiology research!"}
icon_state = "wonderprodProbe"
item_state = "wonderprodProbe"
-/obj/item/weapon/abductor_baton/proc/IsAbductor(mob/living/user)
- if(!ishuman(user))
- return 0
- var/mob/living/carbon/human/H = user
- if(H.get_species() != "Abductor")
- return 0
- return 1
-
/obj/item/weapon/abductor_baton/attack(mob/target, mob/living/user)
- if(!IsAbductor(user))
+ if(!isabductor(user))
return
if(isrobot(target))
@@ -434,7 +373,7 @@ Congratulations! You are now trained for xenobiology research!"}
/obj/item/weapon/abductor_baton/attack_self(mob/living/user)
toggle(user)
- if(istype(user,/mob/living/carbon/human))
+ if(ishuman(user))
var/mob/living/carbon/human/H = user
H.update_inv_l_hand()
H.update_inv_r_hand()
@@ -456,10 +395,9 @@ Congratulations! You are now trained for xenobiology research!"}
H.forcesay(hit_appends)
add_logs(user, L, "stunned")
- return
/obj/item/weapon/abductor_baton/proc/SleepAttack(mob/living/L,mob/living/user)
- if(L.stunned)
+ if(L.stunned || L.sleeping)
L.visible_message("[user] has induced sleep in [L] with [src]!", \
"You suddenly feel very drowsy!")
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
@@ -470,7 +408,6 @@ Congratulations! You are now trained for xenobiology research!"}
to_chat(user, "Sleep inducement works fully only on stunned specimens! ")
L.visible_message("[user] tried to induce sleep in [L] with [src]!", \
"You suddenly feel drowsy!")
- return
/obj/item/weapon/abductor_baton/proc/CuffAttack(mob/living/L,mob/living/user)
if(!iscarbon(L))
@@ -488,7 +425,6 @@ Congratulations! You are now trained for xenobiology research!"}
add_logs(user, C, "handcuffed")
else
to_chat(user, "You fail to handcuff [C].")
- return
/obj/item/weapon/abductor_baton/proc/ProbeAttack(mob/living/L,mob/living/user)
L.visible_message("[user] probes [L] with [src]!", \
@@ -502,7 +438,7 @@ Congratulations! You are now trained for xenobiology research!"}
species = "[H.species.name]"
if(L.mind && L.mind.changeling)
species = "Changeling lifeform"
- var/obj/item/organ/internal/gland/temp = locate() in H.internal_organs
+ var/obj/item/organ/internal/heart/gland/temp = locate() in H.internal_organs
if(temp)
helptext = "Experimental gland detected!"
else
@@ -517,7 +453,7 @@ Congratulations! You are now trained for xenobiology research!"}
icon_state = "cuff_white" // Needs sprite
breakouttime = 450
trashtype = /obj/item/weapon/restraints/handcuffs/energy/used
- origin_tech = "materials=2;magnets=5;abductor=2"
+ origin_tech = "materials=4;magnets=5;abductor=2"
/obj/item/weapon/restraints/handcuffs/energy/used
desc = "energy discharge"
@@ -545,33 +481,45 @@ Congratulations! You are now trained for xenobiology research!"}
/obj/item/weapon/scalpel/alien
name = "alien scalpel"
+ desc = "It's a gleaming sharp knife made out of silvery-green metal."
icon = 'icons/obj/abductor.dmi'
origin_tech = "materials=2;biotech=2;abductor=2"
+ toolspeed = 0.25
/obj/item/weapon/hemostat/alien
name = "alien hemostat"
+ desc = "You've never seen this before."
icon = 'icons/obj/abductor.dmi'
origin_tech = "materials=2;biotech=2;abductor=2"
+ toolspeed = 0.25
/obj/item/weapon/retractor/alien
name = "alien retractor"
+ desc = "You're not sure if you want the veil pulled back."
icon = 'icons/obj/abductor.dmi'
origin_tech = "materials=2;biotech=2;abductor=2"
+ toolspeed = 0.25
/obj/item/weapon/circular_saw/alien
name = "alien saw"
+ desc = "Do the aliens also lose this, and need to find an alien hatchet?"
icon = 'icons/obj/abductor.dmi'
origin_tech = "materials=2;biotech=2;abductor=2"
+ toolspeed = 0.25
/obj/item/weapon/surgicaldrill/alien
name = "alien drill"
+ desc = "Maybe alien surgeons have finally found a use for the drill."
icon = 'icons/obj/abductor.dmi'
origin_tech = "materials=2;biotech=2;abductor=2"
+ toolspeed = 0.25
/obj/item/weapon/cautery/alien
name = "alien cautery"
+ desc = "Why would bloodless aliens have a tool to stop bleeding? Unless..."
icon = 'icons/obj/abductor.dmi'
origin_tech = "materials=2;biotech=2;abductor=2"
+ toolspeed = 0.25
/obj/item/clothing/head/helmet/abductor
name = "agent headgear"
@@ -579,17 +527,12 @@ Congratulations! You are now trained for xenobiology research!"}
icon_state = "alienhelmet"
item_state = "alienhelmet"
blockTracking = 1
- origin_tech = "materials=6;magnets=5;abductor=3"
+ origin_tech = "materials=7;magnets=4;abductor=3"
flags = BLOCKHAIR
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
// Operating Table / Beds / Lockers
-/obj/machinery/optable/abductor
- icon = 'icons/obj/abductor.dmi'
- icon_state = "bed"
- no_icon_updates = 1 //no icon updates for this; it's static.
-
/obj/structure/stool/bed/abductor
name = "resting contraption"
desc = "This looks similar to contraptions from earth. Could aliens be stealing our technology?"
@@ -605,9 +548,9 @@ Congratulations! You are now trained for xenobiology research!"}
/obj/structure/abductor_tableframe/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/wrench))
to_chat(user, "You start disassembling [src]...")
- playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
- if(do_after(user, 30, target = src))
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, I.usesound, 50, 1)
+ if(do_after(user, 30 * I.toolspeed, target = src))
+ playsound(src.loc, I.usesound, 50, 1)
new /obj/item/stack/sheet/mineral/abductor(get_turf(src))
qdel(src)
return
@@ -617,11 +560,21 @@ Congratulations! You are now trained for xenobiology research!"}
to_chat(user, "You need one alien alloy sheet to do this!")
return
to_chat(user, "You start adding [P] to [src]...")
- if(do_after(user, 50, target = src))
+ if(do_after(user, 50 * I.toolspeed, target = src))
P.use(1)
new /obj/structure/table/abductor(src.loc)
qdel(src)
return
+ if(istype(I, /obj/item/stack/sheet/mineral/silver))
+ var/obj/item/stack/sheet/P = I
+ if(P.get_amount() < 1)
+ to_chat(user, "You need one sheet of silver to do this!")
+ return
+ to_chat(user, "You start adding [P] to [src]...")
+ if(do_after(user, 50, target = src))
+ P.use(1)
+ new /obj/machinery/optable/abductor(loc)
+ qdel(src)
/obj/structure/table/abductor
name = "alien table"
@@ -631,10 +584,15 @@ Congratulations! You are now trained for xenobiology research!"}
canSmoothWith = null
parts = /obj/item/stack/sheet/mineral/abductor
+/obj/machinery/optable/abductor
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "bed"
+ no_icon_updates = 1 //no icon updates for this; it's static.
+
/obj/structure/closet/abductor
name = "alien locker"
desc = "Contains secrets of the universe."
icon_state = "abductor"
icon_closed = "abductor"
icon_opened = "abductoropen"
- material_drop = /obj/item/stack/sheet/mineral/abductor
+ material_drop = /obj/item/stack/sheet/mineral/abductor
\ No newline at end of file
diff --git a/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm
index 6021140b79f..18d073d6077 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm
@@ -15,9 +15,9 @@
return 0
var/mob/living/carbon/human/H = user
// You must either: Be of the abductor species, or contain an abductor implant
- if(!(H.get_species() == "Abductor" || (locate(/obj/item/weapon/implant/abductor) in H)))
- return 0
- return 1
+ if((H.get_species() == "Abductor" || (locate(/obj/item/weapon/implant/abductor) in H)))
+ return 1
+ return 0
/datum/surgery_step/internal/extract_organ
@@ -47,11 +47,11 @@
return 1
else
to_chat(user, "You don't find anything in [target]'s [target_zone]!")
- return 0
+ return 1
/datum/surgery_step/internal/gland_insert
name = "insert gland"
- allowed_tools = list(/obj/item/organ/internal/gland = 100)
+ allowed_tools = list(/obj/item/organ/internal/heart/gland = 100)
time = 32
/datum/surgery_step/internal/gland_insert/begin_step(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -61,6 +61,6 @@
/datum/surgery_step/internal/gland_insert/end_step(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
user.visible_message("[user] inserts [tool] into [target].", "You insert [tool] into [target].")
user.drop_item()
- var/obj/item/organ/internal/gland/gland = tool
+ var/obj/item/organ/internal/heart/gland/gland = tool
gland.insert(target, 2)
return 1
diff --git a/code/game/gamemodes/miniantags/abduction/gland.dm b/code/game/gamemodes/miniantags/abduction/gland.dm
index b59f1fd8454..1c481e7c333 100644
--- a/code/game/gamemodes/miniantags/abduction/gland.dm
+++ b/code/game/gamemodes/miniantags/abduction/gland.dm
@@ -1,12 +1,11 @@
-/obj/item/organ/internal/gland
+/obj/item/organ/internal/heart/gland
name = "fleshy mass"
desc = "A nausea-inducing hunk of twisting flesh and metal."
icon = 'icons/obj/abductor.dmi'
- parent_organ = "chest"
- slot = "gland"
icon_state = "gland"
status = ORGAN_ROBOT
- origin_tech = "materials=4;biotech=5;abductor=3"
+ origin_tech = "materials=4;biotech=7;abductor=3"
+ beating = TRUE
var/cooldown_low = 300
var/cooldown_high = 300
var/next_activation = 0
@@ -16,30 +15,33 @@
tough = 1 //not easily broken by combat damage
sterile = 1 //not very germy
-/obj/item/organ/internal/gland/proc/ownerCheck()
+/obj/item/organ/internal/heart/gland/proc/ownerCheck()
if(ishuman(owner))
return 1
if(!human_only && iscarbon(owner))
return 1
return 0
-/obj/item/organ/internal/gland/proc/Start()
+/obj/item/organ/internal/heart/gland/proc/Start()
active = 1
next_activation = world.time + rand(cooldown_low,cooldown_high)
-/obj/item/organ/internal/gland/remove(var/mob/living/carbon/M, special = 0)
+/obj/item/organ/internal/heart/gland/remove(var/mob/living/carbon/M, special = 0)
active = 0
if(initial(uses) == 1)
uses = initial(uses)
- ..()
+ . = ..()
-/obj/item/organ/internal/gland/insert(var/mob/living/carbon/M, special = 0)
+/obj/item/organ/internal/heart/gland/insert(var/mob/living/carbon/M, special = 0)
..()
if(special != 2 && uses) // Special 2 means abductor surgery
Start()
-/obj/item/organ/internal/gland/on_life()
+/obj/item/organ/internal/heart/gland/on_life()
+ if(!beating)
+ // alien glands are immune to stopping.
+ beating = TRUE
if(!active)
return
if(!ownerCheck())
@@ -52,30 +54,28 @@
if(!uses)
active = 0
-/obj/item/organ/internal/gland/proc/activate()
+/obj/item/organ/internal/heart/gland/proc/activate()
return
-/obj/item/organ/internal/gland/heals
- origin_tech = "materials=4;biotech=6;abductor=3"
+/obj/item/organ/internal/heart/gland/heals
cooldown_low = 200
cooldown_high = 400
uses = -1
icon_state = "health"
-/obj/item/organ/internal/gland/heals/activate()
+/obj/item/organ/internal/heart/gland/heals/activate()
to_chat(owner, "You feel curiously revitalized.")
owner.adjustBruteLoss(-20)
owner.adjustOxyLoss(-20)
owner.adjustFireLoss(-20)
-/obj/item/organ/internal/gland/slime
- origin_tech = "materials=4;biotech=6;abductor=3"
+/obj/item/organ/internal/heart/gland/slime
cooldown_low = 600
cooldown_high = 1200
uses = -1
icon_state = "slime"
-/obj/item/organ/internal/gland/slime/activate()
+/obj/item/organ/internal/heart/gland/slime/activate()
to_chat(owner, "You feel nauseous!")
owner.vomit(20)
@@ -83,14 +83,14 @@
Slime.Friends = list(owner)
Slime.Leader = owner
-/obj/item/organ/internal/gland/mindshock
- origin_tech = "materials=4;biotech=5;magnets=3;abductor=3"
+/obj/item/organ/internal/heart/gland/mindshock
+ origin_tech = "materials=4;biotech=4;magnets=6;abductor=3"
cooldown_low = 300
cooldown_high = 300
uses = -1
icon_state = "mindshock"
-/obj/item/organ/internal/gland/mindshock/activate()
+/obj/item/organ/internal/heart/gland/mindshock/activate()
to_chat(owner, "You get a headache.")
var/turf/T = get_turf(owner)
@@ -100,40 +100,37 @@
to_chat(H, "You hear a buzz in your head.")
H.AdjustConfused(20)
-/obj/item/organ/internal/gland/pop
- origin_tech = "materials=4;biotech=6;abductor=3"
+/obj/item/organ/internal/heart/gland/pop
cooldown_low = 900
cooldown_high = 1800
- uses = 6
+ uses = -1
human_only = 1
icon_state = "species"
-/obj/item/organ/internal/gland/pop/activate()
+/obj/item/organ/internal/heart/gland/pop/activate()
to_chat(owner, "You feel unlike yourself.")
var/species = pick("Unathi","Skrell","Diona","Tajaran","Vulpkanin","Kidan","Grey","Diona")
owner.set_species(species)
-/obj/item/organ/internal/gland/ventcrawling
+/obj/item/organ/internal/heart/gland/ventcrawling
origin_tech = "materials=4;biotech=5;bluespace=3;abductor=3"
cooldown_low = 1800
cooldown_high = 2400
uses = 1
icon_state = "vent"
-/obj/item/organ/internal/gland/ventcrawling/activate()
+/obj/item/organ/internal/heart/gland/ventcrawling/activate()
to_chat(owner, "You feel very stretchy.")
owner.ventcrawler = 2
- return
-/obj/item/organ/internal/gland/viral
- origin_tech = "materials=4;biotech=6;abductor=3"
+/obj/item/organ/internal/heart/gland/viral
cooldown_low = 1800
cooldown_high = 2400
uses = 1
icon_state = "viral"
-/obj/item/organ/internal/gland/viral/activate()
+/obj/item/organ/internal/heart/gland/viral/activate()
to_chat(owner, "You feel sick.")
var/virus_type = pick(/datum/disease/beesease, /datum/disease/brainrot, /datum/disease/magnitis)
var/datum/disease/D = new virus_type()
@@ -144,51 +141,49 @@
owner.med_hud_set_status()
-/obj/item/organ/internal/gland/emp //TODO : Replace with something more interesting
- origin_tech = "materials=4;biotech=5;magnets=3;abductor=3"
+/obj/item/organ/internal/heart/gland/emp //TODO : Replace with something more interesting
+ origin_tech = "materials=4;biotech=4;magnets=6;abductor=3"
cooldown_low = 900
cooldown_high = 1600
uses = 10
icon_state = "emp"
-/obj/item/organ/internal/gland/emp/activate()
+/obj/item/organ/internal/heart/gland/emp/activate()
to_chat(owner, "You feel a spike of pain in your head.")
empulse(get_turf(owner), 2, 5, 1)
-/obj/item/organ/internal/gland/spiderman
- origin_tech = "materials=4;biotech=6;abductor=3"
+/obj/item/organ/internal/heart/gland/spiderman
cooldown_low = 450
cooldown_high = 900
uses = 10
icon_state = "spider"
-/obj/item/organ/internal/gland/spiderman/activate()
+/obj/item/organ/internal/heart/gland/spiderman/activate()
to_chat(owner, "You feel something crawling in your skin.")
owner.faction |= "spiders"
- new /obj/effect/spider/spiderling(owner.loc)
+ new /obj/structure/spider/spiderling(owner.loc)
-/obj/item/organ/internal/gland/egg
- origin_tech = "materials=4;biotech=6;abductor=3"
+/obj/item/organ/internal/heart/gland/egg
cooldown_low = 300
cooldown_high = 400
uses = -1
icon_state = "egg"
-/obj/item/organ/internal/gland/egg/activate()
+/obj/item/organ/internal/heart/gland/egg/activate()
to_chat(owner, "You lay an egg!")
var/obj/item/weapon/reagent_containers/food/snacks/egg/egg = new(owner.loc)
egg.reagents.add_reagent("sacid",20)
egg.desc += " It smells bad."
-/obj/item/organ/internal/gland/bloody
- origin_tech = "materials=4;biotech=6;abductor=3"
+/obj/item/organ/internal/heart/gland/bloody
cooldown_low = 200
cooldown_high = 400
uses = -1
-/obj/item/organ/internal/gland/bloody/activate()
- owner.adjustBruteLoss(15)
-
+/obj/item/organ/internal/heart/gland/bloody/activate()
+ if(ishuman(owner))
+ var/mob/living/carbon/human/H = owner
+ H.drip(200)
owner.visible_message("[owner]'s skin erupts with blood!",\
"Blood pours from your skin!")
@@ -202,22 +197,22 @@
H.w_uniform.add_blood(owner)
H.update_inv_w_uniform(0)
-/obj/item/organ/internal/gland/bodysnatch
- origin_tech = "materials=4;biotech=7;abductor=3"
+/obj/item/organ/internal/heart/gland/bodysnatch
cooldown_low = 600
cooldown_high = 600
human_only = 1
uses = 1
-/obj/item/organ/internal/gland/bodysnatch/activate()
+/obj/item/organ/internal/heart/gland/bodysnatch/activate()
to_chat(owner, "You feel something moving around inside you...")
//spawn cocoon with clone greytide snpc inside
if(ishuman(owner))
var/obj/effect/cocoon/abductor/C = new (get_turf(owner))
C.Copy(owner)
C.Start()
- owner.gib()
- return
+ owner.adjustBruteLoss(40)
+ var/turf/T = get_turf(owner)
+ T.add_blood_floor(src)
/obj/effect/cocoon/abductor
name = "slimy cocoon"
@@ -232,11 +227,18 @@
var/mob/living/carbon/human/interactive/greytide/clone = new(src)
var/datum/dna/owner_dna = H.dna
clone.rename_character(clone.name, owner_dna.real_name)
- clone.body_accessory = H.body_accessory
clone.dna = owner_dna.Clone()
clone.set_species(H.species.name)
+ clone.body_accessory = H.body_accessory
domutcheck(clone)
+ for(var/obj/item/I in clone)
+ if(istype(I, /obj/item/weapon/implant))
+ continue
+ if(istype(I, /obj/item/organ))
+ continue
+ qdel(I)
+
//There's no define for this / get all items ?
var/list/slots = list(slot_back,slot_w_uniform,slot_wear_suit,\
slot_wear_mask,slot_head,slot_shoes,slot_gloves,slot_l_ear,slot_r_ear,\
@@ -245,7 +247,7 @@
for(var/slot in slots)
var/obj/item/I = H.get_item_by_slot(slot)
if(I)
- clone.equip_to_slot_if_possible(I,slot)
+ clone.equip_to_slot_or_del(new I.type(clone), slot)
/obj/effect/cocoon/abductor/proc/Start()
hatch_time = world.time + 600
@@ -259,22 +261,25 @@
M.forceMove(get_turf(src))
qdel(src)
-/obj/item/organ/internal/gland/plasma
- cooldown_low = 2400
- cooldown_high = 3000
- origin_tech = "materials=4;biotech=5;plasmatech=3;abductor=3"
- uses = 1
-/obj/item/organ/internal/gland/plasma/activate()
- to_chat(owner, "You feel bloated.")
- sleep(150)
- if(!owner) return
- to_chat(owner, "A massive stomachache overcomes you.")
- sleep(50)
- if(!owner) return
- owner.visible_message("[owner] explodes in a cloud of plasma!")
- var/turf/simulated/T = get_turf(owner)
- if(istype(T))
- T.atmos_spawn_air(SPAWN_TOXINS|SPAWN_20C,300)
- owner.gib()
- return
+/obj/item/organ/internal/heart/gland/plasma
+ cooldown_low = 1200
+ cooldown_high = 1800
+ origin_tech = "materials=4;biotech=4;plasmatech=6;abductor=3"
+ uses = -1
+
+/obj/item/organ/internal/heart/gland/plasma/activate()
+ spawn(0)
+ to_chat(owner, "You feel bloated.")
+ sleep(150)
+ if(!owner)
+ return
+ to_chat(owner, "A massive stomachache overcomes you.")
+ sleep(50)
+ if(!owner)
+ return
+ owner.visible_message("[owner] vomits a cloud of plasma!")
+ var/turf/simulated/T = get_turf(owner)
+ if(istype(T))
+ T.atmos_spawn_air(SPAWN_TOXINS|SPAWN_20C,50)
+ owner.vomit()
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/camera.dm b/code/game/gamemodes/miniantags/abduction/machinery/camera.dm
index 24b02aea489..219ae4b6e54 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/camera.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/camera.dm
@@ -49,15 +49,12 @@
set_droppoint_action.target = console
set_droppoint_action.Grant(user)
-/obj/machinery/computer/camera_advanced/abductor/proc/IsAbductor(mob/living/carbon/human/H)
- return H.get_species() == "Abductor"
-
/obj/machinery/computer/camera_advanced/abductor/proc/IsScientist(mob/living/carbon/human/H)
if(H.mind && H.mind.abductor)
return H.mind.abductor.scientist
/obj/machinery/computer/camera_advanced/abductor/attack_hand(mob/user)
- if(!iscarbon(user) || !IsAbductor(user))
+ if(!isabductor(user))
return
return ..()
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/console.dm b/code/game/gamemodes/miniantags/abduction/machinery/console.dm
index ddac0731249..3a93f8abc75 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/console.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/console.dm
@@ -11,21 +11,6 @@
abductor_equipment.Remove(src)
return ..()
-/obj/machinery/abductor/proc/IsAbductor(mob/living/carbon/human/H)
- return H.get_species() == "Abductor"
-
-/obj/machinery/abductor/proc/IsAgent(mob/living/carbon/human/H)
- if(H.get_species() == "Abductor")
- if(H.mind && H.mind.abductor)
- return H.mind.abductor.agent
- return 0
-
-/obj/machinery/abductor/proc/IsScientist(mob/living/carbon/human/H)
- if(H.get_species() == "Abductor")
- if(H.mind && H.mind.abductor)
- return H.mind.abductor.scientist
- return 0
-
//Console
/obj/machinery/abductor/console
@@ -33,8 +18,8 @@
desc = "Ship command center."
icon = 'icons/obj/abductor.dmi'
icon_state = "console"
- density = 1
- anchored = 1
+ density = TRUE
+ anchored = TRUE
var/obj/item/device/abductor/gizmo/gizmo
var/obj/item/clothing/suit/armor/abductor/vest/vest
var/obj/machinery/abductor/experiment/experiment
@@ -49,9 +34,9 @@
/obj/machinery/abductor/console/attack_hand(mob/user)
if(..())
return
- if(!IsAbductor(user))
+ if(!isabductor(user))
to_chat(user, "You start mashing alien buttons at random!")
- if(do_after(user,100, target = src))
+ if(do_after(user, 100, target = src))
TeleporterSend()
return
user.set_machine(src)
@@ -60,10 +45,13 @@
if(experiment != null)
var/points = experiment.points
+ var/credits = experiment.credits
dat += "Collected Samples : [points] "
+ dat += "Gear Credits: [credits] "
dat += "Transfer data in exchange for supplies: "
dat += "Advanced Baton "
dat += "Agent Helmet "
+ dat += "Agent Vest "
dat += "Radio Silencer "
dat += "Science Tool "
else
@@ -92,13 +80,13 @@
dat+=" "
dat += "Select Agent Vest Disguise "
+ dat += "[vest.flags & NODROP ? "Unlock" : "Lock"] Vest "
else
dat += "NO AGENT VEST DETECTED"
var/datum/browser/popup = new(user, "computer", "Abductor Console", 400, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
- return
/obj/machinery/abductor/console/Topic(href, href_list)
if(..())
@@ -111,6 +99,8 @@
TeleporterRetrieve()
else if(href_list["flip_vest"])
FlipVest()
+ else if(href_list["toggle_vest"])
+ toggle_vest()
else if(href_list["select_disguise"])
SelectDisguise()
else if(href_list["dispense"])
@@ -123,37 +113,28 @@
Dispense(/obj/item/device/abductor/silencer)
if("tool")
Dispense(/obj/item/device/abductor/gizmo)
- src.updateUsrDialog()
+ if("vest")
+ Dispense(/obj/item/clothing/suit/armor/abductor/vest)
+ updateUsrDialog()
/obj/machinery/abductor/console/proc/TeleporterRetrieve()
if(gizmo!=null && pad!=null && gizmo.marked)
pad.Retrieve(gizmo.marked)
- return
/obj/machinery/abductor/console/proc/TeleporterSend()
if(pad!=null)
pad.Send()
- return
/obj/machinery/abductor/console/proc/FlipVest()
if(vest!=null)
vest.flip_mode()
- return
-/obj/machinery/abductor/console/proc/SelectDisguise(remote=0)
- var/list/entries = list()
- var/tempname
- var/datum/icon_snapshot/temp
- for(var/i = 1; i <= disguises.len; i++)
- temp = disguises[i]
- tempname = temp.name
- entries["[tempname]"] = disguises[i]
- var/entry_name = input( "Choose Disguise", "Disguise") in entries
- var/datum/icon_snapshot/chosen = entries[entry_name]
+/obj/machinery/abductor/console/proc/SelectDisguise(remote = 0)
+ var/entry_name = input( "Choose Disguise", "Disguise") as null|anything in disguises
+ var/datum/icon_snapshot/chosen = disguises[entry_name]
if(chosen && (remote || in_range(usr,src)))
vest.SetDisguise(chosen)
- return
/obj/machinery/abductor/console/proc/SetDroppoint(turf/location,user)
if(!istype(location))
@@ -188,13 +169,11 @@
entry.icon = target.icon
entry.icon_state = target.icon_state
entry.overlays = target.get_overlays_copy(list(L_HAND_LAYER,R_HAND_LAYER))
- for(var/i=1,i<=disguises.len,i++)
- var/datum/icon_snapshot/temp = disguises[i]
- if(temp.name == entry.name)
- disguises[i] = entry
- return
- disguises.Add(entry)
- return
+ //Update old disguise instead of adding new one
+ if(disguises[entry.name])
+ disguises[entry.name] = entry
+ return
+ disguises[entry.name] = entry
/obj/machinery/abductor/console/attackby(obj/O, mob/user, params)
if(istype(O, /obj/item/device/abductor/gizmo))
@@ -205,13 +184,16 @@
else if(istype(O, /obj/item/clothing/suit/armor/abductor/vest))
var/obj/item/clothing/suit/armor/abductor/vest/V = O
to_chat(user, "You link the vest to the console.")
+ if(istype(vest))
+ if(vest.flags & NODROP)
+ toggle_vest()
vest = V
else
..()
/obj/machinery/abductor/console/proc/Dispense(item,cost=1)
- if(experiment && experiment.points >= cost)
- experiment.points-=cost
+ if(experiment && experiment.credits >= cost)
+ experiment.credits -=cost
atom_say("Incoming supply!")
if(pad)
flick("alien-pad", pad)
@@ -220,4 +202,9 @@
new item(src.loc)
else
atom_say("Insufficent data!")
- return
+
+/obj/machinery/abductor/console/proc/toggle_vest()
+ vest.flags ^= NODROP
+ var/mob/M = vest.loc
+ if(istype(M))
+ to_chat(M, "[src] is now [vest.flags & NODROP ? "locked" : "unlocked"].")
\ No newline at end of file
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm
index 4ead0232a2f..2b6103632f5 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm
@@ -14,7 +14,8 @@
return rgb(rand(0,255),rand(0,255),rand(0,255))
/obj/machinery/abductor/gland_dispenser/New()
- gland_types = subtypesof(/obj/item/organ/internal/gland)
+ ..()
+ gland_types = subtypesof(/obj/item/organ/internal/heart/gland)
gland_types = shuffle(gland_types)
gland_colors = new/list(gland_types.len)
amounts = new/list(gland_types.len)
@@ -25,7 +26,7 @@
/obj/machinery/abductor/gland_dispenser/attack_hand(mob/user)
if(..())
return
- if(!IsAbductor(user))
+ if(!isabductor(user))
return
user.set_machine(src)
var/box_css = {"
@@ -59,13 +60,15 @@
return
/obj/machinery/abductor/gland_dispenser/attackby(obj/item/weapon/W, mob/user, params)
- if(istype(W, /obj/item/organ/internal/gland))
+ if(istype(W, /obj/item/organ/internal/heart/gland))
if(!user.drop_item())
return
W.forceMove(src)
for(var/i=1,i<=gland_colors.len,i++)
if(gland_types[i] == W.type)
amounts[i]++
+ else
+ ..()
/obj/machinery/abductor/gland_dispenser/Topic(href, href_list)
if(..())
@@ -74,7 +77,7 @@
if(href_list["dispense"])
Dispense(text2num(href_list["dispense"]))
- src.updateUsrDialog()
+ updateUsrDialog()
/obj/machinery/abductor/gland_dispenser/proc/Dispense(count)
if(amounts[count]>0)
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
index 755bd21e2e5..44b2a431c7b 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
@@ -6,6 +6,7 @@
anchored = 1
density = 1
var/points = 0
+ var/credits = 0
var/list/history = list()
var/list/abductee_minds = list()
var/flash = " - || - "
@@ -19,10 +20,10 @@
/obj/machinery/abductor/experiment/MouseDrop_T(mob/living/carbon/human/target, mob/user)
if(user.stat || user.lying || !Adjacent(user) || !target.Adjacent(user) || !ishuman(target))
return
- if(IsAbductor(target))
+ if(isabductor(target))
return
if(occupant)
- to_chat(user, "\The [src] is already occupied.")
+ to_chat(user, "[src] is already occupied.")
return //occupied
if(target.buckled)
return
@@ -118,7 +119,7 @@
if(H.stat == DEAD)
atom_say("Specimen deceased - please provide fresh sample.")
return "Specimen deceased."
- var/obj/item/organ/internal/gland/GlandTest = locate() in H.internal_organs
+ var/obj/item/organ/internal/heart/gland/GlandTest = locate() in H.internal_organs
if(!GlandTest)
atom_say("Experimental dissection not detected!")
return "No glands detected!"
@@ -147,7 +148,7 @@
obj_count++
ticker.mode.update_abductor_icons_added(H.mind)
- for(var/obj/item/organ/internal/gland/G in H.internal_organs)
+ for(var/obj/item/organ/internal/heart/gland/G in H.internal_organs)
G.Start()
point_reward++
if(point_reward > 0)
@@ -155,6 +156,7 @@
SendBack(H)
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
points += point_reward
+ credits += point_reward
return "Experiment successful! [point_reward] new data-points collected."
else
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 1)
@@ -183,7 +185,7 @@
var/obj/item/weapon/grab/grabbed = G
if(!ishuman(grabbed.affecting))
return
- if(IsAbductor(grabbed.affecting))
+ if(isabductor(grabbed.affecting))
return
if(occupant)
to_chat(user, "The [src] is already occupied!")
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/pad.dm b/code/game/gamemodes/miniantags/abduction/machinery/pad.dm
index 285b097d06a..f0ceac0d6ce 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/pad.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/pad.dm
@@ -17,6 +17,8 @@
target.forceMove(teleport_target)
spawn(0)
anim(target.loc,target,'icons/mob/mob.dmi',,"uncloak",,target.dir)
+ to_chat(target, "The instability of the warp leaves you disoriented!")
+ target.Stun(3)
/obj/machinery/abductor/pad/proc/Retrieve(mob/living/target)
flick("alien-pad", src)
diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm
index 16f7a4e0847..ea92b93f473 100644
--- a/code/game/gamemodes/miniantags/borer/borer.dm
+++ b/code/game/gamemodes/miniantags/borer/borer.dm
@@ -2,11 +2,11 @@
name = "host brain"
real_name = "host brain"
-/mob/living/captive_brain/say(var/message)
+/mob/living/captive_brain/say(message)
if(client)
if(client.prefs.muted & MUTE_IC)
- to_chat(src, "\red You cannot speak in IC (muted).")
+ to_chat(src, "You cannot speak in IC (muted).")
return
if(client.handle_spam_prevention(message,MUTE_IC))
return
@@ -43,7 +43,7 @@
to_chat(B.host, "You feel the captive mind of [src] begin to resist your control.")
var/delay = (rand(350,450) + B.host.brainloss)
- addtimer(src, "return_control", delay)
+ addtimer(src, "return_control", delay, FALSE, B)
/mob/living/captive_brain/proc/return_control(mob/living/simple_animal/borer/B)
if(!B || !B.controlling)
@@ -53,7 +53,7 @@
to_chat(src, "With an immense exertion of will, you regain control of your body!")
to_chat(B.host, "You feel control of the host brain ripped from your grasp, and retract your probosci before the wild neural impulses can damage you.")
- B.detatch()
+ B.detach()
/mob/living/simple_animal/borer
name = "cortical borer"
@@ -145,7 +145,7 @@
if(client.statpanel == "Status")
stat("Chemicals", chemicals)
-/mob/living/simple_animal/borer/say(message)
+/mob/living/simple_animal/borer/say(var/message)
var/datum/language/dialect = parse_language(message)
if(!dialect)
dialect = get_default_language()
@@ -250,16 +250,16 @@
if(host.reagents.has_reagent("sugar"))
if(!docile)
if(controlling)
- to_chat(host, "\blue You feel the soporific flow of sugar in your host's blood, lulling you into docility.")
+ to_chat(host, "You feel the soporific flow of sugar in your host's blood, lulling you into docility.")
else
- to_chat(src, "\blue You feel the soporific flow of sugar in your host's blood, lulling you into docility.")
+ to_chat(src, "You feel the soporific flow of sugar in your host's blood, lulling you into docility.")
docile = TRUE
else
if(docile)
if(controlling)
- to_chat(host, "\blue You shake off your lethargy as the sugar leaves your host's blood.")
+ to_chat(host, "You shake off your lethargy as the sugar leaves your host's blood.")
else
- to_chat(src, "\blue You shake off your lethargy as the sugar leaves your host's blood.")
+ to_chat(src, "You shake off your lethargy as the sugar leaves your host's blood.")
docile = FALSE
if(chemicals < max_chems)
@@ -267,7 +267,7 @@
if(controlling)
if(docile)
- to_chat(host, "\blue You are feeling far too docile to continue controlling your host...")
+ to_chat(host, "You are feeling far too docile to continue controlling your host...")
host.release_control()
return
@@ -322,7 +322,7 @@
to_chat(src, "You slither up [M] and begin probing at their ear canal...")
- if(!do_after(src,50, target = M))
+ if(!do_after(src, 50, target = M))
to_chat(src, "As [M] moves away, you are dislodged and fall to the ground.")
return
@@ -457,11 +457,11 @@
if(!hiding)
layer = TURF_LAYER+0.2
- to_chat(src, "\green You are now hiding.")
+ to_chat(src, "You are now hiding.")
hiding = TRUE
else
layer = MOB_LAYER
- to_chat(src, "\green You stop hiding.")
+ to_chat(src, "You stop hiding.")
hiding = FALSE
/mob/living/simple_animal/borer/verb/dominate_victim()
@@ -499,8 +499,8 @@
to_chat(src, "You cannot dominate someone who is already infested!")
return
- to_chat(src, "\red You focus your psychic lance on [M] and freeze their limbs with a wave of terrible dread.")
- to_chat(M, "\red You feel a creeping, horrible sense of dread come over you, freezing your limbs and setting your heart racing.")
+ to_chat(src, "You focus your psychic lance on [M] and freeze their limbs with a wave of terrible dread.")
+ to_chat(M, "You feel a creeping, horrible sense of dread come over you, freezing your limbs and setting your heart racing.")
M.Weaken(3)
used_dominate = world.time
@@ -519,7 +519,7 @@
return
if(docile)
- to_chat(src, "\blue You are feeling far too docile to do that.")
+ to_chat(src, "You are feeling far too docile to do that.")
return
if(!host || !src)
@@ -558,7 +558,7 @@
if(!host)
return
if(controlling)
- detatch()
+ detach()
GrantBorerActions()
RemoveInfestActions()
forceMove(get_turf(host))
@@ -594,7 +594,7 @@
return
if(docile)
- to_chat(src, "\blue You are feeling far too docile to do that.")
+ to_chat(src, "You are feeling far too docile to do that.")
return
if(bonding)
@@ -702,7 +702,7 @@
if(B && B.host_brain)
to_chat(src, "You withdraw your probosci, releasing control of [B.host_brain]")
- B.detatch()
+ B.detach()
else
log_runtime(EXCEPTION("Missing borer or missing host brain upon borer release."), src)
@@ -739,7 +739,7 @@
to_chat(src, "You need 100 chemicals to reproduce!")
return
-/mob/living/simple_animal/borer/proc/detatch()
+/mob/living/simple_animal/borer/proc/detach()
if(!host || !controlling)
return
@@ -815,7 +815,7 @@
to_chat(src, "You are a cortical borer!")
to_chat(src, "You are a brain slug that worms its way into the head of its victim. Use stealth, persuasion and your powers of mind control to keep you, your host and your eventual spawn safe and warm.")
to_chat(src, "Sugar nullifies your abilities, avoid it at all costs!")
- to_chat(src, "You can speak to your fellow borers by prefixing your messages with ':x'. Check out your Borer tab to see your abilities.")
+ to_chat(src, "You can speak to your fellow borers by prefixing your messages with ':bo'. Check out your Borer tab to see your abilities.")
/proc/create_borer_mind(key)
var/datum/mind/M = new /datum/mind(key)
diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
index 70b5f82172f..c6ea23c4bbc 100644
--- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
+++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
@@ -269,7 +269,7 @@
resources++
do_attack_animation(target)
changeNext_move(CLICK_CD_MELEE)
- var/obj/effect/swarmer/integrate/I = new /obj/effect/swarmer/integrate(get_turf(target))
+ var/obj/structure/swarmer/integrate/I = new /obj/structure/swarmer/integrate(get_turf(target))
I.pixel_x = target.pixel_x
I.pixel_y = target.pixel_y
if(istype(target, /obj/item/stack))
@@ -283,7 +283,7 @@
return
/mob/living/simple_animal/hostile/swarmer/proc/DisIntegrate(var/atom/movable/target)
- new /obj/effect/swarmer/disintegration(get_turf(target))
+ new /obj/structure/swarmer/disintegration(get_turf(target))
do_attack_animation(target)
changeNext_move(CLICK_CD_MELEE)
target.ex_act(3)
@@ -317,12 +317,12 @@
/mob/living/simple_animal/hostile/swarmer/proc/DismantleMachine(var/obj/machinery/target)
do_attack_animation(target)
to_chat(src, "We begin to dismantle this machine. We will need to be uninterrupted.")
- var/obj/effect/swarmer/dismantle/D = new /obj/effect/swarmer/dismantle(get_turf(target))
+ var/obj/structure/swarmer/dismantle/D = new /obj/structure/swarmer/dismantle(get_turf(target))
D.pixel_x = target.pixel_x
D.pixel_y = target.pixel_y
if(do_mob(src, target, 100))
if(!src.Adjacent(target))
- to_chat(src, "Error:Dismantleing aborted.")
+ to_chat(src, "Error:Dismantling aborted.")
else
to_chat(src, "Dismantling complete.")
var/obj/item/stack/sheet/metal/M = new /obj/item/stack/sheet/metal(target.loc)
@@ -330,7 +330,7 @@
if(target.component_parts && target.component_parts.len)
for(var/obj/item/I in target.component_parts)
I.forceMove(M.loc)
- var/obj/effect/swarmer/disintegration/N = new /obj/effect/swarmer/disintegration(get_turf(target))
+ var/obj/structure/swarmer/disintegration/N = new /obj/structure/swarmer/disintegration(get_turf(target))
N.pixel_x = target.pixel_x
N.pixel_y = target.pixel_y
target.dropContents()
@@ -342,74 +342,72 @@
-/obj/effect/swarmer //Default swarmer effect object visual feedback
+/obj/structure/swarmer //Default swarmer effect object visual feedback
name = "swarmer ui"
desc = null
gender = NEUTER
icon = 'icons/mob/swarmer.dmi'
icon_state = "ui_light"
- mouse_opacity = 0
- layer = 4
+ layer = MOB_LAYER
+ anchored = 1
unacidable = 1
-
-/obj/effect/swarmer/disintegration
- icon_state = "disintegrate"
-
-/obj/effect/swarmer/disintegration/New()
- playsound(src.loc, "sparks", 100, 1)
- spawn(10)
- qdel(src)
-
-/obj/effect/swarmer/dismantle
- icon_state = "dismantle"
-
-/obj/effect/swarmer/dismantle/New()
- spawn(25)
- qdel(src)
-
-/obj/effect/swarmer/integrate
- icon_state = "integrate"
-
-/obj/effect/swarmer/integrate/New()
- spawn(5)
- qdel(src)
-
-/obj/effect/swarmer/destructible //Default destroyable object for swarmer constructions
light_range = 1
mouse_opacity = 1
var/health = 30
-/obj/effect/swarmer/destructible/proc/TakeDamage(damage)
+/obj/structure/swarmer/disintegration
+ icon_state = "disintegrate"
+
+/obj/structure/swarmer/disintegration/New()
+ playsound(src.loc, "sparks", 100, 1)
+ spawn(10)
+ qdel(src)
+
+/obj/structure/swarmer/dismantle
+ icon_state = "dismantle"
+
+/obj/structure/swarmer/dismantle/New()
+ spawn(25)
+ qdel(src)
+
+/obj/structure/swarmer/integrate
+ icon_state = "integrate"
+
+/obj/structure/swarmer/integrate/New()
+ spawn(5)
+ qdel(src)
+
+/obj/structure/swarmer/proc/TakeDamage(damage)
health -= damage
if(health <= 0)
qdel(src)
-/obj/effect/swarmer/destructible/bullet_act(obj/item/projectile/Proj)
+/obj/structure/swarmer/bullet_act(obj/item/projectile/Proj)
if(Proj.damage)
if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
TakeDamage(Proj.damage)
..()
-/obj/effect/swarmer/destructible/attackby(obj/item/weapon/I, mob/living/user, params)
+/obj/structure/swarmer/attackby(obj/item/weapon/I, mob/living/user, params)
if(istype(I, /obj/item/weapon))
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
TakeDamage(I.force)
return
-/obj/effect/swarmer/destructible/ex_act()
+/obj/structure/swarmer/ex_act()
qdel(src)
return
-/obj/effect/swarmer/destructible/blob_act()
+/obj/structure/swarmer/blob_act()
qdel(src)
return
-/obj/effect/swarmer/destructible/emp_act()
+/obj/structure/swarmer/emp_act()
qdel(src)
return
-/obj/effect/swarmer/destructible/attack_animal(mob/living/user)
+/obj/structure/swarmer/attack_animal(mob/living/user)
if(isanimal(user))
var/mob/living/simple_animal/S = user
S.do_attack_animation(src)
@@ -418,24 +416,14 @@
TakeDamage(rand(S.melee_damage_lower, S.melee_damage_upper))
return
-/mob/living/simple_animal/hostile/swarmer/proc/CreateTrap()
- set name = "Create trap"
- set category = "Swarmer"
- set desc = "Creates a simple trap that will non-lethally electrocute anything that steps on it. Costs 5 resources"
- if(/obj/effect/swarmer/destructible/trap in loc)
- to_chat(src, "There is already a trap here. Aborting.")
- return
- Fabricate(/obj/effect/swarmer/destructible/trap, 5)
- return
-
-/obj/effect/swarmer/destructible/trap
+/obj/structure/swarmer/trap
name = "swarmer trap"
desc = "A quickly assembled trap that electrifies living beings and overwhelms machine sensors. Will not retain its form if damaged enough."
icon_state = "trap"
light_range = 1
health = 10
-/obj/effect/swarmer/destructible/trap/Crossed(var/atom/movable/AM)
+/obj/structure/swarmer/trap/Crossed(var/atom/movable/AM)
if(isliving(AM))
var/mob/living/L = AM
if(!istype(L, /mob/living/simple_animal/hostile/swarmer))
@@ -446,21 +434,29 @@
qdel(src)
..()
+/mob/living/simple_animal/hostile/swarmer/proc/CreateTrap()
+ set name = "Create trap"
+ set category = "Swarmer"
+ set desc = "Creates a simple trap that will non-lethally electrocute anything that steps on it. Costs 5 resources."
+ if(locate(/obj/structure/swarmer/trap) in loc)
+ to_chat(src, "There is already a trap here. Aborting.")
+ return
+ Fabricate(/obj/structure/swarmer/trap, 5)
+
/mob/living/simple_animal/hostile/swarmer/proc/CreateBarricade()
set name = "Create barricade"
set category = "Swarmer"
set desc = "Creates a barricade that will stop anything but swarmers and disabler beams from passing through."
- if(/obj/effect/swarmer/destructible/blockade in loc)
+ if(locate(/obj/structure/swarmer/blockade) in loc)
to_chat(src, "There is already a blockade here. Aborting.")
return
if(resources < 5)
to_chat(src, "We do not have the resources for this!")
return
if(do_mob(src, src, 10))
- Fabricate(/obj/effect/swarmer/destructible/blockade, 5)
- return
+ Fabricate(/obj/structure/swarmer/blockade, 5)
-/obj/effect/swarmer/destructible/blockade
+/obj/structure/swarmer/blockade
name = "swarmer blockade"
desc = "A quickly assembled energy blockade. Will not retain its form if damaged enough, but disabler beams and swarmers pass right through."
icon_state = "barricade"
@@ -469,7 +465,7 @@
density = 1
anchored = 1
-/obj/effect/swarmer/destructible/blockade/CanPass(atom/movable/O)
+/obj/structure/swarmer/blockade/CanPass(atom/movable/O)
if(isswarmer(O))
return 1
if(istype(O, /obj/item/projectile/beam/disabler))
diff --git a/code/game/gamemodes/miniantags/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm
index 94a7895bf51..39acdabacc5 100644
--- a/code/game/gamemodes/miniantags/guardian/guardian.dm
+++ b/code/game/gamemodes/miniantags/guardian/guardian.dm
@@ -496,7 +496,7 @@
melee_damage_upper = 10
damage_transfer = 0.9
projectiletype = /obj/item/projectile/guardian
- ranged_cooldown_time = 1
+ ranged_cooldown_time = 10
projectilesound = 'sound/effects/hit_on_shattered_glass.ogg'
ranged = 1
rapid = 1
diff --git a/code/game/gamemodes/miniantags/morph/morph.dm b/code/game/gamemodes/miniantags/morph/morph.dm
index 9bf6be0bbdc..be21008d5f2 100644
--- a/code/game/gamemodes/miniantags/morph/morph.dm
+++ b/code/game/gamemodes/miniantags/morph/morph.dm
@@ -164,7 +164,7 @@
else if(istype(target,/obj/item)) // Eat items just to be annoying
var/obj/item/I = target
if(!I.anchored)
- if(do_after(src,20, target = I))
+ if(do_after(src, 20, target = I))
eat(I)
return
target.attack_animal(src)
diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm
index f263d658f6b..4a2a629c1d2 100644
--- a/code/game/gamemodes/miniantags/revenant/revenant.dm
+++ b/code/game/gamemodes/miniantags/revenant/revenant.dm
@@ -17,8 +17,8 @@
invisibility = INVISIBILITY_REVENANT
health = INFINITY //Revenants don't use health, they use essence instead
maxHealth = INFINITY
- see_invisible = INVISIBILITY_REVENANT
see_in_dark = 8
+ see_invisible = SEE_INVISIBLE_OBSERVER_NOLIGHTING
universal_understand = 1
response_help = "passes through"
response_disarm = "swings at"
@@ -29,7 +29,6 @@
harm_intent_damage = 0
friendly = "touches"
status_flags = 0
- see_in_dark = 8
wander = 0
density = 0
flying = 1
diff --git a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm
index 85560dda620..3504ada2a94 100644
--- a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm
+++ b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm
@@ -110,6 +110,8 @@
message = "You toggle your night vision."
action_icon_state = "r_nightvision"
action_background_icon_state = "bg_revenant"
+ non_night_vision = INVISIBILITY_REVENANT
+ night_vision = SEE_INVISIBLE_OBSERVER_NOLIGHTING
//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob
/obj/effect/proc_holder/spell/targeted/revenant_transmit
diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm
index 6988d2b16dd..62c3a9a00b0 100644
--- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm
+++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm
@@ -104,9 +104,7 @@
speed = 0
boost = world.time + 60
-
-
-
+// Cult slaughter demon
/mob/living/simple_animal/slaughter/cult //Summoned as part of the cult objective "Bring the Slaughter"
name = "harbringer of the slaughter"
real_name = "harbringer of the Slaughter"
@@ -154,17 +152,18 @@
/mob/living/simple_animal/slaughter/cult/New()
..()
spawn(5)
- var/list/demon_candidates = get_candidates(ROLE_CULTIST)
+ var/list/demon_candidates = pollCandidates("Do you want to play as a slaughter demon?", ROLE_DEMON, 1, 100)
if(!demon_candidates.len)
visible_message("[src] disappears in a flash of red light!")
qdel(src)
return 0
- var/client/C = pick(demon_candidates)
+ var/mob/M = pick(demon_candidates)
var/mob/living/simple_animal/slaughter/cult/S = src
- if(!C)
+ if(!M || !M.client)
visible_message("[src] disappears in a flash of red light!")
qdel(src)
return 0
+ var/client/C = M.client
S.key = C.key
S.mind.assigned_role = "Harbringer of the Slaughter"
@@ -181,7 +180,7 @@
////////////////////The Powers
-//Paradise Port:I added this cuase..SPOOPY DEMON IN YOUR BRAIN
+//Paradise Port: I added this because..SPOOPY DEMON IN YOUR BRAIN
/datum/action/innate/demon/whisper
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index a7f3b36fc74..6c28b9ade28 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -145,11 +145,10 @@ proc/issyndicate(mob/living/M as mob)
var/mob/living/carbon/human/M = synd_mind.current
var/obj/item/organ/external/head/head_organ = M.get_organ("head")
- M.mutations = list()
- M.disabilities = 0
- M.overeatduration = 0
M.set_species("Human",1)
M.dna.ready_dna(M) // Quadriplegic Nuke Ops won't be participating in the paralympics
+ M.reagents.add_reagent("mutadone", 1) //No fat/blind/colourblind/epileptic/whatever ops.
+ M.overeatduration = 0
var/hair_c = pick("#8B4513","#000000","#FF4500","#FFD700") // Brown, black, red, blonde
var/eye_c = pick("#000000","#8B4513","1E90FF") // Black, brown, blue
@@ -223,7 +222,7 @@ proc/issyndicate(mob/living/M as mob)
/datum/game_mode/proc/greet_syndicate(var/datum/mind/syndicate, var/you_are=1)
if(you_are)
- to_chat(syndicate.current, "\blue You are a [syndicate_name()] agent!")
+ to_chat(syndicate.current, "You are a [syndicate_name()] agent!")
var/obj_count = 1
for(var/datum/objective/objective in syndicate.objectives)
to_chat(syndicate.current, "Objective #[obj_count]: [objective.explanation_text]")
@@ -246,9 +245,7 @@ proc/issyndicate(mob/living/M as mob)
synd_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(synd_mob), slot_shoes)
synd_mob.equip_or_collect(new /obj/item/clothing/gloves/combat(synd_mob), slot_gloves)
synd_mob.equip_to_slot_or_del(new /obj/item/weapon/card/id/syndicate(synd_mob), slot_wear_id)
- if(synd_mob.backbag == 2) synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(synd_mob), slot_back)
- if(synd_mob.backbag == 3) synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(synd_mob), slot_back)
- if(synd_mob.backbag == 4) synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(synd_mob), slot_back)
+ synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(synd_mob), slot_back)
synd_mob.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/food/pill/initropidril(synd_mob), slot_in_backpack)
synd_mob.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/automatic/pistol(synd_mob), slot_belt)
synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(synd_mob.back), slot_in_backpack)
diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm
index 6e50736e722..7a85467667e 100644
--- a/code/game/gamemodes/nuclear/nuclearbomb.dm
+++ b/code/game/gamemodes/nuclear/nuclearbomb.dm
@@ -35,8 +35,7 @@ var/bomb_set
poi_list |= src
/obj/machinery/nuclearbomb/Destroy()
- qdel(wires)
- wires = null
+ QDEL_NULL(wires)
poi_list.Remove(src)
return ..()
@@ -58,12 +57,12 @@ var/bomb_set
panel_open = 1
overlays += image(icon, "npanel_open")
to_chat(user, "You unscrew the control panel of [src].")
- playsound(src, 'sound/items/Screwdriver.ogg', 50, 1)
+ playsound(src, O.usesound, 50, 1)
else
panel_open = 0
overlays -= image(icon, "npanel_open")
to_chat(user, "You screw the control panel of [src] back on.")
- playsound(src, 'sound/items/Screwdriver.ogg', 50, 1)
+ playsound(src, O.usesound, 50, 1)
else
if(panel_open == 0)
to_chat(user, "[src] emits a buzzing noise, the panel staying locked in.")
@@ -71,7 +70,7 @@ var/bomb_set
panel_open = 0
overlays -= image(icon, "npanel_open")
to_chat(user, "You screw the control panel of [src] back on.")
- playsound(src, 'sound/items/Screwdriver.ogg', 50, 1)
+ playsound(src, O.usesound, 50, 1)
flick("nuclearbombc", src)
return
@@ -93,7 +92,7 @@ var/bomb_set
var/obj/item/weapon/weldingtool/WT = O
if(!WT.isOn()) return
if(WT.get_fuel() < 5) // uses up 5 fuel.
- to_chat(user, "\red You need more fuel to complete this task.")
+ to_chat(user, "You need more fuel to complete this task.")
return
user.visible_message("[user] starts cutting loose the anchoring bolt covers on [src].", "You start cutting loose the anchoring bolt covers with [O]...")
@@ -120,7 +119,7 @@ var/bomb_set
var/obj/item/weapon/weldingtool/WT = O
if(!WT.isOn()) return
if(WT.get_fuel() < 5) // uses up 5 fuel.
- to_chat(user, "\red You need more fuel to complete this task.")
+ to_chat(user, "You need more fuel to complete this task.")
return
user.visible_message("[user] starts cutting apart the anchoring system sealant on [src].", "You start cutting apart the anchoring system's sealant with [O]...")
@@ -167,9 +166,9 @@ var/bomb_set
else if(deployable)
if(removal_stage < 5)
anchored = 1
- visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring!")
+ visible_message("With a steely snap, bolts slide out of [src] and anchor it to the flooring!")
else
- visible_message("\red \The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.")
+ visible_message("\The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.")
if(!lighthack)
flick("nuclearbombc", src)
icon_state = "nuclearbomb1"
@@ -221,10 +220,10 @@ var/bomb_set
return
if(deployable)
- to_chat(usr, "\red You close several panels to make [src] undeployable.")
+ to_chat(usr, "You close several panels to make [src] undeployable.")
deployable = 0
else
- to_chat(usr, "\red You adjust some panels to make [src] deployable.")
+ to_chat(usr, "You adjust some panels to make [src] deployable.")
deployable = 1
return
@@ -283,7 +282,7 @@ var/bomb_set
nanomanager.update_uis(src)
return
if(safety)
- to_chat(usr, "\red The safety is still on.")
+ to_chat(usr, "The safety is still on.")
nanomanager.update_uis(src)
return
timing = !(timing)
@@ -313,16 +312,16 @@ var/bomb_set
if(href_list["anchor"])
if(removal_stage == 5)
anchored = 0
- visible_message("\red \The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.")
+ visible_message("\The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.")
nanomanager.update_uis(src)
return
if(!isinspace())
anchored = !(anchored)
if(anchored)
- visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring.")
+ visible_message("With a steely snap, bolts slide out of [src] and anchor it to the flooring.")
else
- visible_message("\red The anchoring bolts slide back into the depths of [src].")
+ visible_message("The anchoring bolts slide back into the depths of [src].")
else
to_chat(usr, "There is nothing to anchor to!")
@@ -338,6 +337,11 @@ var/bomb_set
return ..()
return
+/obj/machinery/nuclearbomb/tesla_act(power, explosive)
+ ..()
+ if(explosive)
+ qdel(src)//like the singulo, tesla deletes it. stops it from exploding over and over
+
#define NUKERANGE 80
/obj/machinery/nuclearbomb/proc/explode()
if(safety)
@@ -399,6 +403,7 @@ var/bomb_set
/obj/item/weapon/disk/nuclear/New()
..()
processing_objects.Add(src)
+ poi_list |= src
/obj/item/weapon/disk/nuclear/process()
var/turf/disk_loc = get_turf(src)
@@ -414,10 +419,12 @@ var/bomb_set
if(force)
message_admins("[src] has been !!force deleted!! in ([diskturf ? "[diskturf.x], [diskturf.y] ,[diskturf.z] - JMP":"nonexistent location"]).")
log_game("[src] has been !!force deleted!! in ([diskturf ? "[diskturf.x], [diskturf.y] ,[diskturf.z]":"nonexistent location"]).")
+ poi_list.Remove(src)
processing_objects.Remove(src)
return ..()
if(blobstart.len > 0)
+ poi_list.Remove(src)
var/obj/item/weapon/disk/nuclear/NEWDISK = new(pick(blobstart))
transfer_fingerprints_to(NEWDISK)
message_admins("[src] has been destroyed at ([diskturf.x], [diskturf.y], [diskturf.z] - JMP). Moving it to ([NEWDISK.x], [NEWDISK.y], [NEWDISK.z] - JMP).")
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 5b912908046..e34174f2beb 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -177,8 +177,8 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) \
/datum/objective/hijack
martyr_compatible = 0 //Technically you won't get both anyway.
- explanation_text = "Hijack the shuttle by escaping on it with no loyalist NanoTrasen crew on board and alive. \
- Syndicate agents, other enemies of NanoTrasen, cyborgs, and pets may be allowed to escape alive."
+ explanation_text = "Hijack the shuttle by escaping on it with no loyalist Nanotrasen crew on board and alive. \
+ Syndicate agents, other enemies of Nanotrasen, cyborgs, and pets may be allowed to escape alive."
/datum/objective/hijack/check_completion()
if(!owner.current || owner.current.stat)
@@ -195,7 +195,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) \
return shuttle_master.emergency.is_hijacked()
/datum/objective/hijackclone
- explanation_text = "Hijack the emergency shuttle by ensuring only you (or your copies) escape."
+ explanation_text = "Hijack the shuttle by ensuring only you (or your copies) escape."
martyr_compatible = 0
/datum/objective/hijackclone/check_completion()
@@ -384,8 +384,17 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) \
return steal_target
/datum/objective/steal/check_completion()
- if(!steal_target) return 1 // Free Objective
- return steal_target.check_completion(owner)
+ if(!steal_target)
+ return 1 // Free Objective
+
+ var/list/all_items = owner.current.GetAllContents()
+
+ for(var/obj/I in all_items)
+ if(istype(I, steal_target.typepath))
+ return steal_target.check_special_completion(I)
+ if(I.type in steal_target.altitems)
+ return steal_target.check_special_completion(I)
+
/datum/objective/steal/exchange
martyr_compatible = 0
@@ -489,7 +498,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) \
/datum/objective/blood/proc/gen_amount_goal(low = 150, high = 400)
target_amount = rand(low,high)
target_amount = round(round(target_amount/5)*5)
- explanation_text = "Accumulate atleast [target_amount] units of blood in total."
+ explanation_text = "Accumulate at least [target_amount] total units of blood."
return target_amount
/datum/objective/blood/check_completion()
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index 1a42ae58d61..556b7f50e5b 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -234,7 +234,7 @@
if(rev_mind.assigned_role in command_positions)
return 0
var/mob/living/carbon/human/H = rev_mind.current//Check to see if the potential rev is implanted
- if(isloyal(H))
+ if(ismindshielded(H))
return 0
if((rev_mind in revolutionaries) || (rev_mind in head_revolutionaries))
return 0
@@ -248,8 +248,8 @@
rev_mind.current.create_attack_log("Has been converted to the revolution!")
rev_mind.special_role = SPECIAL_ROLE_REV
update_rev_icons_added(rev_mind)
- if(jobban_isbanned(rev_mind.current, ROLE_REV))
- replace_jobbaned_player(rev_mind.current, ROLE_REV)
+ if(jobban_isbanned(rev_mind.current, ROLE_REV) || jobban_isbanned(rev_mind.current, ROLE_SYNDICATE))
+ replace_jobbanned_player(rev_mind.current, ROLE_REV)
return 1
//////////////////////////////////////////////////////////////////////////////
//Deals with players being converted from the revolution (Not a rev anymore)// // Modified to handle borged MMIs. Accepts another var if the target is being borged at the time -- Polymorph.
diff --git a/code/game/gamemodes/scoreboard.dm b/code/game/gamemodes/scoreboard.dm
index bd391550b62..3a0d531e03a 100644
--- a/code/game/gamemodes/scoreboard.dm
+++ b/code/game/gamemodes/scoreboard.dm
@@ -165,8 +165,8 @@
// has an account?
if(A)
. += A.money
- for(var/obj/item/weapon/spacecash/cash in C.contents)
- . += cash.get_total()
+ for(var/obj/item/stack/spacecash/cash in C.contents)
+ . += cash.amount
for(var/obj/item/weapon/storage/S in C.contents)
. += .(S, level + 1)
diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm
index 10dac6414d2..97f609ca9ff 100644
--- a/code/game/gamemodes/shadowling/shadowling.dm
+++ b/code/game/gamemodes/shadowling/shadowling.dm
@@ -162,8 +162,8 @@ Made by Xhuis
to_chat(new_thrall_mind.current, "Your body has been irreversibly altered. The attentive can see this - you may conceal it by wearing a mask.")
to_chat(new_thrall_mind.current, "Though not nearly as powerful as your masters, you possess some weak powers. These can be found in the Thrall Abilities tab.")
to_chat(new_thrall_mind.current, "You may communicate with your allies by speaking in the Shadowling Hivemind (:8).")
- if(jobban_isbanned(new_thrall_mind.current, ROLE_SHADOWLING))
- replace_jobbaned_player(new_thrall_mind.current, ROLE_SHADOWLING)
+ if(jobban_isbanned(new_thrall_mind.current, ROLE_SHADOWLING) || jobban_isbanned(new_thrall_mind.current, ROLE_SYNDICATE))
+ replace_jobbanned_player(new_thrall_mind.current, ROLE_SHADOWLING)
return 1
diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm
index b04a3012fc3..8abe51675cb 100644
--- a/code/game/gamemodes/shadowling/shadowling_abilities.dm
+++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm
@@ -72,8 +72,8 @@
var/datum/data/pda/utility/flashlight/FL = P.find_program(/datum/data/pda/utility/flashlight)
if(FL && FL.fon)
FL.start()
- else if(istype(I, /obj/item/clothing/head/helmet/space/rig))
- var/obj/item/clothing/head/helmet/space/rig/R = I
+ else if(istype(I, /obj/item/clothing/head/helmet/space/hardsuit))
+ var/obj/item/clothing/head/helmet/space/hardsuit/R = I
if(R.on)
R.toggle_light()
R.visible_message("[R]'s light fades and turns off.")
@@ -109,7 +109,7 @@
charge_counter = charge_max
return
to_chat(user, "You silently disable all nearby lights.")
- for(var/obj/effect/glowshroom/G in orange(2, user)) //Why the fuck was this in the loop below?
+ for(var/obj/structure/glowshroom/G in orange(2, user)) //Why the fuck was this in the loop below?
G.visible_message("\The [G] withers away!")
qdel(G)
for(var/turf/T in targets)
@@ -307,14 +307,14 @@
to_chat(target, "A terrible red light floods your mind. You collapse as conscious thought is wiped away.")
target.Weaken(12)
sleep(20)
- if(isloyal(target))
+ if(ismindshielded(target))
to_chat(user, "They have a mindshield implant. You begin to deactivate it - this will take some time.")
user.visible_message("[user] pauses, then dips their head in concentration!")
to_chat(target, "Your mindshield implant becomes hot as it comes under attack!")
sleep(100) //10 seconds - not spawn() so the enthralling takes longer
to_chat(user, "The nanobots composing the mindshield implant have been rendered inert. Now to continue.")
user.visible_message("[user] relaxes again.")
- for(var/obj/item/weapon/implant/loyalty/L in target)
+ for(var/obj/item/weapon/implant/mindshield/L in target)
if(L && L.implanted)
qdel(L)
to_chat(target, "Your mental protection implant unexpectedly falters, dims, dies.")
@@ -718,8 +718,9 @@
var/more_minutes = 9000
var/timer = shuttle_master.emergency.timeLeft()
timer += more_minutes
- event_announcement.Announce("Major system failure aboard the emergency shuttle. This will extend its arrival time by approximately 15 minutes..", "System Failure", 'sound/misc/notice1.ogg')
+ event_announcement.Announce("Major system failure aboard the emergency shuttle. This will extend its arrival time by approximately 15 minutes and the shuttle is unable to be recalled.", "System Failure", 'sound/misc/notice1.ogg')
shuttle_master.emergency.setTimer(timer)
+ shuttle_master.emergency.canRecall = FALSE
user.mind.spell_list.Remove(src) //Can only be used once!
qdel(src)
diff --git a/code/game/gamemodes/steal_items.dm b/code/game/gamemodes/steal_items.dm
index fd3ad379fe0..92573fcc17e 100644
--- a/code/game/gamemodes/steal_items.dm
+++ b/code/game/gamemodes/steal_items.dm
@@ -6,10 +6,11 @@
#define THEFT_FLAG_UNIQUE 2
/datum/theft_objective
- var/name=""
+ var/name = ""
var/typepath=/atom
- var/list/protected_jobs=list()
- var/flags=0
+ var/list/protected_jobs = list()
+ var/list/altitems = list()
+ var/flags = 0
/datum/theft_objective/proc/check_completion(var/datum/mind/owner)
if(!owner.current)
@@ -70,6 +71,16 @@ datum/theft_objective/ai/check_special_completion(var/obj/item/device/aicard/C)
name = "the station blueprints"
typepath = /obj/item/areaeditor/blueprints
protected_jobs = list("Chief Engineer")
+ altitems = list(/obj/item/weapon/photo)
+
+/datum/objective_item/steal/blueprints/check_special_completion(obj/item/I)
+ if(istype(I, /obj/item/areaeditor/blueprints))
+ return 1
+ if(istype(I, /obj/item/weapon/photo))
+ var/obj/item/weapon/photo/P = I
+ if(P.blueprints)
+ return 1
+ return 0
/datum/theft_objective/voidsuit
name = "a nasa voidsuit"
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index 371aef6c6a0..e60b564f5d0 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -70,6 +70,9 @@
modePlayer += traitors
..()
+/datum/game_mode/traitor/setup_chumps()
+ //since we actually have potential collaborators, we don't prepare any chumps to avoid extra people knowing our codewords.
+ return
/datum/game_mode/proc/forge_traitor_objectives(datum/mind/traitor)
if(istype(traitor.current, /mob/living/silicon))
@@ -345,6 +348,14 @@
if(M && M != traitor_mob)
to_chat(traitor_mob, "We have received credible reports that [M.real_name] might be willing to help our cause. If you need assistance, consider contacting them.")
traitor_mob.mind.store_memory("Potential Collaborator: [M.real_name]")
+ //let's also inform their contact that they might be called upon, but leave it vague.
+ inform_collab(M)
+
+/datum/game_mode/traitor/inform_collab(mob/living/carbon/human/M)
+ if(M.mind in traitors) //if you are already a traitor, you already know the codewords and your role, so skip this message.
+ return
+ ..(M)
+
/datum/game_mode/proc/remove_traitor(datum/mind/traitor_mind)
if(traitor_mind in traitors)
@@ -355,8 +366,8 @@
to_chat(traitor_mind.current, "You have been turned into a robot! You are no longer a traitor.")
else
to_chat(traitor_mind.current, "You have been brainwashed! You are no longer a traitor.")
- ticker.mode.update_traitor_icons_removed(traitor_mind)
-
+ ticker.mode.update_traitor_icons_removed(traitor_mind)
+
/datum/game_mode/proc/update_traitor_icons_added(datum/mind/traitor_mind)
var/datum/atom_hud/antag/tatorhud = huds[ANTAG_HUD_TRAITOR]
tatorhud.join_hud(traitor_mind.current)
diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm
index c38c50ad40a..9d1796523f9 100644
--- a/code/game/gamemodes/vampire/vampire_powers.dm
+++ b/code/game/gamemodes/vampire/vampire_powers.dm
@@ -179,7 +179,7 @@
if(do_mob(user, target, 50))
if(!affects(target))
to_chat(user, "Your piercing gaze fails to knock out [target].")
- to_chat(target, "\blue [user]'s feeble gaze is ineffective.")
+ to_chat(target, "[user]'s feeble gaze is ineffective.")
else
to_chat(user, "Your piercing gaze knocks out [target].")
to_chat(target, "You find yourself unable to move and barely able to speak.")
@@ -294,7 +294,7 @@
/obj/effect/proc_holder/spell/vampire/targetted/enthrall/proc/can_enthrall(mob/living/user, mob/living/carbon/C)
var/enthrall_safe = 0
- for(var/obj/item/weapon/implant/loyalty/L in C)
+ for(var/obj/item/weapon/implant/mindshield/L in C)
if(L && L.implanted)
enthrall_safe = 1
break
@@ -488,7 +488,7 @@
if(!turfs.len)
revert_cast(user)
- to_chat(user, "\red You cannot find darkness to step to.")
+ to_chat(user, "You cannot find darkness to step to.")
return
perform(turfs, user = user)
diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm
index 7e9f98a64f2..c8eafde9048 100644
--- a/code/game/gamemodes/wizard/artefact.dm
+++ b/code/game/gamemodes/wizard/artefact.dm
@@ -586,6 +586,11 @@ var/global/list/multiverse = list()
W.SetOwnerInfo(M)
M.equip_to_slot_or_del(W, slot_wear_id)
+ if(M.get_species() == "Vox")
+ M.species.after_equip_job(null, M) //Voxygen(tm)
+ if(M.get_species() == "Plasmaman")
+ M.species.after_equip_job(null, M) //No fireballs from other dimensions.
+
M.update_icons()
/obj/item/weapon/multisword/pure_evil
diff --git a/code/game/gamemodes/wizard/raginmages.dm b/code/game/gamemodes/wizard/raginmages.dm
index 489e68acec7..c57b7d531c7 100644
--- a/code/game/gamemodes/wizard/raginmages.dm
+++ b/code/game/gamemodes/wizard/raginmages.dm
@@ -61,11 +61,11 @@
message_admins("[wizard.current] went into crit in the wizard lair, another wizard is likely camping")
end_squabble(get_area(wizard.current))
else
- to_chat(wizard.current, "\red The Space Wizard Federation is upset with your performance and have terminated your employment.")
+ to_chat(wizard.current, "The Space Wizard Federation is upset with your performance and have terminated your employment.")
wizard.current.gib() // *REAL* ACTION!! *REAL* DRAMA!! *REAL* BLOODSHED!!
continue
if(wizard.current.client && wizard.current.client.is_afk() > 10 * 60 * 10) // 10 minutes
- to_chat(wizard.current, "\red The Space Wizard Federation is upset with your performance and have terminated your employment.")
+ to_chat(wizard.current, "The Space Wizard Federation is upset with your performance and have terminated your employment.")
wizard.current.gib() // Let's keep the round moving
continue
if(!wizard.current.client)
@@ -181,5 +181,5 @@
/datum/game_mode/wizard/raginmages/declare_completion()
if(finished)
feedback_set_details("round_end_result","loss - wizard killed")
- to_chat(world, "\red The crew has managed to hold off the wizard attack! The Space Wizards Federation has been taught a lesson they will not soon forget!")
+ to_chat(world, " The crew has managed to hold off the wizard attack! The Space Wizards Federation has been taught a lesson they will not soon forget!")
..(1)
diff --git a/code/game/gamemodes/wizard/rightandwrong.dm b/code/game/gamemodes/wizard/rightandwrong.dm
index 7145a414d7e..b33caa4ef73 100644
--- a/code/game/gamemodes/wizard/rightandwrong.dm
+++ b/code/game/gamemodes/wizard/rightandwrong.dm
@@ -129,8 +129,8 @@
if("staffdoor")
new /obj/item/weapon/gun/magic/staff/door(get_turf(H))
if("armor")
- new /obj/item/clothing/suit/space/rig/wizard(get_turf(H))
- new /obj/item/clothing/head/helmet/space/rig/wizard(get_turf(H))
+ new /obj/item/clothing/suit/space/hardsuit/wizard(get_turf(H))
+ new /obj/item/clothing/head/helmet/space/hardsuit/wizard(get_turf(H))
if("scrying")
new /obj/item/weapon/scrying(get_turf(H))
if(!(XRAY in H.mutations))
diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm
index 733c19bc337..7fcd9c198b4 100644
--- a/code/game/gamemodes/wizard/soulstone.dm
+++ b/code/game/gamemodes/wizard/soulstone.dm
@@ -51,7 +51,7 @@
to_chat(user, "There is no power left in the shard.")
return
- if(!ishuman(M) || istype(M, /mob/living/carbon/human/dummy)) //If target is not a human or a dummy
+ if(!ishuman(M)) //If target is not a human
return ..()
if(M.has_brain_worms()) //Borer stuff - RR
@@ -62,8 +62,8 @@
to_chat(user, "A mysterious force prevents you from trapping this being's soul.")
return ..()
- if(iscultist(M))
- to_chat(user, "This soul is already MINE.")
+ if(iscultist(user) && iscultist(M))
+ to_chat(user, "\"Come now, do not capture your fellow's soul.\")
return ..()
M.create_attack_log("Has had their soul captured with [src.name] by [key_name(user)]")
diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm
index fd554e03c85..65843d0e0fc 100644
--- a/code/game/gamemodes/wizard/spellbook.dm
+++ b/code/game/gamemodes/wizard/spellbook.dm
@@ -319,7 +319,7 @@
user.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS)
user.see_in_dark = 8
user.see_invisible = SEE_INVISIBLE_LEVEL_TWO
- to_chat(user, "\blue The walls suddenly disappear.")
+ to_chat(user, "The walls suddenly disappear.")
return 1
@@ -353,7 +353,7 @@
/datum/spellbook_entry/item/armor
name = "Mastercrafted Armor Set"
desc = "An artefact suit of armor that allows you to cast spells while providing more protection against attacks and the void of space."
- item_path = /obj/item/clothing/suit/space/rig/wizard
+ item_path = /obj/item/clothing/suit/space/hardsuit/wizard
log_name = "HS"
category = "Defensive"
@@ -362,7 +362,7 @@
if(.)
new /obj/item/clothing/shoes/sandal(get_turf(user)) //In case they've lost them.
new /obj/item/clothing/gloves/color/purple(get_turf(user))//To complete the outfit
- new /obj/item/clothing/head/helmet/space/rig/wizard(get_turf(user))
+ new /obj/item/clothing/head/helmet/space/hardsuit/wizard(get_turf(user))
/datum/spellbook_entry/item/contract
name = "Contract of Apprenticeship"
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index c00e0436473..ac8fc9550cf 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -157,7 +157,7 @@
wizard_mob.faction = list("wizard")
- wizard_mob.species.equip(wizard_mob)
+ wizard_mob.species.after_equip_job(null, wizard_mob)
to_chat(wizard_mob, "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.")
to_chat(wizard_mob, "The spellbook is bound to you, and others cannot use it.")
@@ -197,7 +197,7 @@
/datum/game_mode/wizard/declare_completion(var/ragin = 0)
if(finished && !ragin)
feedback_set_details("round_end_result","loss - wizard killed")
- to_chat(world, "\red The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!")
+ to_chat(world, " The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!")
..()
return 1
diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm
index 58d041b9442..2f0e9ab849a 100644
--- a/code/game/jobs/access.dm
+++ b/code/game/jobs/access.dm
@@ -74,6 +74,7 @@
/var/const/access_magistrate = 74
/var/const/access_minisat = 75
/var/const/access_mineral_storeroom = 76
+/var/const/access_network = 77
/var/const/access_weapons = 99 //Weapon authorization for secbots
@@ -93,18 +94,21 @@
/var/const/access_cent_bridge = 113//Bridge.
/var/const/access_cent_commander = 114//Commander's Office/ID computer.
- //The Syndicate
+//The Syndicate
/var/const/access_syndicate = 150//General Syndicate Access
/var/const/access_syndicate_leader = 151//Nuke Op Leader Access
/var/const/access_vox = 152//Vox Access
//Trade Stations
-
var/const/access_trade_sol = 160
- //MONEY
+//MONEY
/var/const/access_crate_cash = 200
+//Awaymissions
+/var/const/access_away01 = 271
+
+
/obj/var/list/req_access = null
/obj/var/req_access_txt = "0"
/obj/var/list/req_one_access = null
@@ -241,7 +245,7 @@ var/const/access_trade_sol = 160
access_theatre, access_research, access_mining, access_mailsorting,
access_heads_vault, access_mining_station, access_xenobiology, access_ce, access_hop, access_hos, access_RC_announce,
access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_paramedic, access_blueshield, access_mechanic,access_weapons,
- access_pilot, access_ntrep, access_magistrate, access_mineral_storeroom, access_minisat)
+ access_pilot, access_ntrep, access_magistrate, access_mineral_storeroom, access_minisat, access_network)
/proc/get_all_centcom_access()
return list(access_cent_general, access_cent_living, access_cent_medical, access_cent_security, access_cent_storage, access_cent_shuttles, access_cent_telecomms, access_cent_teleporter, access_cent_specops, access_cent_specops_commander, access_cent_blackops, access_cent_thunder, access_cent_bridge, access_cent_commander)
@@ -266,7 +270,7 @@ var/const/access_trade_sol = 160
if(REGION_MEDBAY) //medbay
return list(access_medical, access_genetics, access_morgue, access_chemistry, access_psychiatrist, access_virology, access_surgery, access_cmo, access_paramedic)
if(REGION_RESEARCH) //research
- return list(access_research, access_tox, access_tox_storage, access_genetics, access_robotics, access_xenobiology, access_xenoarch, access_minisat, access_rd)
+ return list(access_research, access_tox, access_tox_storage, access_genetics, access_robotics, access_xenobiology, access_xenoarch, access_minisat, access_rd, access_network)
if(REGION_ENGINEERING) //engineering and maintenance
return list(access_construction, access_maint_tunnels, access_engine, access_engine_equip, access_external_airlocks, access_tech_storage, access_atmospherics, access_minisat, access_ce, access_mechanic)
if(REGION_SUPPLY) //supply
@@ -426,6 +430,8 @@ var/const/access_trade_sol = 160
return "Keycode Auth. Device"
if(access_tcomsat)
return "Telecommunications"
+ if(access_network)
+ return "Network Access"
if(access_gateway)
return "Gateway"
if(access_sec_doors)
diff --git a/code/game/jobs/job/central.dm b/code/game/jobs/job/central.dm
index d5cba5be3d0..64298b70fbe 100644
--- a/code/game/jobs/job/central.dm
+++ b/code/game/jobs/job/central.dm
@@ -8,36 +8,37 @@
spawn_positions = 5
supervisors = "the admins"
selection_color = "#ffdddd"
- idtype = /obj/item/weapon/card/id/centcom
access = list()
minimal_access = list()
admin_only = 1
-
-/datum/job/ntnavyofficer/equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/clothing/under/rank/centcom/officer(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/shoes/centcom(H), slot_shoes)
- H.equip_or_collect(new /obj/item/clothing/gloves/color/white(H), slot_gloves)
- H.equip_or_collect(new /obj/item/device/radio/headset/centcom(H), slot_l_ear)
- H.equip_or_collect(new /obj/item/clothing/head/beret/centcom/officer(H), slot_head)
- H.equip_or_collect(new /obj/item/device/pda/centcom(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/clothing/glasses/hud/security/sunglasses(H), slot_glasses)
- H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/gun/energy/pulse/pistol(H), slot_in_backpack)
-
- H.equip_or_collect(new /obj/item/weapon/implanter/dust(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/implanter/death_alarm(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
- H.sec_hud_set_implants()
- return 1
+ outfit = /datum/outfit/job/ntnavyofficer
/datum/job/ntnavyofficer/get_access()
return get_centcom_access(title)
+/datum/outfit/job/ntnavyofficer
+ name = "Nanotrasen Navy Officer"
+ jobtype = /datum/job/ntnavyofficer
+
+ uniform = /obj/item/clothing/under/rank/centcom/officer
+ gloves = /obj/item/clothing/gloves/color/white
+ shoes = /obj/item/clothing/shoes/centcom
+ head = /obj/item/clothing/head/beret/centcom/officer
+ l_ear = /obj/item/device/radio/headset/centcom
+ glasses = /obj/item/clothing/glasses/hud/security/sunglasses
+ id = /obj/item/weapon/card/id/centcom
+ pda = /obj/item/device/pda/centcom
+ backpack_contents = list(
+ /obj/item/weapon/gun/energy/pulse/pistol = 1,
+ /obj/item/weapon/implanter/dust = 1,
+ /obj/item/weapon/implanter/death_alarm = 1
+ )
+
+ implants = list(/obj/item/weapon/implant/mindshield)
+
+ backpack = /obj/item/weapon/storage/backpack/satchel
+
+
// CC Officials who lead ERTs, Death Squads, etc.
/datum/job/ntspecops
@@ -48,33 +49,34 @@
spawn_positions = 5
supervisors = "the admins"
selection_color = "#ffdddd"
- idtype = /obj/item/weapon/card/id/centcom
access = list()
minimal_access = list()
admin_only = 1
spawn_ert = 1
-
-/datum/job/ntspecops/equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/clothing/under/syndicate/combat(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/shoes/combat(H), slot_shoes)
- H.equip_or_collect(new /obj/item/clothing/gloves/combat(H), slot_gloves)
- H.equip_or_collect(new /obj/item/device/radio/headset/centcom(H), slot_l_ear)
- H.equip_or_collect(new /obj/item/clothing/head/beret/centcom/officer/navy(H), slot_head)
- H.equip_or_collect(new /obj/item/device/pda/centcom(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/clothing/glasses/hud/security/sunglasses(H), slot_glasses)
- H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/clothing/suit/space/deathsquad/officer(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/implanter/dust(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/gun/energy/pulse/pistol/m1911(H), slot_belt)
- H.equip_or_collect(new /obj/item/weapon/implanter/death_alarm(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
- H.sec_hud_set_implants()
- return 1
+ outfit = /datum/outfit/job/ntspecops
/datum/job/ntspecops/get_access()
return get_centcom_access(title)
+
+/datum/outfit/job/ntspecops
+ name = "Special Operations Officer"
+ jobtype = /datum/job/ntspecops
+
+ uniform = /obj/item/clothing/under/syndicate/combat
+ suit = /obj/item/clothing/suit/space/deathsquad/officer
+ gloves = /obj/item/clothing/gloves/combat
+ shoes = /obj/item/clothing/shoes/combat
+ head = /obj/item/clothing/head/beret/centcom/officer/navy
+ l_ear = /obj/item/device/radio/headset/centcom
+ glasses = /obj/item/clothing/glasses/hud/security/sunglasses
+ id = /obj/item/weapon/card/id/centcom
+ pda = /obj/item/device/pda/centcom
+ backpack_contents = list(
+ /obj/item/weapon/implanter/dust = 1,
+ /obj/item/weapon/gun/energy/pulse/pistol/m1911 = 1,
+ /obj/item/weapon/implanter/death_alarm = 1
+ )
+
+ implants = list(/obj/item/weapon/implant/mindshield)
+
+ backpack = /obj/item/weapon/storage/backpack/satchel
\ No newline at end of file
diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm
index a6f1ef11749..40b1dfd8bd1 100644
--- a/code/game/jobs/job/civilian.dm
+++ b/code/game/jobs/job/civilian.dm
@@ -9,20 +9,19 @@
access = list() //See /datum/job/assistant/get_access()
minimal_access = list() //See /datum/job/assistant/get_access()
alt_titles = list("Tourist","Businessman","Trader","Assistant")
-
-/datum/job/civilian/equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/clothing/under/color/random(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/shoes/black(H), slot_shoes)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- return 1
+ outfit = /datum/outfit/job/assistant
/datum/job/civilian/get_access()
if(config.assistant_maint)
return list(access_maint_tunnels)
else
return list()
+
+/datum/outfit/job/assistant
+ name = "Civilian"
+ jobtype = /datum/job/civilian
+
+ uniform = /obj/item/clothing/under/color/random
+ shoes = /obj/item/clothing/shoes/black
+
+
diff --git a/code/game/jobs/job/engineering.dm b/code/game/jobs/job/engineering.dm
index 7e6f664252f..8d3c4d65165 100644
--- a/code/game/jobs/job/engineering.dm
+++ b/code/game/jobs/job/engineering.dm
@@ -7,7 +7,6 @@
is_engineering = 1
supervisors = "the captain"
selection_color = "#ffeeaa"
- idtype = /obj/item/weapon/card/id/ce
req_admin_notify = 1
access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels,
access_teleporter, access_external_airlocks, access_atmospherics, access_emergency_storage, access_eva,
@@ -20,24 +19,29 @@
minimal_player_age = 21
exp_requirements = 600
exp_type = EXP_TYPE_CREW
+ outfit = /datum/outfit/job/chief_engineer
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/heads/ce(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack/industrial(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_eng(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/clothing/under/rank/chief_engineer(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/device/pda/heads/ce(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/clothing/shoes/brown(H), slot_shoes)
- H.equip_or_collect(new /obj/item/clothing/head/hardhat/white(H), slot_head)
- H.equip_or_collect(new /obj/item/weapon/storage/belt/utility/full(H), slot_belt)
- H.equip_or_collect(new /obj/item/clothing/gloves/color/black/ce(H), slot_gloves)
- H.equip_or_collect(new /obj/item/weapon/storage/box/engineer(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/melee/classic_baton/telescopic(H), slot_in_backpack)
- return 1
+/datum/outfit/job/chief_engineer
+ name = "Chief Engineer"
+ jobtype = /datum/job/chief_engineer
+ uniform = /obj/item/clothing/under/rank/chief_engineer
+ belt = /obj/item/weapon/storage/belt/utility/chief/full
+ gloves = /obj/item/clothing/gloves/color/black/ce
+ shoes = /obj/item/clothing/shoes/brown
+ head = /obj/item/clothing/head/hardhat/white
+ l_ear = /obj/item/device/radio/headset/heads/ce
+ id = /obj/item/weapon/card/id/ce
+ l_pocket = /obj/item/device/t_scanner
+ pda = /obj/item/device/pda/heads/ce
+ backpack_contents = list(
+ /obj/item/weapon/melee/classic_baton/telescopic = 1
+ )
+
+ backpack = /obj/item/weapon/storage/backpack/industrial
+ satchel = /obj/item/weapon/storage/backpack/satchel_eng
+ dufflebag = /obj/item/weapon/storage/backpack/duffel/engineering
+ box = /obj/item/weapon/storage/box/engineer
/datum/job/engineer
@@ -49,26 +53,31 @@
is_engineering = 1
supervisors = "the chief engineer"
selection_color = "#fff5cc"
- idtype = /obj/item/weapon/card/id/engineering
access = list(access_eva, access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels, access_external_airlocks, access_construction, access_atmospherics, access_mineral_storeroom)
minimal_access = list(access_eva, access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels, access_external_airlocks, access_construction, access_mineral_storeroom)
alt_titles = list("Maintenance Technician","Engine Technician","Electrician")
minimal_player_age = 7
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_eng(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack/industrial(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_eng(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/clothing/under/rank/engineer(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/shoes/workboots(H), slot_shoes)
- H.equip_or_collect(new /obj/item/weapon/storage/belt/utility/full(H), slot_belt)
- H.equip_or_collect(new /obj/item/clothing/head/hardhat(H), slot_head)
- H.equip_or_collect(new /obj/item/device/t_scanner(H), slot_r_store)
- H.equip_or_collect(new /obj/item/device/pda/engineering(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/weapon/storage/box/engineer(H), slot_in_backpack)
- return 1
+ exp_requirements = 300
+ exp_type = EXP_TYPE_CREW
+ outfit = /datum/outfit/job/engineer
+
+/datum/outfit/job/engineer
+ name = "Station Engineer"
+ jobtype = /datum/job/engineer
+
+ uniform = /obj/item/clothing/under/rank/engineer
+ belt = /obj/item/weapon/storage/belt/utility/full
+ shoes = /obj/item/clothing/shoes/workboots
+ head = /obj/item/clothing/head/hardhat
+ l_ear = /obj/item/device/radio/headset/headset_eng
+ id = /obj/item/weapon/card/id/engineering
+ l_pocket = /obj/item/device/t_scanner
+ pda = /obj/item/device/pda/engineering
+
+ backpack = /obj/item/weapon/storage/backpack/industrial
+ satchel = /obj/item/weapon/storage/backpack/satchel_eng
+ dufflebag = /obj/item/weapon/storage/backpack/duffel/engineering
+ box = /obj/item/weapon/storage/box/engineer
@@ -81,24 +90,26 @@
is_engineering = 1
supervisors = "the chief engineer"
selection_color = "#fff5cc"
- idtype = /obj/item/weapon/card/id/engineering
access = list(access_eva, access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels, access_external_airlocks, access_construction, access_atmospherics, access_mineral_storeroom)
minimal_access = list(access_eva, access_atmospherics, access_maint_tunnels, access_external_airlocks, access_emergency_storage, access_construction, access_mineral_storeroom)
alt_titles = list("Atmospheric Technician")
minimal_player_age = 7
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_eng(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/clothing/under/rank/atmospheric_technician(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/shoes/workboots(H), slot_shoes)
- H.equip_or_collect(new /obj/item/weapon/storage/belt/utility/atmostech/(H), slot_belt)
- H.equip_or_collect(new /obj/item/device/pda/atmos(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/weapon/storage/box/engineer(H), slot_in_backpack)
- return 1
+ exp_requirements = 300
+ exp_type = EXP_TYPE_CREW
+ outfit = /datum/outfit/job/atmos
+
+/datum/outfit/job/atmos
+ name = "Life Support Specialist"
+ jobtype = /datum/job/atmos
+
+ uniform = /obj/item/clothing/under/rank/atmospheric_technician
+ belt = /obj/item/weapon/storage/belt/utility/atmostech
+ shoes = /obj/item/clothing/shoes/workboots
+ l_ear = /obj/item/device/radio/headset/headset_eng
+ id = /obj/item/weapon/card/id/engineering
+ pda = /obj/item/device/pda/atmos
+
+ box = /obj/item/weapon/storage/box/engineer
/datum/job/mechanic
title = "Mechanic"
@@ -109,24 +120,27 @@
is_engineering = 1
supervisors = "the chief engineer"
selection_color = "#fff5cc"
- idtype = /obj/item/weapon/card/id/engineering
access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels, access_mechanic, access_external_airlocks, access_mineral_storeroom)
minimal_access = list(access_maint_tunnels, access_emergency_storage, access_mechanic, access_external_airlocks, access_mineral_storeroom)
+ outfit = /datum/outfit/job/mechanic
+/datum/outfit/job/mechanic
+ name = "Mechanic"
+ jobtype = /datum/job/mechanic
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_eng(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack/industrial(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_eng(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/clothing/under/rank/mechanic(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/shoes/workboots(H), slot_shoes)
- H.equip_or_collect(new /obj/item/weapon/storage/belt/utility/full(H), slot_belt)
- H.equip_or_collect(new /obj/item/clothing/head/hardhat(H), slot_head)
- H.equip_or_collect(new /obj/item/device/t_scanner(H), slot_r_store)
- H.equip_or_collect(new /obj/item/device/pda/engineering(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/weapon/storage/box/engineer(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/pod_paint_bucket(H), slot_in_backpack)
- return 1
+ uniform = /obj/item/clothing/under/rank/mechanic
+ belt = /obj/item/weapon/storage/belt/utility/full
+ shoes = /obj/item/clothing/shoes/workboots
+ head = /obj/item/clothing/head/hardhat
+ l_ear = /obj/item/device/radio/headset/headset_eng
+ id = /obj/item/weapon/card/id/engineering
+ r_pocket = /obj/item/device/t_scanner
+ pda = /obj/item/device/pda/engineering
+ backpack_contents = list(
+ /obj/item/weapon/pod_paint_bucket = 1
+ )
+
+ backpack = /obj/item/weapon/storage/backpack/industrial
+ satchel = /obj/item/weapon/storage/backpack/satchel_eng
+ dufflebag = /obj/item/weapon/storage/backpack/duffel/engineering
+ box = /obj/item/weapon/storage/box/engineer
diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm
index b4dc5610ce6..4d0b4d51dd3 100644
--- a/code/game/jobs/job/job.dm
+++ b/code/game/jobs/job/job.dm
@@ -29,9 +29,6 @@
//Sellection screen color
var/selection_color = "#ffffff"
- //the type of the ID the player will have
- var/idtype = /obj/item/weapon/card/id
-
//List of alternate titles, if any
var/list/alt_titles
@@ -57,14 +54,32 @@
var/admin_only = 0
var/spawn_ert = 0
+ var/outfit = null
+
/////////////////////////////////
// /vg/ feature: Job Objectives!
/////////////////////////////////
var/required_objectives=list() // Objectives that are ALWAYS added.
var/optional_objectives=list() // Objectives that are SOMETIMES added.
-/datum/job/proc/equip(var/mob/living/carbon/human/H)
- return 1
+//Only override this proc
+/datum/job/proc/after_spawn(mob/living/carbon/human/H)
+
+/datum/job/proc/announce(mob/living/carbon/human/H)
+
+/datum/job/proc/equip(mob/living/carbon/human/H, visualsOnly = FALSE, announce = TRUE)
+ if(!H)
+ return 0
+
+ H.species.before_equip_job(src, H, visualsOnly)
+
+ if(outfit)
+ H.equipOutfit(outfit, visualsOnly)
+
+ H.species.after_equip_job(src, H, visualsOnly)
+
+ if(!visualsOnly && announce)
+ announce(H)
/datum/job/proc/get_access()
if(!config) //Needed for robots.
@@ -94,44 +109,149 @@
return max(0, minimal_player_age - C.player_age)
-/datum/job/proc/apply_fingerprints(var/mob/living/carbon/human/H)
- if(!istype(H))
- return
- if(H.back)
- H.back.add_fingerprint(H,1) //The 1 sets a flag to ignore gloves
- for(var/obj/item/I in H.back.contents)
- I.add_fingerprint(H,1)
- if(H.wear_id)
- H.wear_id.add_fingerprint(H,1)
- if(H.w_uniform)
- H.w_uniform.add_fingerprint(H,1)
- if(H.wear_suit)
- H.wear_suit.add_fingerprint(H,1)
- if(H.wear_mask)
- H.wear_mask.add_fingerprint(H,1)
- if(H.head)
- H.head.add_fingerprint(H,1)
- if(H.shoes)
- H.shoes.add_fingerprint(H,1)
- if(H.gloves)
- H.gloves.add_fingerprint(H,1)
- if(H.l_ear)
- H.l_ear.add_fingerprint(H,1)
- if(H.r_ear)
- H.r_ear.add_fingerprint(H,1)
- if(H.glasses)
- H.glasses.add_fingerprint(H,1)
- if(H.belt)
- H.belt.add_fingerprint(H,1)
- for(var/obj/item/I in H.belt.contents)
- I.add_fingerprint(H,1)
- if(H.s_store)
- H.s_store.add_fingerprint(H,1)
- if(H.l_store)
- H.l_store.add_fingerprint(H,1)
- if(H.r_store)
- H.r_store.add_fingerprint(H,1)
- return 1
-
/datum/job/proc/is_position_available()
return (current_positions < total_positions) || (total_positions == -1)
+
+/datum/outfit/job
+ name = "Standard Gear"
+ collect_not_del = TRUE // we don't want anyone to lose their job shit
+
+ var/allow_loadout = TRUE
+ var/allow_backbag_choice = TRUE
+ var/jobtype = null
+
+ uniform = /obj/item/clothing/under/color/grey
+ id = /obj/item/weapon/card/id
+ l_ear = /obj/item/device/radio/headset
+ back = /obj/item/weapon/storage/backpack
+ shoes = /obj/item/clothing/shoes/black
+ pda = /obj/item/device/pda
+
+ var/list/implants = null
+
+ var/backpack = /obj/item/weapon/storage/backpack
+ var/satchel = /obj/item/weapon/storage/backpack/satchel_norm
+ var/dufflebag = /obj/item/weapon/storage/backpack/duffel
+ var/box = /obj/item/weapon/storage/box/survival
+
+ var/tmp/list/gear_leftovers = list()
+
+/datum/outfit/job/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ if(allow_backbag_choice)
+ switch(H.backbag)
+ if(GBACKPACK)
+ back = /obj/item/weapon/storage/backpack //Grey backpack
+ if(GSATCHEL)
+ back = /obj/item/weapon/storage/backpack/satchel_norm //Grey satchel
+ if(GDUFFLEBAG)
+ back = /obj/item/weapon/storage/backpack/duffel //Grey Dufflebag
+ if(LSATCHEL)
+ back = /obj/item/weapon/storage/backpack/satchel //Leather Satchel
+ if(DSATCHEL)
+ back = satchel //Department satchel
+ if(DDUFFLEBAG)
+ back = dufflebag //Department dufflebag
+ else
+ back = backpack //Department backpack
+
+ if(box)
+ backpack_contents.Insert(1, box) // Box always takes a first slot in backpack
+ backpack_contents[box] = 1
+
+ if(allow_loadout && H.client && (H.client.prefs.gear && H.client.prefs.gear.len))
+ for(var/gear in H.client.prefs.gear)
+ var/datum/gear/G = gear_datums[gear]
+ if(G)
+ var/permitted = FALSE
+
+ if(G.allowed_roles)
+ if(name in G.allowed_roles)
+ permitted = TRUE
+ else
+ permitted = TRUE
+
+ if(G.whitelisted && (G.whitelisted != H.species.name || !is_alien_whitelisted(H, G.whitelisted)))
+ permitted = FALSE
+
+ if(!permitted)
+ to_chat(H, "Your current job or whitelist status does not permit you to spawn with [gear]!")
+ continue
+
+ if(G.slot)
+ if(H.equip_to_slot_or_del(G.spawn_item(H), G.slot))
+ to_chat(H, "Equipping you with [gear]!")
+ else
+ gear_leftovers += G
+ else
+ gear_leftovers += G
+
+/datum/outfit/job/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ if(visualsOnly)
+ return
+
+ imprint_idcard(H)
+
+ H.sec_hud_set_ID()
+
+ imprint_pda(H)
+
+ if(implants)
+ for(var/implant_type in implants)
+ var/obj/item/weapon/implant/I = new implant_type(H)
+ I.imp_in = H
+ I.implanted = 1
+ H.sec_hud_set_implants()
+
+ if(gear_leftovers.len)
+ for(var/datum/gear/G in gear_leftovers)
+ var/atom/placed_in = H.equip_or_collect(G.spawn_item(null, H.client.prefs.gear[G.display_name]))
+ if(istype(placed_in))
+ if(isturf(placed_in))
+ to_chat(H, "Placing \the [G] on [placed_in]!")
+ else
+ to_chat(H, "Placing \the [G] in [placed_in.name]]")
+ continue
+ if(H.equip_to_appropriate_slot(G))
+ to_chat(H, "Placing \the [G] in your inventory!")
+ continue
+ if(H.put_in_hands(G))
+ to_chat(H, "Placing \the [G] in your hands!")
+ continue
+ to_chat(H, "Failed to locate a storage object on your mob, either you spawned with no hands free and no backpack or this is a bug.")
+ qdel(G)
+
+ qdel(gear_leftovers)
+
+ return 1
+
+/datum/outfit/job/proc/imprint_idcard(mob/living/carbon/human/H)
+ var/datum/job/J = job_master.GetJobType(jobtype)
+ if(!J)
+ J = job_master.GetJob(H.job)
+
+ var/alt_title
+ if(H.mind)
+ alt_title = H.mind.role_alt_title
+
+ var/obj/item/weapon/card/id/C = H.wear_id
+ if(istype(C))
+ C.access = J.get_access()
+ C.registered_name = H.real_name
+ C.rank = J.title
+ C.assignment = alt_title ? alt_title : J.title
+ C.sex = capitalize(H.gender)
+ C.age = H.age
+ C.name = "[C.registered_name]'s ID Card ([C.assignment])"
+ C.photo = get_id_photo(H)
+
+ if(H.mind && H.mind.initial_account)
+ C.associated_account_number = H.mind.initial_account.account_number
+
+/datum/outfit/job/proc/imprint_pda(mob/living/carbon/human/H)
+ var/obj/item/device/pda/PDA = H.wear_pda
+ var/obj/item/weapon/card/id/C = H.wear_id
+ if(istype(PDA) && istype(C))
+ PDA.owner = H.real_name
+ PDA.ownjob = C.assignment
+ PDA.ownrank = C.rank
+ PDA.name = "PDA-[H.real_name] ([PDA.ownjob])"
diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm
index 9e4e5f5acee..25a37f69496 100644
--- a/code/game/jobs/job/medical.dm
+++ b/code/game/jobs/job/medical.dm
@@ -7,7 +7,6 @@
is_medical = 1
supervisors = "the captain"
selection_color = "#ffddf0"
- idtype = /obj/item/weapon/card/id/cmo
req_admin_notify = 1
access = list(access_medical, access_morgue, access_genetics, access_heads,
access_chemistry, access_virology, access_cmo, access_surgery, access_RC_announce,
@@ -18,25 +17,27 @@
minimal_player_age = 21
exp_requirements = 600
exp_type = EXP_TYPE_CREW
+ outfit = /datum/outfit/job/cmo
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/heads/cmo(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack/medic(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_med(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/clothing/under/rank/chief_medical_officer(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/shoes/brown(H), slot_shoes)
- H.equip_or_collect(new /obj/item/device/pda/heads/cmo(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/clothing/suit/storage/labcoat/cmo(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/weapon/storage/firstaid/adv(H), slot_l_hand)
- H.equip_or_collect(new /obj/item/device/flashlight/pen(H), slot_s_store)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/melee/classic_baton/telescopic(H), slot_in_backpack)
- return 1
+/datum/outfit/job/cmo
+ name = "Chief Medical Officer"
+ jobtype = /datum/job/cmo
+ uniform = /obj/item/clothing/under/rank/chief_medical_officer
+ suit = /obj/item/clothing/suit/storage/labcoat/cmo
+ shoes = /obj/item/clothing/shoes/brown
+ l_ear = /obj/item/device/radio/headset/heads/cmo
+ id = /obj/item/weapon/card/id/cmo
+ suit_store = /obj/item/device/flashlight/pen
+ l_hand = /obj/item/weapon/storage/firstaid/adv
+ pda = /obj/item/device/pda/heads/cmo
+ backpack_contents = list(
+ /obj/item/weapon/melee/classic_baton/telescopic = 1
+ )
+ backpack = /obj/item/weapon/storage/backpack/medic
+ satchel = /obj/item/weapon/storage/backpack/satchel_med
+ dufflebag = /obj/item/weapon/storage/backpack/duffel/medical
/datum/job/doctor
title = "Medical Doctor"
@@ -47,54 +48,58 @@
is_medical = 1
supervisors = "the chief medical officer"
selection_color = "#ffeef0"
- idtype = /obj/item/weapon/card/id/medical
access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics, access_mineral_storeroom)
minimal_access = list(access_medical, access_morgue, access_surgery, access_maint_tunnels)
alt_titles = list("Surgeon","Nurse","Coroner")
minimal_player_age = 3
+ exp_requirements = 180
+ exp_type = EXP_TYPE_CREW
+ outfit = /datum/outfit/job/doctor
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_med(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack/medic(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_med(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- if(H.mind.role_alt_title)
- switch(H.mind.role_alt_title)
- if("Coroner")
- H.equip_or_collect(new /obj/item/clothing/under/rank/medical/mortician(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/suit/storage/labcoat/mortician(H), slot_wear_suit)
- if(H.backbag != 1)
- H.equip_or_collect(new /obj/item/clothing/head/surgery/black(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/autopsy_scanner(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/device/mass_spectrometer(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/storage/box/bodybags(H), slot_in_backpack)
- if("Surgeon")
- H.equip_or_collect(new /obj/item/clothing/under/rank/medical/blue(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/clothing/head/surgery/blue(H), slot_head)
- if("Medical Doctor")
- H.equip_or_collect(new /obj/item/clothing/under/rank/medical(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit)
- if("Nurse")
- if(H.gender == FEMALE)
- if(prob(50))
- H.equip_or_collect(new /obj/item/clothing/under/rank/nursesuit(H), slot_w_uniform)
- else
- H.equip_or_collect(new /obj/item/clothing/under/rank/nurse(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/head/nursehat(H), slot_head)
+/datum/outfit/job/doctor
+ name = "Medical Doctor"
+ jobtype = /datum/job/doctor
+
+ uniform = /obj/item/clothing/under/rank/medical
+ suit = /obj/item/clothing/suit/storage/labcoat
+ shoes = /obj/item/clothing/shoes/white
+ l_ear = /obj/item/device/radio/headset/headset_med
+ id = /obj/item/weapon/card/id/medical
+ suit_store = /obj/item/device/flashlight/pen
+ l_hand = /obj/item/weapon/storage/firstaid/adv
+ pda = /obj/item/device/pda/medical
+
+ backpack = /obj/item/weapon/storage/backpack/medic
+ satchel = /obj/item/weapon/storage/backpack/satchel_med
+ dufflebag = /obj/item/weapon/storage/backpack/duffel/medical
+
+/datum/outfit/job/doctor/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(H.mind.role_alt_title)
+ switch(H.mind.role_alt_title)
+ if("Coroner")
+ uniform = /obj/item/clothing/under/rank/medical/mortician
+ suit = /obj/item/clothing/suit/storage/labcoat/mortician
+ backpack_contents = list(
+ /obj/item/clothing/head/surgery/black = 1,
+ /obj/item/weapon/autopsy_scanner = 1,
+ /obj/item/device/mass_spectrometer = 1,
+ /obj/item/weapon/storage/box/bodybags = 1
+ )
+ if("Surgeon")
+ uniform = /obj/item/clothing/under/rank/medical/blue
+ head = /obj/item/clothing/head/surgery/blue
+ if("Medical Doctor")
+ uniform = /obj/item/clothing/under/rank/medical
+ if("Nurse")
+ if(H.gender == FEMALE)
+ if(prob(50))
+ uniform = /obj/item/clothing/under/rank/nursesuit
else
- H.equip_or_collect(new /obj/item/clothing/under/rank/medical/purple(H), slot_w_uniform)
- else
- H.equip_or_collect(new /obj/item/clothing/under/rank/medical(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/clothing/shoes/white(H), slot_shoes)
- H.equip_or_collect(new /obj/item/device/pda/medical(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/weapon/storage/firstaid/adv(H), slot_l_hand)
- H.equip_or_collect(new /obj/item/device/flashlight/pen(H), slot_s_store)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- return 1
+ uniform = /obj/item/clothing/under/rank/nurse
+ head = /obj/item/clothing/head/nursehat
+ else
+ uniform = /obj/item/clothing/under/rank/medical/purple
@@ -108,28 +113,29 @@
is_medical = 1
supervisors = "the chief medical officer"
selection_color = "#ffeef0"
- idtype = /obj/item/weapon/card/id/medical
access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics, access_mineral_storeroom)
minimal_access = list(access_medical, access_chemistry, access_maint_tunnels, access_mineral_storeroom)
alt_titles = list("Pharmacist","Pharmacologist")
minimal_player_age = 7
+ exp_requirements = 300
+ exp_type = EXP_TYPE_CREW
+ outfit = /datum/outfit/job/chemist
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- switch(H.backbag)
- if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/chemistry(H), slot_back)
- if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_chem(H), slot_back)
- if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_med(H), slot_l_ear)
- H.equip_or_collect(new /obj/item/clothing/glasses/science(H), slot_glasses)
- H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/chemist(H), slot_w_uniform)
- H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes)
- H.equip_to_slot_or_del(new /obj/item/device/pda/chemist(H), slot_wear_pda)
- H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/chemist(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- return 1
+/datum/outfit/job/chemist
+ name = "Chemist"
+ jobtype = /datum/job/chemist
+ uniform = /obj/item/clothing/under/rank/chemist
+ suit = /obj/item/clothing/suit/storage/labcoat/chemist
+ shoes = /obj/item/clothing/shoes/white
+ l_ear = /obj/item/device/radio/headset/headset_med
+ glasses = /obj/item/clothing/glasses/science
+ id = /obj/item/weapon/card/id/medical
+ pda = /obj/item/device/pda/chemist
+ backpack = /obj/item/weapon/storage/backpack/chemistry
+ satchel = /obj/item/weapon/storage/backpack/satchel_chem
+ dufflebag = /obj/item/weapon/storage/backpack/duffel/chemistry
/datum/job/geneticist
title = "Geneticist"
@@ -140,25 +146,29 @@
is_medical = 1
supervisors = "the chief medical officer and the research director"
selection_color = "#ffeef0"
- idtype = /obj/item/weapon/card/id/medical
access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics, access_research, access_mineral_storeroom)
minimal_access = list(access_medical, access_morgue, access_genetics, access_research, access_maint_tunnels)
minimal_player_age = 3
+ exp_requirements = 180
+ exp_type = EXP_TYPE_CREW
+ outfit = /datum/outfit/job/geneticist
+
+/datum/outfit/job/geneticist
+ name = "Geneticist"
+ jobtype = /datum/job/geneticist
+
+ uniform = /obj/item/clothing/under/rank/geneticist
+ suit = /obj/item/clothing/suit/storage/labcoat/genetics
+ shoes = /obj/item/clothing/shoes/white
+ l_ear = /obj/item/device/radio/headset/headset_medsci
+ id = /obj/item/weapon/card/id/medical
+ suit_store = /obj/item/device/flashlight/pen
+ pda = /obj/item/device/pda/geneticist
+
+ backpack = /obj/item/weapon/storage/backpack/genetics
+ satchel = /obj/item/weapon/storage/backpack/satchel_gen
+ dufflebag = /obj/item/weapon/storage/backpack/duffel/genetics
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- switch(H.backbag)
- if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/genetics(H), slot_back)
- if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_gen(H), slot_back)
- if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_medsci(H), slot_l_ear)
- H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/geneticist(H), slot_w_uniform)
- H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes)
- H.equip_to_slot_or_del(new /obj/item/device/pda/geneticist(H), slot_wear_pda)
- H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/genetics(H), slot_wear_suit)
- H.equip_to_slot_or_del(new /obj/item/device/flashlight/pen(H), slot_s_store)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- return 1
/datum/job/virologist
title = "Virologist"
@@ -169,27 +179,30 @@
is_medical = 1
supervisors = "the chief medical officer"
selection_color = "#ffeef0"
- idtype = /obj/item/weapon/card/id/medical
access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics)
minimal_access = list(access_medical, access_virology, access_maint_tunnels, access_mineral_storeroom)
alt_titles = list("Pathologist","Microbiologist")
minimal_player_age = 7
+ exp_requirements = 300
+ exp_type = EXP_TYPE_CREW
+ outfit = /datum/outfit/job/virologist
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_med(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack/virology(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_vir(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/clothing/under/rank/virologist(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/device/pda/viro(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/clothing/mask/surgical(H), slot_wear_mask)
- H.equip_or_collect(new /obj/item/clothing/shoes/white(H), slot_shoes)
- H.equip_or_collect(new /obj/item/clothing/suit/storage/labcoat/virologist(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/device/flashlight/pen(H), slot_s_store)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- return 1
+/datum/outfit/job/virologist
+ name = "Virologist"
+ jobtype = /datum/job/virologist
+
+ uniform = /obj/item/clothing/under/rank/virologist
+ suit = /obj/item/clothing/suit/storage/labcoat/virologist
+ shoes = /obj/item/clothing/shoes/white
+ mask = /obj/item/clothing/mask/surgical
+ l_ear = /obj/item/device/radio/headset/headset_med
+ id = /obj/item/weapon/card/id/medical
+ suit_store = /obj/item/device/flashlight/pen
+ pda = /obj/item/device/pda/viro
+
+ backpack = /obj/item/weapon/storage/backpack/virology
+ satchel = /obj/item/weapon/storage/backpack/satchel_vir
+ dufflebag = /obj/item/weapon/storage/backpack/duffel/virology
/datum/job/psychiatrist
title = "Psychiatrist"
@@ -200,34 +213,33 @@
is_medical = 1
supervisors = "the chief medical officer"
selection_color = "#ffeef0"
- idtype = /obj/item/weapon/card/id/medical
access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics, access_psychiatrist)
minimal_access = list(access_medical, access_psychiatrist, access_maint_tunnels)
alt_titles = list("Psychologist","Therapist")
+ outfit = /datum/outfit/job/psychiatrist
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_med(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
- if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
- if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- if(H.mind.role_alt_title)
- switch(H.mind.role_alt_title)
- if("Psychiatrist")
- H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/psych(H), slot_w_uniform)
- if("Psychologist")
- H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/psych/turtleneck(H), slot_w_uniform)
- if("Therapist")
- H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical(H), slot_w_uniform)
- else
- H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical(H), slot_w_uniform)
- H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit)
- H.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(H), slot_shoes)
- H.equip_to_slot_or_del(new /obj/item/device/pda/medical(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/device/flashlight/pen(H), slot_s_store)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- return 1
+/datum/outfit/job/psychiatrist
+ name = "Psychiatrist"
+ jobtype = /datum/job/psychiatrist
+
+ uniform = /obj/item/clothing/under/rank/medical
+ suit = /obj/item/clothing/suit/storage/labcoat
+ shoes = /obj/item/clothing/shoes/laceup
+ l_ear = /obj/item/device/radio/headset/headset_med
+ id = /obj/item/weapon/card/id/medical
+ suit_store = /obj/item/device/flashlight/pen
+ pda = /obj/item/device/pda/medical
+
+/datum/outfit/job/psychiatrist/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(H.mind.role_alt_title)
+ switch(H.mind.role_alt_title)
+ if("Psychiatrist")
+ uniform = /obj/item/clothing/under/rank/psych
+ if("Psychologist")
+ uniform = /obj/item/clothing/under/rank/psych/turtleneck
+ if("Therapist")
+ uniform = /obj/item/clothing/under/rank/medical
/datum/job/paramedic
title = "Paramedic"
@@ -238,23 +250,31 @@
is_medical = 1
supervisors = "the chief medical officer"
selection_color = "#ffeef0"
- idtype = /obj/item/weapon/card/id/medical
access = list(access_paramedic, access_medical, access_sec_doors, access_maint_tunnels, access_external_airlocks, access_morgue)
minimal_access=list(access_paramedic, access_medical, access_sec_doors, access_maint_tunnels, access_external_airlocks, access_morgue)
minimal_player_age = 3
+ exp_requirements = 180
+ exp_type = EXP_TYPE_CREW
+ outfit = /datum/outfit/job/paramedic
+/datum/outfit/job/paramedic
+ name = "Paramedic"
+ jobtype = /datum/job/paramedic
+
+ uniform = /obj/item/clothing/under/rank/medical/paramedic
+ shoes = /obj/item/clothing/shoes/black
+ head = /obj/item/clothing/head/soft/blue
+ mask = /obj/item/clothing/mask/cigarette
+ l_ear = /obj/item/device/radio/headset/headset_med
+ id = /obj/item/weapon/card/id/medical
+ l_pocket = /obj/item/device/flashlight/pen
+ pda = /obj/item/device/pda/medical
+ backpack_contents = list(
+ /obj/item/device/healthanalyzer = 1
+ )
+
+ backpack = /obj/item/weapon/storage/backpack/medic
+ satchel = /obj/item/weapon/storage/backpack/satchel_med
+ dufflebag = /obj/item/weapon/storage/backpack/duffel/medical
+ box = /obj/item/weapon/storage/box/engineer
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_med(H), slot_l_ear)
- if(H.backbag == 2) H.equip_or_collect(new /obj/item/weapon/storage/backpack/medic (H), slot_back)
- if(H.backbag == 3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_med(H), slot_back)
- H.equip_or_collect(new /obj/item/clothing/under/rank/medical/paramedic(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/shoes/black(H), slot_shoes)
- H.equip_or_collect(new /obj/item/device/pda/medical(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/clothing/mask/cigarette(H), slot_wear_mask)
- H.equip_or_collect(new /obj/item/clothing/head/soft/blue(H), slot_head)
- H.equip_or_collect(new /obj/item/device/flashlight/pen(H), slot_s_store)
- H.equip_or_collect(new /obj/item/weapon/storage/box/engineer(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/device/healthanalyzer(H), slot_in_backpack)
- return 1
diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm
index 2e07a08b2bc..bfab5c736ec 100644
--- a/code/game/jobs/job/science.dm
+++ b/code/game/jobs/job/science.dm
@@ -1,116 +1,121 @@
-/datum/job/rd
- title = "Research Director"
- flag = RD
- department_flag = MEDSCI
- total_positions = 1
- spawn_positions = 1
- is_science = 1
- supervisors = "the captain"
- selection_color = "#ffddff"
- req_admin_notify = 1
- idtype = /obj/item/weapon/card/id/rd
- access = list(access_rd, access_heads, access_tox, access_genetics, access_morgue,
- access_tox_storage, access_tech_storage, access_teleporter, access_sec_doors,
- access_research, access_robotics, access_xenobiology, access_ai_upload,
- access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_minisat, access_mineral_storeroom)
- minimal_access = list(access_eva, access_rd, access_heads, access_tox, access_genetics, access_morgue,
- access_tox_storage, access_tech_storage, access_teleporter, access_sec_doors,
- access_research, access_robotics, access_xenobiology, access_ai_upload,
- access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_minisat, access_maint_tunnels, access_mineral_storeroom)
- minimal_player_age = 21
- exp_requirements = 600
- exp_type = EXP_TYPE_CREW
-
- // All science-y guys get bonuses for maxing out their tech.
- required_objectives=list(
- /datum/job_objective/further_research
- )
-
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- switch(H.backbag)
- if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/science(H), slot_back)
- if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back)
- if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/rd(H), slot_l_ear)
- H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes)
- H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/research_director(H), slot_w_uniform)
- H.equip_to_slot_or_del(new /obj/item/device/pda/heads/rd(H), slot_wear_pda)
- H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit)
- H.equip_to_slot_or_del(new /obj/item/weapon/clipboard(H), slot_l_hand)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/melee/classic_baton/telescopic(H), slot_in_backpack)
- return 1
-
-
-
-/datum/job/scientist
- title = "Scientist"
- flag = SCIENTIST
- department_flag = MEDSCI
- total_positions = 6
- spawn_positions = 6
- is_science = 1
- supervisors = "the research director"
- selection_color = "#ffeeff"
- idtype = /obj/item/weapon/card/id/research
- access = list(access_robotics, access_tox, access_tox_storage, access_research, access_xenobiology, access_xenoarch, access_mineral_storeroom)
- minimal_access = list(access_tox, access_tox_storage, access_research, access_xenobiology, access_xenoarch, access_maint_tunnels, access_mineral_storeroom)
- alt_titles = list("Xenoarcheologist", "Anomalist", "Plasma Researcher", "Xenobiologist", "Chemical Researcher")
- minimal_player_age = 3
-
- // All science-y guys get bonuses for maxing out their tech.
- required_objectives=list(
- /datum/job_objective/further_research
- )
-
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- switch(H.backbag)
- if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/science(H), slot_back)
- if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back)
- if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sci(H), slot_l_ear)
- H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/scientist(H), slot_w_uniform)
- H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes)
- H.equip_to_slot_or_del(new /obj/item/device/pda/toxins(H), slot_wear_pda)
- H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/science(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- return 1
-
-
-
-/datum/job/roboticist
- title = "Roboticist"
- flag = ROBOTICIST
- department_flag = MEDSCI
- total_positions = 2
- spawn_positions = 2
- is_science = 1
- supervisors = "the research director"
- selection_color = "#ffeeff"
- idtype = /obj/item/weapon/card/id/research
- access = list(access_robotics, access_tox, access_tox_storage, access_tech_storage, access_morgue, access_research, access_mineral_storeroom) //As a job that handles so many corpses, it makes sense for them to have morgue access.
- minimal_access = list(access_robotics, access_tech_storage, access_morgue, access_research, access_maint_tunnels, access_mineral_storeroom) //As a job that handles so many corpses, it makes sense for them to have morgue access.
- alt_titles = list("Biomechanical Engineer","Mechatronic Engineer")
- minimal_player_age = 3
-
- required_objectives=list(
- /datum/job_objective/make_cyborg,
- /datum/job_objective/make_ripley
- )
-
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_sci(H), slot_l_ear)
- H.equip_or_collect(new /obj/item/clothing/under/rank/roboticist(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/shoes/black(H), slot_shoes)
- 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/weapon/storage/belt/utility/full(H), slot_belt)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- return 1
+/datum/job/rd
+ title = "Research Director"
+ flag = RD
+ department_flag = MEDSCI
+ total_positions = 1
+ spawn_positions = 1
+ is_science = 1
+ supervisors = "the captain"
+ selection_color = "#ffddff"
+ req_admin_notify = 1
+ access = list(access_rd, access_heads, access_tox, access_genetics, access_morgue,
+ access_tox_storage, access_tech_storage, access_teleporter, access_sec_doors,
+ access_research, access_robotics, access_xenobiology, access_ai_upload,
+ access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_minisat, access_mineral_storeroom, access_network)
+ minimal_access = list(access_eva, access_rd, access_heads, access_tox, access_genetics, access_morgue,
+ access_tox_storage, access_tech_storage, access_teleporter, access_sec_doors,
+ access_research, access_robotics, access_xenobiology, access_ai_upload,
+ access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_minisat, access_maint_tunnels, access_mineral_storeroom, access_network)
+ minimal_player_age = 21
+ exp_requirements = 600
+ exp_type = EXP_TYPE_CREW
+
+ // All science-y guys get bonuses for maxing out their tech.
+ required_objectives = list(
+ /datum/job_objective/further_research
+ )
+
+ outfit = /datum/outfit/job/rd
+
+/datum/outfit/job/rd
+ name = "Research Director"
+ jobtype = /datum/job/rd
+
+ uniform = /obj/item/clothing/under/rank/research_director
+ suit = /obj/item/clothing/suit/storage/labcoat
+ shoes = /obj/item/clothing/shoes/brown
+ l_ear = /obj/item/device/radio/headset/heads/rd
+ id = /obj/item/weapon/card/id/rd
+ l_hand = /obj/item/weapon/clipboard
+ pda = /obj/item/device/pda/heads/rd
+ backpack_contents = list(
+ /obj/item/weapon/melee/classic_baton/telescopic = 1
+ )
+
+ backpack = /obj/item/weapon/storage/backpack/science
+ satchel = /obj/item/weapon/storage/backpack/satchel_tox
+ dufflebag = /obj/item/weapon/storage/backpack/duffel/science
+
+
+/datum/job/scientist
+ title = "Scientist"
+ flag = SCIENTIST
+ department_flag = MEDSCI
+ total_positions = 6
+ spawn_positions = 6
+ is_science = 1
+ supervisors = "the research director"
+ selection_color = "#ffeeff"
+ access = list(access_robotics, access_tox, access_tox_storage, access_research, access_xenobiology, access_xenoarch, access_mineral_storeroom)
+ minimal_access = list(access_tox, access_tox_storage, access_research, access_xenobiology, access_xenoarch, access_maint_tunnels, access_mineral_storeroom)
+ alt_titles = list("Xenoarcheologist", "Anomalist", "Plasma Researcher", "Xenobiologist", "Chemical Researcher")
+ minimal_player_age = 3
+ exp_requirements = 300
+ exp_type = EXP_TYPE_CREW
+ // All science-y guys get bonuses for maxing out their tech.
+ required_objectives = list(
+ /datum/job_objective/further_research
+ )
+
+ outfit = /datum/outfit/job/scientist
+
+/datum/outfit/job/scientist
+ name = "Scientist"
+ jobtype = /datum/job/scientist
+
+ uniform = /obj/item/clothing/under/rank/scientist
+ suit = /obj/item/clothing/suit/storage/labcoat/science
+ shoes = /obj/item/clothing/shoes/white
+ l_ear = /obj/item/device/radio/headset/headset_sci
+ id = /obj/item/weapon/card/id/research
+ pda = /obj/item/device/pda/toxins
+
+ backpack = /obj/item/weapon/storage/backpack/science
+ satchel = /obj/item/weapon/storage/backpack/satchel_tox
+ dufflebag = /obj/item/weapon/storage/backpack/duffel/science
+
+
+/datum/job/roboticist
+ title = "Roboticist"
+ flag = ROBOTICIST
+ department_flag = MEDSCI
+ total_positions = 2
+ spawn_positions = 2
+ is_science = 1
+ supervisors = "the research director"
+ selection_color = "#ffeeff"
+ access = list(access_robotics, access_tox, access_tox_storage, access_tech_storage, access_morgue, access_research, access_mineral_storeroom) //As a job that handles so many corpses, it makes sense for them to have morgue access.
+ minimal_access = list(access_robotics, access_tech_storage, access_morgue, access_research, access_maint_tunnels, access_mineral_storeroom) //As a job that handles so many corpses, it makes sense for them to have morgue access.
+ alt_titles = list("Biomechanical Engineer","Mechatronic Engineer")
+ minimal_player_age = 3
+ exp_requirements = 180
+ exp_type = EXP_TYPE_CREW
+
+ required_objectives = list(
+ /datum/job_objective/make_cyborg,
+ /datum/job_objective/make_ripley
+ )
+
+ outfit = /datum/outfit/job/roboticist
+
+/datum/outfit/job/roboticist
+ name = "Roboticist"
+ jobtype = /datum/job/roboticist
+
+ uniform = /obj/item/clothing/under/rank/roboticist
+ suit = /obj/item/clothing/suit/storage/labcoat
+ belt = /obj/item/weapon/storage/belt/utility/full
+ shoes = /obj/item/clothing/shoes/black
+ l_ear = /obj/item/device/radio/headset/headset_sci
+ id = /obj/item/weapon/card/id/research
+ pda = /obj/item/device/pda/roboticist
diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm
index cd1e3fb370d..a7ed2b6b7a8 100644
--- a/code/game/jobs/job/security.dm
+++ b/code/game/jobs/job/security.dm
@@ -7,7 +7,6 @@
is_security = 1
supervisors = "the captain"
selection_color = "#ffdddd"
- idtype = /obj/item/weapon/card/id/hos
req_admin_notify = 1
access = list(access_security, access_sec_doors, access_brig, access_armory, access_court,
access_forensics_lockers, access_pilot, access_morgue, access_maint_tunnels, access_all_personal_lockers,
@@ -20,30 +19,32 @@
minimal_player_age = 21
exp_requirements = 600
exp_type = EXP_TYPE_CREW
+ outfit = /datum/outfit/job/hos
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack/security(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_sec(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/device/radio/headset/heads/hos/alt(H), slot_l_ear)
- H.equip_or_collect(new /obj/item/clothing/under/rank/head_of_security(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/shoes/jackboots(H), slot_shoes)
- H.equip_or_collect(new /obj/item/clothing/suit/armor/hos(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/device/pda/heads/hos(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/clothing/gloves/color/black/hos(H), slot_gloves)
- H.equip_or_collect(new /obj/item/clothing/head/HoS(H), slot_head)
- H.equip_or_collect(new /obj/item/clothing/glasses/hud/security/sunglasses(H), slot_glasses)
- H.equip_or_collect(new /obj/item/weapon/gun/energy/gun(H), slot_s_store)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(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/classic_baton/telescopic(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
- H.sec_hud_set_implants()
- return 1
+/datum/outfit/job/hos
+ name = "Head of Security"
+ jobtype = /datum/job/hos
+
+ uniform = /obj/item/clothing/under/rank/head_of_security
+ suit = /obj/item/clothing/suit/armor/hos
+ gloves = /obj/item/clothing/gloves/color/black/hos
+ shoes = /obj/item/clothing/shoes/jackboots
+ head = /obj/item/clothing/head/HoS
+ l_ear = /obj/item/device/radio/headset/heads/hos/alt
+ glasses = /obj/item/clothing/glasses/hud/security/sunglasses
+ id = /obj/item/weapon/card/id/hos
+ suit_store = /obj/item/weapon/gun/energy/gun
+ pda = /obj/item/device/pda/heads/hos
+ backpack_contents = list(
+ /obj/item/weapon/restraints/handcuffs = 1,
+ /obj/item/weapon/melee/classic_baton/telescopic = 1
+ )
+
+ implants = list(/obj/item/weapon/implant/mindshield)
+
+ backpack = /obj/item/weapon/storage/backpack/security
+ satchel = /obj/item/weapon/storage/backpack/satchel_sec
+ dufflebag = /obj/item/weapon/storage/backpack/duffel/security
@@ -56,37 +57,37 @@
is_security = 1
supervisors = "the head of security"
selection_color = "#ffeeee"
- idtype = /obj/item/weapon/card/id/security
access = list(access_security, access_sec_doors, access_brig, access_armory, access_court, access_maint_tunnels, access_morgue, access_weapons)
minimal_access = list(access_security, access_sec_doors, access_brig, access_armory, access_court, access_maint_tunnels, access_weapons)
minimal_player_age = 21
exp_requirements = 300
exp_type = EXP_TYPE_CREW
+ outfit = /datum/outfit/job/warden
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_sec/alt(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack/security(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_sec(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/clothing/under/rank/warden(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/shoes/jackboots(H), slot_shoes)
- H.equip_or_collect(new /obj/item/clothing/suit/armor/vest/warden(H), slot_wear_suit)
- H.equip_to_slot_or_del(new /obj/item/clothing/head/warden(H), slot_head)
- H.equip_or_collect(new /obj/item/device/pda/warden(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/clothing/gloves/color/black(H), slot_gloves)
- H.equip_or_collect(new /obj/item/clothing/glasses/hud/security/sunglasses(H), slot_glasses)
-// H.equip_or_collect(new /obj/item/clothing/mask/gas(H), slot_wear_mask) //Grab one from the armory you donk
- H.equip_or_collect(new /obj/item/device/flash(H), slot_l_store)
- H.equip_or_collect(new /obj/item/weapon/gun/energy/gun/advtaser(H), slot_s_store)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(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
- H.sec_hud_set_implants()
- return 1
+/datum/outfit/job/warden
+ name = "Warden"
+ jobtype = /datum/job/warden
+
+ uniform = /obj/item/clothing/under/rank/warden
+ suit = /obj/item/clothing/suit/armor/vest/warden
+ gloves = /obj/item/clothing/gloves/color/black
+ shoes = /obj/item/clothing/shoes/jackboots
+ head = /obj/item/clothing/head/warden
+ l_ear = /obj/item/device/radio/headset/headset_sec/alt
+ glasses = /obj/item/clothing/glasses/hud/security/sunglasses
+ id = /obj/item/weapon/card/id/security
+ l_pocket = /obj/item/device/flash
+ suit_store = /obj/item/weapon/gun/energy/gun/advtaser
+ pda = /obj/item/device/pda/warden
+ backpack_contents = list(
+ /obj/item/weapon/restraints/handcuffs = 1
+ )
+
+ implants = list(/obj/item/weapon/implant/mindshield)
+
+ backpack = /obj/item/weapon/storage/backpack/security
+ satchel = /obj/item/weapon/storage/backpack/satchel_sec
+ dufflebag = /obj/item/weapon/storage/backpack/duffel/security
@@ -100,50 +101,53 @@
supervisors = "the head of security"
selection_color = "#ffeeee"
alt_titles = list("Forensic Technician")
- idtype = /obj/item/weapon/card/id/security
access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_court, access_weapons)
minimal_access = list(access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_court, access_weapons)
alt_titles = list("Forensic Technician")
minimal_player_age = 14
exp_requirements = 300
exp_type = EXP_TYPE_CREW
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_sec/alt(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/clothing/under/det(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/shoes/brown(H), slot_shoes)
- H.equip_or_collect(new /obj/item/device/pda/detective(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/toy/crayon/white(H), slot_l_store)
-/* var/obj/item/clothing/mask/cigarette/CIG = new /obj/item/clothing/mask/cigarette(H)
- CIG.light("")
- H.equip_or_collect(CIG, slot_wear_mask) */
- H.equip_or_collect(new /obj/item/clothing/glasses/sunglasses/noir(H),slot_glasses)
- H.equip_or_collect(new /obj/item/clothing/gloves/color/black(H), slot_gloves)
- if(H.mind.role_alt_title && H.mind.role_alt_title == "Forensic Technician")
- H.equip_or_collect(new /obj/item/clothing/suit/storage/det_suit/forensics/blue(H), slot_wear_suit)
- else
- H.equip_or_collect(new /obj/item/clothing/suit/storage/det_suit(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/clothing/head/det_hat(H), slot_head)
- H.equip_or_collect(new /obj/item/weapon/lighter/zippo(H), slot_l_store)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/storage/box/evidence(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/device/detective_scanner(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/melee/classic_baton/telescopic(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
- H.sec_hud_set_implants()
+ outfit = /datum/outfit/job/detective
- H.dna.SetSEState(SOBERBLOCK,1)
- H.mutations += SOBER
- H.check_mutations = 1
- return 1
+/datum/outfit/job/detective
+ name = "Detective"
+ jobtype = /datum/job/detective
+ uniform = /obj/item/clothing/under/det
+ suit = /obj/item/clothing/suit/storage/det_suit
+ gloves = /obj/item/clothing/gloves/color/black
+ shoes = /obj/item/clothing/shoes/brown
+ head = /obj/item/clothing/head/det_hat
+ l_ear = /obj/item/device/radio/headset/headset_sec/alt
+ glasses = /obj/item/clothing/glasses/sunglasses/noir
+ id = /obj/item/weapon/card/id/security
+ l_pocket = /obj/item/toy/crayon/white
+ r_pocket = /obj/item/weapon/lighter/zippo
+ pda = /obj/item/device/pda/detective
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/evidence = 1,
+ /obj/item/device/detective_scanner = 1,
+ /obj/item/weapon/melee/classic_baton/telescopic = 1
+ )
+ implants = list(/obj/item/weapon/implant/mindshield)
+
+/datum/outfit/job/detective/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(H.mind.role_alt_title)
+ switch(H.mind.role_alt_title)
+ if("Forensic Technician")
+ suit = /obj/item/clothing/suit/storage/det_suit/forensics/blue
+ head = null
+
+/datum/outfit/job/detective/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ H.dna.SetSEState(SOBERBLOCK,1)
+ H.mutations += SOBER
+ H.check_mutations = 1
/datum/job/officer
title = "Security Officer"
@@ -154,34 +158,38 @@
is_security = 1
supervisors = "the head of security"
selection_color = "#ffeeee"
- idtype = /obj/item/weapon/card/id/security
access = list(access_security, access_sec_doors, access_brig, access_court, access_maint_tunnels, access_morgue, access_weapons)
minimal_access = list(access_security, access_sec_doors, access_brig, access_court, access_maint_tunnels, access_weapons)
minimal_player_age = 14
exp_requirements = 300
exp_type = EXP_TYPE_CREW
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_sec/alt(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack/security(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_sec(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/clothing/under/rank/security(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/shoes/jackboots(H), slot_shoes)
- H.equip_or_collect(new /obj/item/clothing/suit/armor/vest/security(H), slot_wear_suit)
- H.equip_to_slot_or_del(new /obj/item/clothing/head/helmet(H), slot_head)
- H.equip_or_collect(new /obj/item/device/pda/security(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/clothing/gloves/color/black(H), slot_gloves)
- H.equip_or_collect(new /obj/item/weapon/gun/energy/gun/advtaser(H), slot_s_store)
- H.equip_or_collect(new /obj/item/device/flash(H), slot_l_store)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(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
- H.sec_hud_set_implants()
- return 1
+ outfit = /datum/outfit/job/officer
+
+/datum/outfit/job/officer
+ name = "Security Officer"
+ jobtype = /datum/job/officer
+
+ uniform = /obj/item/clothing/under/rank/security
+ suit = /obj/item/clothing/suit/armor/vest/security
+ gloves = /obj/item/clothing/gloves/color/black
+ shoes = /obj/item/clothing/shoes/jackboots
+ head = /obj/item/clothing/head/helmet
+ l_ear = /obj/item/device/radio/headset/headset_sec/alt
+ id = /obj/item/weapon/card/id/security
+ l_pocket = /obj/item/device/flash
+ suit_store = /obj/item/weapon/gun/energy/gun/advtaser
+ pda = /obj/item/device/pda/security
+ backpack_contents = list(
+ /obj/item/weapon/restraints/handcuffs = 1
+ )
+
+ implants = list(/obj/item/weapon/implant/mindshield)
+
+ backpack = /obj/item/weapon/storage/backpack/security
+ satchel = /obj/item/weapon/storage/backpack/satchel_sec
+ dufflebag = /obj/item/weapon/storage/backpack/duffel/security
+
+
/datum/job/brigdoc
title = "Brig Physician"
@@ -192,30 +200,31 @@
is_security = 1
supervisors = "the head of security"
selection_color = "#ffeeee"
- idtype = /obj/item/weapon/card/id/security
access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics)
minimal_access = list(access_medical, access_morgue, access_surgery, access_security, access_sec_doors, access_brig, access_court, access_maint_tunnels)
+ outfit = /datum/outfit/job/brigdoc
+
+/datum/outfit/job/brigdoc
+ name = "Brig Physician"
+ jobtype = /datum/job/brigdoc
+
+ uniform = /obj/item/clothing/under/rank/security/brigphys
+ suit = /obj/item/clothing/suit/storage/fr_jacket
+ shoes = /obj/item/clothing/shoes/white
+ l_ear = /obj/item/device/radio/headset/headset_sec/alt
+ glasses = /obj/item/clothing/glasses/hud/health/health_advanced
+ id = /obj/item/weapon/card/id/security
+ suit_store = /obj/item/device/flashlight/pen
+ l_hand = /obj/item/weapon/storage/firstaid/adv
+ pda = /obj/item/device/pda/medical
+
+ implants = list(/obj/item/weapon/implant/mindshield)
+
+ backpack = /obj/item/weapon/storage/backpack/medic
+ satchel = /obj/item/weapon/storage/backpack/satchel_med
+ dufflebag = /obj/item/weapon/storage/backpack/duffel/medical
+
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_sec/alt(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack/medic(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_med(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/clothing/under/rank/security/brigphys(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/suit/storage/fr_jacket(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/clothing/glasses/hud/health/health_advanced, slot_glasses)
- H.equip_or_collect(new /obj/item/clothing/shoes/white(H), slot_shoes)
- H.equip_or_collect(new /obj/item/device/pda/medical(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/weapon/storage/firstaid/adv(H), slot_l_hand)
- H.equip_or_collect(new /obj/item/device/flashlight/pen(H), slot_s_store)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(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
- H.sec_hud_set_implants()
- return 1
/datum/job/pilot
title = "Security Pod Pilot"
@@ -226,28 +235,31 @@
is_security = 1
supervisors = "the head of security"
selection_color = "#ffeeee"
- idtype = /obj/item/weapon/card/id/security
access = list(access_security, access_sec_doors, access_brig, access_court, access_maint_tunnels, access_morgue, access_weapons, access_pilot, access_external_airlocks)
minimal_access = list(access_security, access_sec_doors, access_brig, access_court, access_maint_tunnels, access_weapons, access_pilot, access_external_airlocks)
minimal_player_age = 7
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_sec/alt(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack/security(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_sec(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/clothing/under/rank/security/pod_pilot(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/suit/jacket/pilot(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/clothing/shoes/jackboots(H), slot_shoes)
- H.equip_or_collect(new /obj/item/device/pda/security(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/clothing/gloves/color/black(H), slot_gloves)
- H.equip_or_collect(new /obj/item/weapon/gun/energy/gun/advtaser(H), slot_s_store)
- H.equip_or_collect(new /obj/item/device/flash(H), slot_l_store)
- H.equip_or_collect(new /obj/item/weapon/storage/box/engineer(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
- H.sec_hud_set_implants()
- return 1
+ outfit = /datum/outfit/job/pilot
+
+/datum/outfit/job/pilot
+ name = "Security Pod Pilot"
+ jobtype = /datum/job/pilot
+
+ uniform = /obj/item/clothing/under/rank/security/pod_pilot
+ suit = /obj/item/clothing/suit/jacket/pilot
+ gloves = /obj/item/clothing/gloves/color/black
+ shoes = /obj/item/clothing/shoes/jackboots
+ l_ear = /obj/item/device/radio/headset/headset_sec/alt
+ id = /obj/item/weapon/card/id/security
+ l_pocket = /obj/item/device/flash
+ suit_store = /obj/item/weapon/gun/energy/gun/advtaser
+ pda = /obj/item/device/pda/security
+ backpack_contents = list(
+ /obj/item/weapon/restraints/handcuffs = 1
+ )
+
+ implants = list(/obj/item/weapon/implant/mindshield)
+
+ backpack = /obj/item/weapon/storage/backpack/security
+ satchel = /obj/item/weapon/storage/backpack/satchel_sec
+ dufflebag = /obj/item/weapon/storage/backpack/duffel/security
+ box = /obj/item/weapon/storage/box/engineer
\ No newline at end of file
diff --git a/code/game/jobs/job/silicon.dm b/code/game/jobs/job/silicon.dm
index 1331db02791..1b092087997 100644
--- a/code/game/jobs/job/silicon.dm
+++ b/code/game/jobs/job/silicon.dm
@@ -11,9 +11,9 @@
exp_requirements = 1200
exp_type = EXP_TYPE_CREW
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- return 1
+/datum/job/ai/equip(mob/living/carbon/human/H)
+ if(!H)
+ return 0
/datum/job/ai/is_position_available()
return (empty_playable_ai_cores.len != 0)
@@ -32,6 +32,7 @@
exp_type = EXP_TYPE_CREW
alt_titles = list("Android", "Robot")
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- return 1
\ No newline at end of file
+/datum/job/cyborg/equip(mob/living/carbon/human/H)
+ if(!H)
+ return 0
+ return H.Robotize()
\ No newline at end of file
diff --git a/code/game/jobs/job/supervisor.dm b/code/game/jobs/job/supervisor.dm
index 981753c5aee..e1b6bfda98e 100644
--- a/code/game/jobs/job/supervisor.dm
+++ b/code/game/jobs/job/supervisor.dm
@@ -7,7 +7,6 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0)
spawn_positions = 1
supervisors = "Nanotrasen officials"
selection_color = "#ccccff"
- idtype = /obj/item/weapon/card/id/gold
req_admin_notify = 1
is_command = 1
access = list() //See get_access()
@@ -15,36 +14,46 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0)
minimal_player_age = 30
exp_requirements = 1200
exp_type = EXP_TYPE_CREW
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/heads/captain/alt(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack/captain(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_cap(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- var/obj/item/clothing/under/U = new /obj/item/clothing/under/rank/captain(H)
+ outfit = /datum/outfit/job/captain
+
+/datum/job/captain/get_access()
+ return get_all_accesses()
+
+/datum/job/captain/announce(mob/living/carbon/human/H)
+ . = ..()
+ captain_announcement.Announce("All hands, Captain [H.real_name] on deck!")
+ callHook("captain_spawned", list("captain" = H))
+
+/datum/outfit/job/captain
+ name = "Captain"
+ jobtype = /datum/job/captain
+
+ uniform = /obj/item/clothing/under/rank/captain
+ suit = /obj/item/clothing/suit/armor/vest/capcarapace
+ shoes = /obj/item/clothing/shoes/brown
+ head = /obj/item/clothing/head/caphat
+ l_ear = /obj/item/device/radio/headset/heads/captain/alt
+ glasses = /obj/item/clothing/glasses/sunglasses
+ id = /obj/item/weapon/card/id/gold
+ pda = /obj/item/device/pda/captain
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/ids = 1,
+ /obj/item/weapon/melee/classic_baton/telescopic = 1
+ )
+
+ implants = list(/obj/item/weapon/implant/mindshield)
+
+ backpack = /obj/item/weapon/storage/backpack/captain
+ satchel = /obj/item/weapon/storage/backpack/satchel_cap
+ dufflebag = /obj/item/weapon/storage/backpack/duffel/captain
+
+/datum/outfit/job/captain/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(H && H.w_uniform)
+ var/obj/item/clothing/under/U = H.w_uniform
var/obj/item/clothing/accessory/medal/gold/captain/M = new /obj/item/clothing/accessory/medal/gold/captain(U)
U.accessories += M
M.on_attached(U)
- H.equip_or_collect(U, slot_w_uniform)
- H.equip_or_collect(new /obj/item/device/pda/captain(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/clothing/suit/armor/vest/capcarapace(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/clothing/shoes/brown(H), slot_shoes)
- H.equip_or_collect(new /obj/item/clothing/head/caphat(H), slot_head)
- H.equip_or_collect(new /obj/item/clothing/glasses/sunglasses(H), slot_glasses)
- H.equip_or_collect(new /obj/item/weapon/storage/box/ids(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/melee/classic_baton/telescopic(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
- H.sec_hud_set_implants()
- captain_announcement.Announce("All hands, Captain [H.real_name] on deck!")
- callHook("captain_spawned", list("captain" = H))
- return 1
-
- get_access()
- return get_all_accesses()
@@ -56,7 +65,6 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0)
spawn_positions = 1
supervisors = "the captain"
selection_color = "#ddddff"
- idtype = /obj/item/weapon/card/id/silver
req_admin_notify = 1
is_command = 1
minimal_player_age = 21
@@ -75,22 +83,25 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0)
access_theatre, access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station,
access_clown, access_mime, access_hop, access_RC_announce, access_keycard_auth, access_gateway, access_weapons, access_mineral_storeroom)
+ outfit = /datum/outfit/job/hop
+
+/datum/outfit/job/hop
+ name = "Head of Personnel"
+ jobtype = /datum/job/hop
+
+ uniform = /obj/item/clothing/under/rank/head_of_personnel
+ shoes = /obj/item/clothing/shoes/brown
+ head = /obj/item/clothing/head/hopcap
+ l_ear = /obj/item/device/radio/headset/heads/hop
+ id = /obj/item/weapon/card/id/silver
+ pda = /obj/item/device/pda/heads/hop
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/ids = 1,
+ /obj/item/weapon/melee/classic_baton/telescopic = 1
+ )
+
+ implants = list()
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/heads/hop(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/clothing/under/rank/head_of_personnel(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/head/hopcap(H), slot_head)
- H.equip_or_collect(new /obj/item/clothing/shoes/brown(H), slot_shoes)
- H.equip_or_collect(new /obj/item/device/pda/heads/hop(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/weapon/storage/box/ids(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/melee/classic_baton/telescopic(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- return 1
/datum/job/nanotrasenrep
@@ -101,7 +112,6 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0)
spawn_positions = 1
supervisors = "the command staff"
selection_color = "#ddddff"
- idtype = /obj/item/weapon/card/id/nanotrasen
req_admin_notify = 1
is_command = 1
minimal_player_age = 21
@@ -118,25 +128,26 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0)
access_theatre, access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station,
access_clown, access_mime, access_hop, access_RC_announce, access_keycard_auth, access_gateway, access_weapons, access_ntrep)
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/heads/ntrep(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/weapon/melee/classic_baton/ntcane(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/lighter/zippo/nt_rep(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/clothing/under/rank/ntrep(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/suit/storage/ntrep(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/clothing/shoes/centcom(H), slot_shoes)
- H.equip_or_collect(new /obj/item/device/pda/heads/ntrep(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(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
- H.sec_hud_set_implants()
- return 1
+ outfit = /datum/outfit/job/nanotrasenrep
+
+/datum/outfit/job/nanotrasenrep
+ name = "Nanotrasen Representative"
+ jobtype = /datum/job/nanotrasenrep
+
+ uniform = /obj/item/clothing/under/rank/ntrep
+ suit = /obj/item/clothing/suit/storage/ntrep
+ shoes = /obj/item/clothing/shoes/centcom
+ l_ear = /obj/item/device/radio/headset/heads/ntrep
+ id = /obj/item/weapon/card/id/nanotrasen
+ l_pocket = /obj/item/weapon/lighter/zippo/nt_rep
+ pda = /obj/item/device/pda/heads/ntrep
+ backpack_contents = list(
+ /obj/item/weapon/melee/classic_baton/ntcane = 1
+ )
+
+ implants = list(/obj/item/weapon/implant/mindshield)
+
+
/datum/job/blueshield
title = "Blueshield"
@@ -146,7 +157,6 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0)
spawn_positions = 1
supervisors = "the Nanotrasen representative"
selection_color = "#ddddff"
- idtype = /obj/item/weapon/card/id/nanotrasen
req_admin_notify = 1
is_command = 1
minimal_player_age = 21
@@ -159,27 +169,29 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0)
minimal_access = list(access_forensics_lockers, access_sec_doors, access_medical, access_construction, access_engine, access_maint_tunnels, access_research,
access_RC_announce, access_keycard_auth, access_heads, access_blueshield, access_weapons)
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/heads/blueshield/alt(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack/security(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/clothing/gloves/combat(H), slot_gloves)
- H.equip_or_collect(new /obj/item/clothing/shoes/jackboots(H), slot_shoes)
- H.equip_or_collect(new /obj/item/clothing/glasses/hud/health/health_advanced, slot_glasses)
- H.equip_or_collect(new /obj/item/clothing/under/rank/blueshield(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/suit/armor/vest/blueshield(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/device/pda/heads/blueshield(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/storage/box/deathimp(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/gun/energy/gun/blueshield(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
- H.sec_hud_set_implants()
- return 1
+ outfit = /datum/outfit/job/blueshield
+
+/datum/outfit/job/blueshield
+ name = "Blueshield"
+ jobtype = /datum/job/blueshield
+
+ uniform = /obj/item/clothing/under/rank/blueshield
+ suit = /obj/item/clothing/suit/armor/vest/blueshield
+ gloves = /obj/item/clothing/gloves/combat
+ shoes = /obj/item/clothing/shoes/jackboots
+ l_ear = /obj/item/device/radio/headset/heads/blueshield/alt
+ glasses = /obj/item/clothing/glasses/hud/health/health_advanced
+ id = /obj/item/weapon/card/id/nanotrasen
+ pda = /obj/item/device/pda/heads/blueshield
+ backpack_contents = list(
+ /obj/item/weapon/storage/box/deathimp = 1,
+ /obj/item/weapon/gun/energy/gun/blueshield = 1
+ )
+
+ implants = list(/obj/item/weapon/implant/mindshield)
+
+ backpack = /obj/item/weapon/storage/backpack/security
+
/datum/job/judge
title = "Magistrate"
@@ -189,7 +201,6 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0)
spawn_positions = 1
supervisors = "the Nanotrasen Supreme Court"
selection_color = "#ddddff"
- idtype = /obj/item/weapon/card/id/nanotrasen
req_admin_notify = 1
is_legal = 1
minimal_player_age = 30
@@ -199,29 +210,31 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0)
access_crematorium, access_kitchen, access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_hydroponics, access_lawyer,
access_theatre, access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station,
access_clown, access_mime, access_hop, access_RC_announce, access_keycard_auth, access_gateway, access_magistrate)
- minimal_access = list(access_security, access_sec_doors, access_brig, access_court, access_maint_tunnels, access_lawyer, access_magistrate)
+ minimal_access = list(access_security, access_sec_doors, access_brig, access_court, access_maint_tunnels, access_lawyer, access_magistrate, access_heads)
+
+ outfit = /datum/outfit/job/judge
+
+/datum/outfit/job/judge
+ name = "Magistrate"
+ jobtype = /datum/job/judge
+
+ uniform = /obj/item/clothing/under/suit_jacket/really_black
+ suit = /obj/item/clothing/suit/judgerobe
+ gloves = /obj/item/clothing/gloves/color/white
+ shoes = /obj/item/clothing/shoes/centcom
+ head = /obj/item/clothing/head/powdered_wig
+ l_ear = /obj/item/device/radio/headset/heads/magistrate/alt
+ glasses = /obj/item/clothing/glasses/hud/security/sunglasses
+ id = /obj/item/weapon/card/id/nanotrasen
+ l_pocket = /obj/item/device/flash
+ pda = /obj/item/device/pda/heads/magistrate
+ backpack_contents = list(
+ /obj/item/weapon/melee/classic_baton/telescopic = 1
+ )
+
+ implants = list(/obj/item/weapon/implant/mindshield)
+
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/heads/magistrate/alt(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/clothing/under/suit_jacket/really_black(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/suit/judgerobe(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/clothing/shoes/centcom(H), slot_shoes)
- H.equip_or_collect(new /obj/item/clothing/head/powdered_wig(H), slot_head)
- H.equip_or_collect(new /obj/item/clothing/glasses/hud/security/sunglasses(H), slot_glasses)
- H.equip_or_collect(new /obj/item/device/pda/heads/magistrate(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/weapon/melee/classic_baton/telescopic(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/device/flash(H), slot_r_store)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(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
- H.sec_hud_set_implants()
- return 1
//var/global/lawyer = 0//Checks for another lawyer //This changed clothes on 2nd lawyer, both IA get the same dreds.
/datum/job/lawyer
@@ -239,26 +252,21 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0)
minimal_player_age = 30
exp_requirements = 300
exp_type = EXP_TYPE_CREW
- idtype = /obj/item/weapon/card/id/security
+ outfit = /datum/outfit/job/lawyer
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_sec/alt(H), slot_l_ear)
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/clothing/under/rank/internalaffairs(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/suit/storage/internalaffairs(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/clothing/shoes/brown(H), slot_shoes)
- H.equip_or_collect(new /obj/item/clothing/glasses/hud/security/sunglasses(H), slot_glasses)
- H.equip_or_collect(new /obj/item/device/pda/lawyer(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/weapon/storage/briefcase(H), slot_l_hand)
- H.equip_or_collect(new /obj/item/device/laser_pointer(H), slot_l_store)
- H.equip_or_collect(new /obj/item/device/flash(H), slot_r_store)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(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
- H.sec_hud_set_implants()
- return 1
+/datum/outfit/job/lawyer
+ name = "Internal Affairs Agent"
+ jobtype = /datum/job/lawyer
+
+ uniform = /obj/item/clothing/under/rank/internalaffairs
+ suit = /obj/item/clothing/suit/storage/internalaffairs
+ shoes = /obj/item/clothing/shoes/brown
+ l_ear = /obj/item/device/radio/headset/headset_sec/alt
+ glasses = /obj/item/clothing/glasses/hud/security/sunglasses
+ id = /obj/item/weapon/card/id/security
+ l_pocket = /obj/item/device/laser_pointer
+ r_pocket = /obj/item/device/flash
+ l_hand = /obj/item/weapon/storage/briefcase
+ pda = /obj/item/device/pda/lawyer
+
+ implants = list(/obj/item/weapon/implant/mindshield)
diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm
index 2148c339000..b7d6b448895 100644
--- a/code/game/jobs/job/support.dm
+++ b/code/game/jobs/job/support.dm
@@ -10,29 +10,31 @@
selection_color = "#dddddd"
access = list(access_hydroponics, access_bar, access_kitchen, access_morgue, access_weapons, access_mineral_storeroom)
minimal_access = list(access_bar, access_maint_tunnels, access_weapons, access_mineral_storeroom)
+ outfit = /datum/outfit/job/bartender
+/datum/outfit/job/bartender
+ name = "Bartender"
+ jobtype = /datum/job/bartender
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_service(H), slot_l_ear)
- H.equip_or_collect(new /obj/item/clothing/glasses/sunglasses/reagent(H), slot_glasses)
- H.equip_or_collect(new /obj/item/clothing/shoes/black(H), slot_shoes)
- H.equip_or_collect(new /obj/item/clothing/suit/armor/vest(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/clothing/under/rank/bartender(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/device/pda/bar(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/weapon/storage/belt/bandolier/full(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/toy/russian_revolver(H), slot_in_backpack)
+ uniform = /obj/item/clothing/under/rank/bartender
+ suit = /obj/item/clothing/suit/armor/vest
+ belt = /obj/item/weapon/storage/belt/bandolier/full
+ shoes = /obj/item/clothing/shoes/black
+ l_ear = /obj/item/device/radio/headset/headset_service
+ glasses = /obj/item/clothing/glasses/sunglasses/reagent
+ pda = /obj/item/device/pda/bar
+ backpack_contents = list(
+ /obj/item/toy/russian_revolver = 1
+ )
- H.dna.SetSEState(SOBERBLOCK,1)
- H.mutations += SOBER
- H.check_mutations = 1
+/datum/outfit/job/bartender/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
- return 1
+ H.dna.SetSEState(SOBERBLOCK,1)
+ H.mutations += SOBER
+ H.check_mutations = 1
@@ -48,22 +50,18 @@
access = list(access_hydroponics, access_bar, access_kitchen, access_morgue)
minimal_access = list(access_kitchen, access_maint_tunnels)
alt_titles = list("Cook","Culinary Artist","Butcher")
+ outfit = /datum/outfit/job/chef
+/datum/outfit/job/chef
+ name = "Chef"
+ jobtype = /datum/job/chef
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_service(H), slot_l_ear)
- H.equip_or_collect(new /obj/item/clothing/under/rank/chef(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/suit/chef(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/clothing/shoes/black(H), slot_shoes)
- H.equip_or_collect(new /obj/item/clothing/head/chefhat(H), slot_head)
- H.equip_or_collect(new /obj/item/device/pda/chef(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- return 1
+ uniform = /obj/item/clothing/under/rank/chef
+ suit = /obj/item/clothing/suit/chef
+ shoes = /obj/item/clothing/shoes/black
+ head = /obj/item/clothing/head/chefhat
+ l_ear = /obj/item/device/radio/headset/headset_service
+ pda = /obj/item/device/pda/chef
@@ -79,23 +77,23 @@
access = list(access_hydroponics, access_bar, access_kitchen, access_morgue)
minimal_access = list(access_hydroponics, access_morgue, access_maint_tunnels)
alt_titles = list("Hydroponicist", "Botanical Researcher")
+ outfit = /datum/outfit/job/hydro
+/datum/outfit/job/hydro
+ name = "Botanist"
+ jobtype = /datum/job/hydro
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack/botany(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_hyd(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_service(H), slot_l_ear)
- H.equip_or_collect(new /obj/item/clothing/under/rank/hydroponics(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/shoes/black(H), slot_shoes)
- H.equip_or_collect(new /obj/item/clothing/gloves/botanic_leather(H), slot_gloves)
- H.equip_or_collect(new /obj/item/clothing/suit/apron(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/device/plant_analyzer(H), slot_s_store)
- H.equip_or_collect(new /obj/item/device/pda/botanist(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- return 1
+ uniform = /obj/item/clothing/under/rank/hydroponics
+ suit = /obj/item/clothing/suit/apron
+ gloves = /obj/item/clothing/gloves/botanic_leather
+ shoes = /obj/item/clothing/shoes/black
+ l_ear = /obj/item/device/radio/headset/headset_service
+ suit_store = /obj/item/device/plant_analyzer
+ pda = /obj/item/device/pda/botanist
+
+ backpack = /obj/item/weapon/storage/backpack/botany
+ satchel = /obj/item/weapon/storage/backpack/satchel_hyd
+ dufflebag = /obj/item/weapon/storage/backpack/duffel/hydro
@@ -109,25 +107,21 @@
is_supply = 1
supervisors = "the head of personnel"
selection_color = "#dddddd"
- idtype = /obj/item/weapon/card/id/supply
access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station, access_mineral_storeroom)
minimal_access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station, access_mineral_storeroom)
+ outfit = /datum/outfit/job/qm
+/datum/outfit/job/qm
+ name = "Quartermaster"
+ jobtype = /datum/job/qm
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_cargo(H), slot_l_ear)
- H.equip_or_collect(new /obj/item/clothing/under/rank/cargo(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/shoes/brown(H), slot_shoes)
- H.equip_or_collect(new /obj/item/device/pda/quartermaster(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/clothing/glasses/sunglasses(H), slot_glasses)
- H.equip_or_collect(new /obj/item/weapon/clipboard(H), slot_l_hand)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- return 1
+ uniform = /obj/item/clothing/under/rank/cargo
+ shoes = /obj/item/clothing/shoes/brown
+ l_ear = /obj/item/device/radio/headset/headset_cargo
+ glasses = /obj/item/clothing/glasses/sunglasses
+ id = /obj/item/weapon/card/id/supply
+ l_hand = /obj/item/weapon/clipboard
+ pda = /obj/item/device/pda/quartermaster
@@ -140,23 +134,19 @@
is_supply = 1
supervisors = "the quartermaster"
selection_color = "#dddddd"
- idtype = /obj/item/weapon/card/id/supply
access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station, access_mineral_storeroom)
minimal_access = list(access_maint_tunnels, access_cargo, access_cargo_bot, access_mailsorting, access_mineral_storeroom)
+ outfit = /datum/outfit/job/cargo_tech
+/datum/outfit/job/cargo_tech
+ name = "Cargo Technician"
+ jobtype = /datum/job/cargo_tech
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_cargo(H), slot_l_ear)
- H.equip_or_collect(new /obj/item/clothing/under/rank/cargotech(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/shoes/black(H), slot_shoes)
- H.equip_or_collect(new /obj/item/device/pda/cargo(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- return 1
+ uniform = /obj/item/clothing/under/rank/cargotech
+ shoes = /obj/item/clothing/shoes/black
+ l_ear = /obj/item/device/radio/headset/headset_cargo
+ id = /obj/item/weapon/card/id/supply
+ pda = /obj/item/device/pda/cargo
@@ -169,32 +159,30 @@
is_supply = 1
supervisors = "the quartermaster"
selection_color = "#dddddd"
- idtype = /obj/item/weapon/card/id/supply
access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station, access_mineral_storeroom)
minimal_access = list(access_mining, access_mint, access_mining_station, access_mailsorting, access_maint_tunnels, access_mineral_storeroom)
alt_titles = list("Spelunker")
+ outfit = /datum/outfit/job/mining
- equip(var/mob/living/carbon/human/H)
- if(!H)
- return 0
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_cargo/mining(H), slot_l_ear)
- switch(H.backbag)
- if(2)
- H.equip_or_collect(new /obj/item/weapon/storage/backpack/industrial(H), slot_back)
- if(3)
- H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_eng(H), slot_back)
- if(4)
- H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/clothing/under/rank/miner(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/gloves/fingerless(H), slot_gloves)
- H.equip_or_collect(new /obj/item/device/pda/shaftminer(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/clothing/shoes/workboots(H), slot_shoes)
- H.equip_or_collect(new /obj/item/weapon/reagent_containers/food/pill/patch/styptic(H), slot_l_store)
- H.equip_or_collect(new /obj/item/device/flashlight/seclite(H), slot_r_store)
- H.equip_or_collect(new /obj/item/weapon/mining_voucher(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/storage/bag/ore(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- return 1
+/datum/outfit/job/mining
+ name = "Shaft Miner"
+ jobtype = /datum/job/mining
+
+ uniform = /obj/item/clothing/under/rank/miner
+ gloves = /obj/item/clothing/gloves/fingerless
+ shoes = /obj/item/clothing/shoes/workboots
+ l_ear = /obj/item/device/radio/headset/headset_cargo/mining
+ id = /obj/item/weapon/card/id/supply
+ l_pocket = /obj/item/weapon/reagent_containers/food/pill/patch/styptic
+ r_pocket = /obj/item/device/flashlight/seclite
+ pda = /obj/item/device/pda/shaftminer
+ backpack_contents = list(
+ /obj/item/weapon/mining_voucher = 1,
+ /obj/item/weapon/storage/bag/ore = 1
+ )
+
+ backpack = /obj/item/weapon/storage/backpack/industrial
+ satchel = /obj/item/weapon/storage/backpack/satchel_eng
@@ -209,40 +197,51 @@
is_service = 1
supervisors = "the head of personnel"
selection_color = "#dddddd"
- idtype = /obj/item/weapon/card/id/clown
access = list(access_clown, access_theatre, access_maint_tunnels)
minimal_access = list(access_clown, access_theatre, access_maint_tunnels)
+ outfit = /datum/outfit/job/clown
+/datum/outfit/job/clown
+ name = "Clown"
+ jobtype = /datum/job/clown
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/weapon/storage/backpack/clown(H), slot_back)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- if(H.gender == FEMALE)
- H.equip_or_collect(new /obj/item/clothing/mask/gas/sexyclown(H), slot_wear_mask)
- H.equip_or_collect(new /obj/item/clothing/under/sexyclown(H), slot_w_uniform)
- else
- H.equip_or_collect(new /obj/item/clothing/under/rank/clown(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/mask/gas/clown_hat(H), slot_wear_mask)
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_service(H), slot_l_ear)
- H.equip_or_collect(new /obj/item/clothing/shoes/clown_shoes(H), slot_shoes)
- H.equip_or_collect(new /obj/item/device/pda/clown(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/clothing/mask/gas/clown_hat(H), slot_wear_mask)
- H.equip_or_collect(new /obj/item/weapon/reagent_containers/food/snacks/grown/banana(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/bikehorn(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/stamp/clown(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/toy/crayon/rainbow(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/storage/fancy/crayons(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/reagent_containers/spray/waterflower(H), slot_in_backpack)
- if(H.get_species() == "Machine")
- var/obj/item/organ/internal/cyberimp/brain/clown_voice/implant
- implant = new
- implant.insert(H)
- H.mutations.Add(CLUMSY)
- H.dna.SetSEState(COMICBLOCK,1,1)
- genemutcheck(H,COMICBLOCK,null,MUTCHK_FORCED)
- return 1
+ uniform = /obj/item/clothing/under/rank/clown
+ shoes = /obj/item/clothing/shoes/clown_shoes
+ mask = /obj/item/clothing/mask/gas/clown_hat
+ l_ear = /obj/item/device/radio/headset/headset_service
+ id = /obj/item/weapon/card/id/clown
+ pda = /obj/item/device/pda/clown
+ backpack_contents = list(
+ /obj/item/weapon/reagent_containers/food/snacks/grown/banana = 1,
+ /obj/item/weapon/bikehorn = 1,
+ /obj/item/weapon/stamp/clown = 1,
+ /obj/item/toy/crayon/rainbow = 1,
+ /obj/item/weapon/storage/fancy/crayons = 1,
+ /obj/item/weapon/reagent_containers/spray/waterflower = 1
+ )
+ backpack = /obj/item/weapon/storage/backpack/clown
+ satchel = /obj/item/weapon/storage/backpack/clown
+ dufflebag = /obj/item/weapon/storage/backpack/duffel/clown
+
+/datum/outfit/job/clown/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(H.gender == FEMALE)
+ mask = /obj/item/clothing/mask/gas/sexyclown
+ uniform = /obj/item/clothing/under/sexyclown
+
+/datum/outfit/job/clown/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ if(H.get_species() == "Machine")
+ var/obj/item/organ/internal/cyberimp/brain/clown_voice/implant = new
+ implant.insert(H)
+
+ H.mutations.Add(CLUMSY)
+ H.dna.SetSEState(COMICBLOCK, 1, 1)
+ genemutcheck(H, COMICBLOCK, null, MUTCHK_FORCED)
/datum/job/mime
@@ -254,35 +253,45 @@
is_service = 1
supervisors = "the head of personnel"
selection_color = "#dddddd"
- idtype = /obj/item/weapon/card/id/mime
access = list(access_mime, access_theatre, access_maint_tunnels)
minimal_access = list(access_mime, access_theatre, access_maint_tunnels)
+ outfit = /datum/outfit/job/mime
+/datum/outfit/job/mime
+ name = "Mime"
+ jobtype = /datum/job/mime
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- H.equip_or_collect(new /obj/item/weapon/storage/backpack/mime(H), slot_back)
- if(H.gender == FEMALE)
- H.equip_or_collect(new /obj/item/clothing/under/sexymime(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/mask/gas/sexymime(H), slot_wear_mask)
- else
- H.equip_or_collect(new /obj/item/clothing/under/mime(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/mask/gas/mime(H), slot_wear_mask)
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_service(H), slot_l_ear)
- H.equip_or_collect(new /obj/item/clothing/shoes/black(H), slot_shoes)
- H.equip_or_collect(new /obj/item/device/pda/mime(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/clothing/gloves/color/white(H), slot_gloves)
- H.equip_or_collect(new /obj/item/clothing/head/beret(H), slot_head)
- H.equip_or_collect(new /obj/item/clothing/suit/suspenders(H), slot_wear_suit)
- H.equip_or_collect(new /obj/item/toy/crayon/mime(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/cane(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- if(H.mind)
- H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall(null))
- H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/mime/speak(null))
- H.mind.miming = 1
- return 1
+ uniform = /obj/item/clothing/under/mime
+ suit = /obj/item/clothing/suit/suspenders
+ back = /obj/item/weapon/storage/backpack/mime
+ gloves = /obj/item/clothing/gloves/color/white
+ shoes = /obj/item/clothing/shoes/black
+ head = /obj/item/clothing/head/beret
+ mask = /obj/item/clothing/mask/gas/mime
+ l_ear = /obj/item/device/radio/headset/headset_service
+ id = /obj/item/weapon/card/id/mime
+ pda = /obj/item/device/pda/mime
+ backpack_contents = list(
+ /obj/item/toy/crayon/mime = 1,
+ /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing = 1,
+ /obj/item/weapon/cane = 1
+ )
+
+/datum/outfit/job/mime/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(H.gender == FEMALE)
+ uniform = /obj/item/clothing/under/sexymime
+ suit = /obj/item/clothing/mask/gas/sexymime
+
+/datum/outfit/job/mime/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ if(visualsOnly)
+ return
+
+ if(H.mind)
+ H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall(null))
+ H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/mime/speak(null))
+ H.mind.miming = 1
@@ -298,21 +307,16 @@
access = list(access_janitor, access_maint_tunnels)
minimal_access = list(access_janitor, access_maint_tunnels)
alt_titles = list("Custodial Technician")
+ outfit = /datum/outfit/job/janitor
+/datum/outfit/job/janitor
+ name = "Janitor"
+ jobtype = /datum/job/janitor
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_service(H), slot_l_ear)
- H.equip_or_collect(new /obj/item/clothing/under/rank/janitor(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/shoes/black(H), slot_shoes)
- H.equip_or_collect(new /obj/item/device/pda/janitor(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- return 1
-
+ uniform = /obj/item/clothing/under/rank/janitor
+ shoes = /obj/item/clothing/shoes/black
+ l_ear = /obj/item/device/radio/headset/headset_service
+ pda = /obj/item/device/pda/janitor
//More or less assistants
@@ -328,24 +332,19 @@
access = list(access_library, access_maint_tunnels)
minimal_access = list(access_library, access_maint_tunnels)
alt_titles = list("Journalist")
+ outfit = /datum/outfit/job/librarian
+/datum/outfit/job/librarian
+ name = "Librarian"
+ jobtype = /datum/job/librarian
- equip(var/mob/living/carbon/human/H)
- if(!H)
- return 0
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_service(H), slot_l_ear)
- H.equip_or_collect(new /obj/item/clothing/under/suit_jacket/red(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/device/pda/librarian(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/clothing/shoes/black(H), slot_shoes)
- H.equip_or_collect(new /obj/item/weapon/storage/bag/books(H), slot_l_hand)
- H.equip_or_collect(new /obj/item/weapon/barcodescanner(H), slot_r_store)
- H.equip_or_collect(new /obj/item/device/laser_pointer(H), slot_l_store)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- return 1
+ uniform = /obj/item/clothing/under/suit_jacket/red
+ shoes = /obj/item/clothing/shoes/black
+ l_ear = /obj/item/device/radio/headset/headset_service
+ l_pocket = /obj/item/device/laser_pointer
+ r_pocket = /obj/item/weapon/barcodescanner
+ l_hand = /obj/item/weapon/storage/bag/books
+ pda = /obj/item/device/pda/librarian
/datum/job/barber
title = "Barber"
@@ -359,18 +358,17 @@
alt_titles = list("Hair Stylist","Beautician")
access = list(access_maint_tunnels)
minimal_access = list(access_maint_tunnels)
+ outfit = /datum/outfit/job/barber
+/datum/outfit/job/barber
+ name = "Barber"
+ jobtype = /datum/job/barber
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_service(H), slot_l_ear)
- H.equip_or_collect(new /obj/item/clothing/under/barber(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/clothing/shoes/black(H), slot_shoes)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/storage/box/barber(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/weapon/storage/box/lip_stick(H), slot_in_backpack)
- return 1
+ uniform = /obj/item/clothing/under/barber
+ shoes = /obj/item/clothing/shoes/black
+ l_ear = /obj/item/device/radio/headset/headset_service
+ backpack_contents = list(
+ /obj/item/clothing/shoes/black = 1,
+ /obj/item/weapon/storage/box/lip_stick = 1,
+ /obj/item/weapon/storage/box/barber = 1
+ )
diff --git a/code/game/jobs/job/support_chaplain.dm b/code/game/jobs/job/support_chaplain.dm
index da9bd5c8ec1..8ff51148b9f 100644
--- a/code/game/jobs/job/support_chaplain.dm
+++ b/code/game/jobs/job/support_chaplain.dm
@@ -11,149 +11,156 @@
access = list(access_morgue, access_chapel_office, access_crematorium, access_maint_tunnels)
minimal_access = list(access_morgue, access_chapel_office, access_crematorium, access_maint_tunnels)
+ outfit = /datum/outfit/job/chaplain
- equip(var/mob/living/carbon/human/H)
- if(!H) return 0
- var/obj/item/weapon/storage/bible/B = new /obj/item/weapon/storage/bible(H) //BS12 EDIT
- H.equip_or_collect(B, slot_l_hand)
- switch(H.backbag)
- if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack(H), slot_back)
- if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
- if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_or_collect(new /obj/item/device/radio/headset/headset_service(H), slot_l_ear)
- H.equip_or_collect(new /obj/item/clothing/under/rank/chaplain(H), slot_w_uniform)
- H.equip_or_collect(new /obj/item/device/pda/chaplain(H), slot_wear_pda)
- H.equip_or_collect(new /obj/item/clothing/shoes/black(H), slot_shoes)
- H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
- H.equip_or_collect(new /obj/item/device/camera/spooky(H), slot_in_backpack)
- spawn(0)
- var/religion_name = "Christianity"
- var/new_religion = sanitize(copytext(input(H, "You are the crew services officer. Would you like to change your religion? Default is Christianity, in SPACE.", "Name change", religion_name),1,MAX_NAME_LEN))
+/datum/outfit/job/chaplain
+ name = "Chaplain"
+ jobtype = /datum/job/chaplain
- if(!new_religion)
- new_religion = religion_name
+ uniform = /obj/item/clothing/under/rank/chaplain
+ shoes = /obj/item/clothing/shoes/black
+ l_ear = /obj/item/device/radio/headset/headset_service
+ pda = /obj/item/device/pda/chaplain
+ backpack_contents = list(
+ /obj/item/device/camera/spooky = 1
+ )
- switch(lowertext(new_religion))
- if("christianity")
- B.name = pick("The Holy Bible")
- if("satanism")
- B.name = "The Unholy Bible"
- if("cthulu")
- B.name = "The Necronomicon"
- if("islam")
- B.name = "Quran"
- if("scientology")
- B.name = pick("The Biography of L. Ron Hubbard","Dianetics")
- if("chaos")
- B.name = "The Book of Lorgar"
- if("imperium")
- B.name = "Uplifting Primer"
- if("toolboxia")
- B.name = "Toolbox Manifesto Robusto"
- if("homosexuality")
- B.name = "Guys Gone Wild"
- if("lol", "wtf", "gay", "penis", "ass", "poo", "badmin", "shitmin", "deadmin", "cock", "cocks")
- B.name = pick("Woodys Got Wood: The Aftermath", "War of the Cocks", "Sweet Bro and Hella Jef: Expanded Edition")
- H.setBrainLoss(99) // starts off retarded as fuck
- if("science")
- B.name = pick("Principle of Relativity", "Quantum Enigma: Physics Encounters Consciousness", "Programming the Universe", "Quantum Physics and Theology", "String Theory for Dummies", "How To: Build Your Own Warp Drive", "The Mysteries of Bluespace", "Playing God: Collector's Edition")
+/datum/outfit/job/chaplain/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+
+ if(visualsOnly)
+ return
+
+ var/obj/item/weapon/storage/bible/B = new /obj/item/weapon/storage/bible(H)
+
+ spawn()
+ H.equip_to_slot_or_del(B, slot_l_hand)
+
+ var/religion_name = "Christianity"
+ var/new_religion = sanitize(copytext(input(H, "You are the crew services officer. Would you like to change your religion? Default is Christianity, in SPACE.", "Name change", religion_name),1,MAX_NAME_LEN))
+
+ if(!new_religion)
+ new_religion = religion_name
+
+ switch(lowertext(new_religion))
+ if("christianity")
+ B.name = pick("The Holy Bible")
+ if("satanism")
+ B.name = "The Unholy Bible"
+ if("cthulu")
+ B.name = "The Necronomicon"
+ if("islam")
+ B.name = "Quran"
+ if("scientology")
+ B.name = pick("The Biography of L. Ron Hubbard","Dianetics")
+ if("chaos")
+ B.name = "The Book of Lorgar"
+ if("imperium")
+ B.name = "Uplifting Primer"
+ if("toolboxia")
+ B.name = "Toolbox Manifesto Robusto"
+ if("homosexuality")
+ B.name = "Guys Gone Wild"
+ if("lol", "wtf", "gay", "penis", "ass", "poo", "badmin", "shitmin", "deadmin", "cock", "cocks")
+ B.name = pick("Woodys Got Wood: The Aftermath", "War of the Cocks", "Sweet Bro and Hella Jef: Expanded Edition")
+ H.setBrainLoss(99) // starts off retarded as fuck
+ if("science")
+ B.name = pick("Principle of Relativity", "Quantum Enigma: Physics Encounters Consciousness", "Programming the Universe", "Quantum Physics and Theology", "String Theory for Dummies", "How To: Build Your Own Warp Drive", "The Mysteries of Bluespace", "Playing God: Collector's Edition")
+ else
+ B.name = "The Holy Book of [new_religion]"
+ feedback_set_details("religion_name","[new_religion]")
+
+ var/deity_name = "Space Jesus"
+ var/new_deity = sanitize(copytext(input(H, "Would you like to change your deity? Default is Space Jesus.", "Name change", deity_name),1,MAX_NAME_LEN))
+
+ if((length(new_deity) == 0) || (new_deity == "Space Jesus") )
+ new_deity = deity_name
+ B.deity_name = new_deity
+
+ var/accepted = 0
+ var/outoftime = 0
+ spawn(200) // 20 seconds to choose
+ outoftime = 1
+ var/new_book_style = "Bible"
+
+ while(!accepted)
+ if(!B) break // prevents possible runtime errors
+ new_book_style = input(H,"Which bible style would you like?") in list("Bible", "Koran", "Scrapbook", "Creeper", "White Bible", "Holy Light", "Athiest", "Tome", "The King in Yellow", "Ithaqua", "Scientology", "the bible melts", "Necronomicon", "Greentext")
+ switch(new_book_style)
+ if("Koran")
+ B.icon_state = "koran"
+ B.item_state = "koran"
+ for(var/area/chapel/main/A in world)
+ for(var/turf/T in A.contents)
+ if(T.icon_state == "carpetsymbol")
+ T.dir = 4
+ if("Scrapbook")
+ B.icon_state = "scrapbook"
+ B.item_state = "scrapbook"
+ if("Creeper")
+ B.icon_state = "creeper"
+ B.item_state = "syringe_kit"
+ if("White Bible")
+ B.icon_state = "white"
+ B.item_state = "syringe_kit"
+ if("Holy Light")
+ B.icon_state = "holylight"
+ B.item_state = "syringe_kit"
+ if("Athiest")
+ B.icon_state = "athiest"
+ B.item_state = "syringe_kit"
+ for(var/area/chapel/main/A in world)
+ for(var/turf/T in A.contents)
+ if(T.icon_state == "carpetsymbol")
+ T.dir = 10
+ if("Tome")
+ B.icon_state = "tome"
+ B.item_state = "syringe_kit"
+ if("The King in Yellow")
+ B.icon_state = "kingyellow"
+ B.item_state = "kingyellow"
+ if("Ithaqua")
+ B.icon_state = "ithaqua"
+ B.item_state = "ithaqua"
+ if("Scientology")
+ B.icon_state = "scientology"
+ B.item_state = "scientology"
+ for(var/area/chapel/main/A in world)
+ for(var/turf/T in A.contents)
+ if(T.icon_state == "carpetsymbol")
+ T.dir = 8
+ if("the bible melts")
+ B.icon_state = "melted"
+ B.item_state = "melted"
+ if("Necronomicon")
+ B.icon_state = "necronomicon"
+ B.item_state = "necronomicon"
+ if("Greentext")
+ B.icon_state = "greentext"
+ B.item_state = "greentext"
else
- B.name = "The Holy Book of [new_religion]"
- feedback_set_details("religion_name","[new_religion]")
+ // if christian bible, revert to default
+ B.icon_state = "bible"
+ B.item_state = "bible"
+ for(var/area/chapel/main/A in world)
+ for(var/turf/T in A.contents)
+ if(T.icon_state == "carpetsymbol")
+ T.dir = 2
- spawn(1)
- var/deity_name = "Space Jesus"
- var/new_deity = sanitize(copytext(input(H, "Would you like to change your deity? Default is Space Jesus.", "Name change", deity_name),1,MAX_NAME_LEN))
+ H.update_inv_l_hand() // so that it updates the bible's item_state in his hand
- if((length(new_deity) == 0) || (new_deity == "Space Jesus") )
- new_deity = deity_name
- B.deity_name = new_deity
-
- var/accepted = 0
- var/outoftime = 0
- spawn(200) // 20 seconds to choose
- outoftime = 1
- var/new_book_style = "Bible"
-
- while(!accepted)
- if(!B) break // prevents possible runtime errors
- new_book_style = input(H,"Which bible style would you like?") in list("Bible", "Koran", "Scrapbook", "Creeper", "White Bible", "Holy Light", "Athiest", "Tome", "The King in Yellow", "Ithaqua", "Scientology", "the bible melts", "Necronomicon", "Greentext")
- switch(new_book_style)
- if("Koran")
- B.icon_state = "koran"
- B.item_state = "koran"
- for(var/area/chapel/main/A in world)
- for(var/turf/T in A.contents)
- if(T.icon_state == "carpetsymbol")
- T.dir = 4
- if("Scrapbook")
- B.icon_state = "scrapbook"
- B.item_state = "scrapbook"
- if("Creeper")
- B.icon_state = "creeper"
- B.item_state = "syringe_kit"
- if("White Bible")
- B.icon_state = "white"
- B.item_state = "syringe_kit"
- if("Holy Light")
- B.icon_state = "holylight"
- B.item_state = "syringe_kit"
- if("Athiest")
- B.icon_state = "athiest"
- B.item_state = "syringe_kit"
- for(var/area/chapel/main/A in world)
- for(var/turf/T in A.contents)
- if(T.icon_state == "carpetsymbol")
- T.dir = 10
- if("Tome")
- B.icon_state = "tome"
- B.item_state = "syringe_kit"
- if("The King in Yellow")
- B.icon_state = "kingyellow"
- B.item_state = "kingyellow"
- if("Ithaqua")
- B.icon_state = "ithaqua"
- B.item_state = "ithaqua"
- if("Scientology")
- B.icon_state = "scientology"
- B.item_state = "scientology"
- for(var/area/chapel/main/A in world)
- for(var/turf/T in A.contents)
- if(T.icon_state == "carpetsymbol")
- T.dir = 8
- if("the bible melts")
- B.icon_state = "melted"
- B.item_state = "melted"
- if("Necronomicon")
- B.icon_state = "necronomicon"
- B.item_state = "necronomicon"
- if("Greentext")
- B.icon_state = "greentext"
- B.item_state = "greentext"
- else
- // if christian bible, revert to default
- B.icon_state = "bible"
- B.item_state = "bible"
- for(var/area/chapel/main/A in world)
- for(var/turf/T in A.contents)
- if(T.icon_state == "carpetsymbol")
- T.dir = 2
-
- H.update_inv_l_hand() // so that it updates the bible's item_state in his hand
-
- switch(input(H,"Look at your bible - is this what you want?") in list("Yes","No"))
- if("Yes")
+ switch(input(H,"Look at your bible - is this what you want?") in list("Yes","No"))
+ if("Yes")
+ accepted = 1
+ if("No")
+ if(outoftime)
+ to_chat(H, "Welp, out of time, buddy. You're stuck. Next time choose faster.")
accepted = 1
- if("No")
- if(outoftime)
- to_chat(H, "Welp, out of time, buddy. You're stuck. Next time choose faster.")
- accepted = 1
- if(ticker)
- ticker.Bible_icon_state = B.icon_state
- ticker.Bible_item_state = B.item_state
- ticker.Bible_name = B.name
- ticker.Bible_deity_name = B.deity_name
- feedback_set_details("religion_deity","[new_deity]")
- feedback_set_details("religion_book","[new_book_style]")
- return 1
+ if(ticker)
+ ticker.Bible_icon_state = B.icon_state
+ ticker.Bible_item_state = B.item_state
+ ticker.Bible_name = B.name
+ ticker.Bible_deity_name = B.deity_name
+ feedback_set_details("religion_deity","[new_deity]")
+ feedback_set_details("religion_book","[new_book_style]")
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index a770084dbbc..433b2adfb27 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -1,3 +1,4 @@
+
var/global/datum/controller/occupations/job_master
#define GET_RANDOM_JOB 0
@@ -5,571 +6,482 @@ var/global/datum/controller/occupations/job_master
#define RETURN_TO_LOBBY 2
/datum/controller/occupations
- //List of all jobs
+ //List of all jobs
var/list/occupations = list()
- //Players who need jobs
+ var/list/name_occupations = list() //Dict of all jobs, keys are titles
+ var/list/type_occupations = list() //Dict of all jobs, keys are types
+ //Players who need jobs
var/list/unassigned = list()
- //Debug info
+ //Debug info
var/list/job_debug = list()
+/datum/controller/occupations/proc/SetupOccupations(var/list/faction = list("Station"))
+ occupations = list()
- proc/SetupOccupations(var/list/faction = list("Station"))
- occupations = list()
- var/list/all_jobs = subtypesof(/datum/job)
- if(!all_jobs.len)
- to_chat(world, "\red \b Error setting up jobs, no job datums found")
- return 0
- for(var/J in all_jobs)
- var/datum/job/job = new J()
- if(!job) continue
- if(!job.faction in faction) continue
- occupations += job
-
- return 1
-
-
- proc/Debug(var/text)
- if(!Debug2) return 0
- job_debug.Add(text)
- return 1
-
-
- proc/GetJob(var/rank)
- if(!rank) return null
- for(var/datum/job/J in occupations)
- if(!J) continue
- if(J.title == rank) return J
- return null
-
- proc/GetPlayerAltTitle(mob/new_player/player, rank)
- return player.client.prefs.GetPlayerAltTitle(GetJob(rank))
-
- proc/AssignRole(var/mob/new_player/player, var/rank, var/latejoin = 0)
- Debug("Running AR, Player: [player], Rank: [rank], LJ: [latejoin]")
- if(player && player.mind && rank)
- var/datum/job/job = GetJob(rank)
- if(!job) return 0
- if(jobban_isbanned(player, rank)) return 0
- if(!job.player_old_enough(player.client)) return 0
- if(job.available_in_playtime(player.client))
- return 0
- if(!is_job_whitelisted(player, rank)) return 0
- var/position_limit = job.total_positions
- if(!latejoin)
- position_limit = job.spawn_positions
- if((job.current_positions < position_limit) || position_limit == -1)
- Debug("Player: [player] is now Rank: [rank], JCP:[job.current_positions], JPL:[position_limit]")
- player.mind.assigned_role = rank
- player.mind.role_alt_title = GetPlayerAltTitle(player, rank)
-
- // JOB OBJECTIVES OH SHIT
- player.mind.job_objectives.Cut()
- for(var/objectiveType in job.required_objectives)
- new objectiveType(player.mind)
-
- // 50/50 chance of getting optional objectives.
- for(var/objectiveType in job.optional_objectives)
- if(prob(50))
- new objectiveType(player.mind)
-
- unassigned -= player
- job.current_positions++
- return 1
- Debug("AR has failed, Player: [player], Rank: [rank]")
+ var/list/all_jobs = subtypesof(/datum/job)
+ if(!all_jobs.len)
+ to_chat(world, "Error setting up jobs, no job datums found")
return 0
- proc/FreeRole(var/rank) //making additional slot on the fly
- var/datum/job/job = GetJob(rank)
- if(job && job.current_positions >= job.total_positions && job.total_positions != -1)
- job.total_positions++
- return 1
+ for(var/J in all_jobs)
+ var/datum/job/job = new J()
+ if(!job)
+ continue
+ if(!job.faction in faction)
+ continue
+ occupations += job
+ name_occupations[job.title] = job
+ type_occupations[J] = job
+
+ return 1
+
+
+/datum/controller/occupations/proc/Debug(var/text)
+ if(!Debug2)
return 0
+ job_debug.Add(text)
+ return 1
- proc/FindOccupationCandidates(datum/job/job, level, flag)
- Debug("Running FOC, Job: [job], Level: [level], Flag: [flag]")
- var/list/candidates = list()
- for(var/mob/new_player/player in unassigned)
- Debug(" - Player: [player] Banned: [jobban_isbanned(player, job.title)] Old Enough: [!job.player_old_enough(player.client)] AvInPlaytime: [job.available_in_playtime(player.client)] Flag && Be Special: [flag] && [player.client.prefs.be_special] Job Department: [player.client.prefs.GetJobDepartment(job, level)] Job Flag: [job.flag] Job Department Flag = [job.department_flag]")
- if(jobban_isbanned(player, job.title))
- Debug("FOC isbanned failed, Player: [player]")
- continue
- if(!job.player_old_enough(player.client))
- Debug("FOC player not old enough, Player: [player]")
- continue
- if(job.available_in_playtime(player.client))
- Debug("FOC player not enough playtime, Player: [player]")
- continue
- if(flag && !(flag in player.client.prefs.be_special))
- Debug("FOC flag failed, Player: [player], Flag: [flag], ")
- continue
- if(player.mind && job.title in player.mind.restricted_roles)
- Debug("FOC incompatbile with antagonist role, Player: [player]")
- continue
- if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
- Debug("FOC pass, Player: [player], Level:[level]")
- candidates += player
- return candidates
- proc/GiveRandomJob(var/mob/new_player/player)
- Debug("GRJ Giving random job, Player: [player]")
- for(var/datum/job/job in shuffle(occupations))
- if(!job)
- continue
-
- if(istype(job, GetJob("Civilian"))) // We don't want to give him assistant, that's boring!
- continue
-
- if(job.title in command_positions) //If you want a command position, select it!
- continue
-
- if(job.title in whitelisted_positions) // No random whitelisted job, sorry!
- continue
-
- if(job.admin_only) // No admin positions either.
- continue
-
- if(jobban_isbanned(player, job.title))
- Debug("GRJ isbanned failed, Player: [player], Job: [job.title]")
- continue
-
- if(!job.player_old_enough(player.client))
- Debug("GRJ player not old enough, Player: [player]")
- continue
-
- if(job.available_in_playtime(player.client))
- Debug("GRJ player not enough playtime, Player: [player]")
- continue
-
- if(player.mind && job.title in player.mind.restricted_roles)
- Debug("GRJ incompatible with antagonist role, Player: [player], Job: [job.title]")
- continue
-
- if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1)
- Debug("GRJ Random job given, Player: [player], Job: [job]")
- AssignRole(player, job.title)
- unassigned -= player
- break
-
- proc/ResetOccupations()
- for(var/mob/new_player/player in player_list)
- if((player) && (player.mind))
- player.mind.assigned_role = null
- player.mind.special_role = null
+/datum/controller/occupations/proc/GetJob(rank)
+ if(!occupations.len)
SetupOccupations()
- unassigned = list()
- return
+ return name_occupations[rank]
+/datum/controller/occupations/proc/GetJobType(jobtype)
+ if(!occupations.len)
+ SetupOccupations()
+ return type_occupations[jobtype]
- ///This proc is called before the level loop of DivideOccupations() and will try to select a head, ignoring ALL non-head preferences for every level until it locates a head or runs out of levels to check
- proc/FillHeadPosition()
- for(var/level = 1 to 3)
- for(var/command_position in command_positions)
- var/datum/job/job = GetJob(command_position)
- if(!job) continue
- var/list/candidates = FindOccupationCandidates(job, level)
- if(!candidates.len) continue
+/datum/controller/occupations/proc/GetPlayerAltTitle(mob/new_player/player, rank)
+ return player.client.prefs.GetPlayerAltTitle(GetJob(rank))
- // Build a weighted list, weight by age.
- var/list/weightedCandidates = list()
-
- // Different head positions have different good ages.
- var/good_age_minimal = 25
- var/good_age_maximal = 60
- if(command_position == "Captain")
- good_age_minimal = 30
- good_age_maximal = 70 // Old geezer captains ftw
-
- for(var/mob/V in candidates)
- // Log-out during round-start? What a bad boy, no head position for you!
- if(!V.client) continue
- var/age = V.client.prefs.age
- switch(age)
- if(good_age_minimal - 10 to good_age_minimal)
- weightedCandidates[V] = 3 // Still a bit young.
- if(good_age_minimal to good_age_minimal + 10)
- weightedCandidates[V] = 6 // Better.
- if(good_age_minimal + 10 to good_age_maximal - 10)
- weightedCandidates[V] = 10 // Great.
- if(good_age_maximal - 10 to good_age_maximal)
- weightedCandidates[V] = 6 // Still good.
- if(good_age_maximal to good_age_maximal + 10)
- weightedCandidates[V] = 6 // Bit old, don't you think?
- if(good_age_maximal to good_age_maximal + 50)
- weightedCandidates[V] = 3 // Geezer.
- else
- // If there's ABSOLUTELY NOBODY ELSE
- if(candidates.len == 1) weightedCandidates[V] = 1
-
-
- var/mob/new_player/candidate = pickweight(weightedCandidates)
- if(AssignRole(candidate, command_position))
- return 1
- return 0
-
-
- ///This proc is called at the start of the level loop of DivideOccupations() and will cause head jobs to be checked before any other jobs of the same level
- proc/CheckHeadPositions(var/level)
- for(var/command_position in command_positions)
- var/datum/job/job = GetJob(command_position)
- if(!job) continue
- var/list/candidates = FindOccupationCandidates(job, level)
- if(!candidates.len) continue
- var/mob/new_player/candidate = pick(candidates)
- AssignRole(candidate, command_position)
- return
-
-
- proc/FillAIPosition()
- var/ai_selected = 0
- var/datum/job/job = GetJob("AI")
+/datum/controller/occupations/proc/AssignRole(var/mob/new_player/player, var/rank, var/latejoin = 0)
+ Debug("Running AR, Player: [player], Rank: [rank], LJ: [latejoin]")
+ if(player && player.mind && rank)
+ var/datum/job/job = GetJob(rank)
if(!job)
return 0
- if((job.title == "AI") && (config) && (!config.allow_ai))
+ if(jobban_isbanned(player, rank))
return 0
- for(var/i = job.total_positions, i > 0, i--)
- for(var/level = 1 to 3)
- var/list/candidates = list()
- candidates = FindOccupationCandidates(job, level)
- if(candidates.len)
- var/mob/new_player/candidate = pick(candidates)
- if(AssignRole(candidate, "AI"))
- ai_selected++
- break
- if(ai_selected) return 1
+ if(!job.player_old_enough(player.client))
return 0
+ if(job.available_in_playtime(player.client))
+ return 0
+ if(!is_job_whitelisted(player, rank))
+ return 0
+
+ var/position_limit = job.total_positions
+ if(!latejoin)
+ position_limit = job.spawn_positions
+
+ if((job.current_positions < position_limit) || position_limit == -1)
+ Debug("Player: [player] is now Rank: [rank], JCP:[job.current_positions], JPL:[position_limit]")
+ player.mind.assigned_role = rank
+ player.mind.role_alt_title = GetPlayerAltTitle(player, rank)
+
+ // JOB OBJECTIVES OH SHIT
+ player.mind.job_objectives.Cut()
+ for(var/objectiveType in job.required_objectives)
+ new objectiveType(player.mind)
+
+ // 50/50 chance of getting optional objectives.
+ for(var/objectiveType in job.optional_objectives)
+ if(prob(50))
+ new objectiveType(player.mind)
+
+ unassigned -= player
+ job.current_positions++
+ return 1
+
+ Debug("AR has failed, Player: [player], Rank: [rank]")
+ return 0
+
+/datum/controller/occupations/proc/FreeRole(var/rank) //making additional slot on the fly
+ var/datum/job/job = GetJob(rank)
+ if(job && job.current_positions >= job.total_positions && job.total_positions != -1)
+ job.total_positions++
+ return 1
+ return 0
+
+/datum/controller/occupations/proc/FindOccupationCandidates(datum/job/job, level, flag)
+ Debug("Running FOC, Job: [job], Level: [level], Flag: [flag]")
+ var/list/candidates = list()
+ for(var/mob/new_player/player in unassigned)
+ Debug(" - Player: [player] Banned: [jobban_isbanned(player, job.title)] Old Enough: [!job.player_old_enough(player.client)] AvInPlaytime: [job.available_in_playtime(player.client)] Flag && Be Special: [flag] && [player.client.prefs.be_special] Job Department: [player.client.prefs.GetJobDepartment(job, level)] Job Flag: [job.flag] Job Department Flag = [job.department_flag]")
+ if(jobban_isbanned(player, job.title))
+ Debug("FOC isbanned failed, Player: [player]")
+ continue
+ if(!job.player_old_enough(player.client))
+ Debug("FOC player not old enough, Player: [player]")
+ continue
+ if(job.available_in_playtime(player.client))
+ Debug("FOC player not enough playtime, Player: [player]")
+ continue
+ if(flag && !(flag in player.client.prefs.be_special))
+ Debug("FOC flag failed, Player: [player], Flag: [flag], ")
+ continue
+ if(player.mind && job.title in player.mind.restricted_roles)
+ Debug("FOC incompatbile with antagonist role, Player: [player]")
+ continue
+ if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
+ Debug("FOC pass, Player: [player], Level:[level]")
+ candidates += player
+ return candidates
+
+/datum/controller/occupations/proc/GiveRandomJob(var/mob/new_player/player)
+ Debug("GRJ Giving random job, Player: [player]")
+ for(var/datum/job/job in shuffle(occupations))
+ if(!job)
+ continue
+
+ if(istype(job, GetJob("Civilian"))) // We don't want to give him assistant, that's boring!
+ continue
+
+ if(job.title in command_positions) //If you want a command position, select it!
+ continue
+
+ if(job.title in whitelisted_positions) // No random whitelisted job, sorry!
+ continue
+
+ if(job.admin_only) // No admin positions either.
+ continue
+
+ if(jobban_isbanned(player, job.title))
+ Debug("GRJ isbanned failed, Player: [player], Job: [job.title]")
+ continue
+
+ if(!job.player_old_enough(player.client))
+ Debug("GRJ player not old enough, Player: [player]")
+ continue
+
+ if(job.available_in_playtime(player.client))
+ Debug("GRJ player not enough playtime, Player: [player]")
+ continue
+
+ if(player.mind && job.title in player.mind.restricted_roles)
+ Debug("GRJ incompatible with antagonist role, Player: [player], Job: [job.title]")
+ continue
+
+ if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1)
+ Debug("GRJ Random job given, Player: [player], Job: [job]")
+ AssignRole(player, job.title)
+ unassigned -= player
+ break
+
+/datum/controller/occupations/proc/ResetOccupations()
+ for(var/mob/new_player/player in player_list)
+ if((player) && (player.mind))
+ player.mind.assigned_role = null
+ player.mind.special_role = null
+ SetupOccupations()
+ unassigned = list()
+ return
+
+
+///This proc is called before the level loop of DivideOccupations() and will try to select a head, ignoring ALL non-head preferences for every level until it locates a head or runs out of levels to check
+/datum/controller/occupations/proc/FillHeadPosition()
+ for(var/level = 1 to 3)
+ for(var/command_position in command_positions)
+ var/datum/job/job = GetJob(command_position)
+ if(!job)
+ continue
+ var/list/candidates = FindOccupationCandidates(job, level)
+ if(!candidates.len)
+ continue
+
+ // Build a weighted list, weight by age.
+ var/list/weightedCandidates = list()
+
+ // Different head positions have different good ages.
+ var/good_age_minimal = 25
+ var/good_age_maximal = 60
+ if(command_position == "Captain")
+ good_age_minimal = 30
+ good_age_maximal = 70 // Old geezer captains ftw
+
+ for(var/mob/V in candidates)
+ // Log-out during round-start? What a bad boy, no head position for you!
+ if(!V.client)
+ continue
+ var/age = V.client.prefs.age
+ switch(age)
+ if(good_age_minimal - 10 to good_age_minimal)
+ weightedCandidates[V] = 3 // Still a bit young.
+ if(good_age_minimal to good_age_minimal + 10)
+ weightedCandidates[V] = 6 // Better.
+ if(good_age_minimal + 10 to good_age_maximal - 10)
+ weightedCandidates[V] = 10 // Great.
+ if(good_age_maximal - 10 to good_age_maximal)
+ weightedCandidates[V] = 6 // Still good.
+ if(good_age_maximal to good_age_maximal + 10)
+ weightedCandidates[V] = 6 // Bit old, don't you think?
+ if(good_age_maximal to good_age_maximal + 50)
+ weightedCandidates[V] = 3 // Geezer.
+ else
+ // If there's ABSOLUTELY NOBODY ELSE
+ if(candidates.len == 1)
+ weightedCandidates[V] = 1
+
+ var/mob/new_player/candidate = pickweight(weightedCandidates)
+ if(AssignRole(candidate, command_position))
+ return 1
+
+ return 0
+
+
+///This proc is called at the start of the level loop of DivideOccupations() and will cause head jobs to be checked before any other jobs of the same level
+/datum/controller/occupations/proc/CheckHeadPositions(var/level)
+ for(var/command_position in command_positions)
+ var/datum/job/job = GetJob(command_position)
+ if(!job)
+ continue
+ var/list/candidates = FindOccupationCandidates(job, level)
+ if(!candidates.len)
+ continue
+ var/mob/new_player/candidate = pick(candidates)
+ AssignRole(candidate, command_position)
+
+
+/datum/controller/occupations/proc/FillAIPosition()
+ if(config && !config.allow_ai)
+ return 0
+
+ var/ai_selected = 0
+ var/datum/job/job = GetJob("AI")
+ if(!job)
+ return 0
+
+ for(var/i = job.total_positions, i > 0, i--)
+ for(var/level = 1 to 3)
+ var/list/candidates = list()
+ candidates = FindOccupationCandidates(job, level)
+ if(candidates.len)
+ var/mob/new_player/candidate = pick(candidates)
+ if(AssignRole(candidate, "AI"))
+ ai_selected++
+ break
+
+ if(ai_selected)
+ return 1
+
+ return 0
/** Proc DivideOccupations
- * fills var "assigned_role" for all ready players.
- * This proc must not have any side effect besides of modifying "assigned_role".
- **/
- proc/DivideOccupations()
- //Setup new player list and get the jobs list
- Debug("Running DO")
- SetupOccupations()
+* fills var "assigned_role" for all ready players.
+* This proc must not have any side effect besides of modifying "assigned_role".
+**/
+/datum/controller/occupations/proc/DivideOccupations()
+ //Setup new player list and get the jobs list
+ Debug("Running DO")
+ SetupOccupations()
- //Holder for Triumvirate is stored in the ticker, this just processes it
- if(ticker)
- for(var/datum/job/ai/A in occupations)
- if(ticker.triai)
- A.spawn_positions = 3
+ //Holder for Triumvirate is stored in the ticker, this just processes it
+ if(ticker)
+ for(var/datum/job/ai/A in occupations)
+ if(ticker.triai)
+ A.spawn_positions = 3
- //Get the players who are ready
- for(var/mob/new_player/player in player_list)
- if(player.ready && player.mind && !player.mind.assigned_role)
- unassigned += player
- if(player.client.prefs.randomslot)
- player.client.prefs.load_random_character_slot(player.client)
- Debug("DO, Len: [unassigned.len]")
- if(unassigned.len == 0) return 0
+ //Get the players who are ready
+ for(var/mob/new_player/player in player_list)
+ if(player.ready && player.mind && !player.mind.assigned_role)
+ unassigned += player
+ if(player.client.prefs.randomslot)
+ player.client.prefs.load_random_character_slot(player.client)
- //Shuffle players and jobs
- unassigned = shuffle(unassigned)
+ Debug("DO, Len: [unassigned.len]")
+ if(unassigned.len == 0)
+ return 0
- HandleFeedbackGathering()
+ //Shuffle players and jobs
+ unassigned = shuffle(unassigned)
- //People who wants to be assistants, sure, go on.
- Debug("DO, Running Civilian Check 1")
- var/datum/job/civ = new /datum/job/civilian()
- var/list/civilian_candidates = FindOccupationCandidates(civ, 3)
- Debug("AC1, Candidates: [civilian_candidates.len]")
- for(var/mob/new_player/player in civilian_candidates)
- Debug("AC1 pass, Player: [player]")
- AssignRole(player, "Civilian")
- civilian_candidates -= player
- Debug("DO, AC1 end")
+ HandleFeedbackGathering()
- //Select one head
- Debug("DO, Running Head Check")
- FillHeadPosition()
- Debug("DO, Head Check end")
+ //People who wants to be assistants, sure, go on.
+ Debug("DO, Running Civilian Check 1")
+ var/datum/job/civ = new /datum/job/civilian()
+ var/list/civilian_candidates = FindOccupationCandidates(civ, 3)
+ Debug("AC1, Candidates: [civilian_candidates.len]")
+ for(var/mob/new_player/player in civilian_candidates)
+ Debug("AC1 pass, Player: [player]")
+ AssignRole(player, "Civilian")
+ civilian_candidates -= player
+ Debug("DO, AC1 end")
- //Check for an AI
- Debug("DO, Running AI Check")
- FillAIPosition()
- Debug("DO, AI Check end")
+ //Select one head
+ Debug("DO, Running Head Check")
+ FillHeadPosition()
+ Debug("DO, Head Check end")
- //Other jobs are now checked
- Debug("DO, Running Standard Check")
+ //Check for an AI
+ Debug("DO, Running AI Check")
+ FillAIPosition()
+ Debug("DO, AI Check end")
+
+ //Other jobs are now checked
+ Debug("DO, Running Standard Check")
- // New job giving system by Donkie
- // This will cause lots of more loops, but since it's only done once it shouldn't really matter much at all.
- // Hopefully this will add more randomness and fairness to job giving.
+ // New job giving system by Donkie
+ // This will cause lots of more loops, but since it's only done once it shouldn't really matter much at all.
+ // Hopefully this will add more randomness and fairness to job giving.
- // Loop through all levels from high to low
- var/list/shuffledoccupations = shuffle(occupations)
- for(var/level = 1 to 3)
- //Check the head jobs first each level
- CheckHeadPositions(level)
+ // Loop through all levels from high to low
+ var/list/shuffledoccupations = shuffle(occupations)
+ for(var/level = 1 to 3)
+ //Check the head jobs first each level
+ CheckHeadPositions(level)
- // Loop through all unassigned players
- for(var/mob/new_player/player in unassigned)
-
- // Loop through all jobs
- for(var/datum/job/job in shuffledoccupations) // SHUFFLE ME BABY
- if(!job)
- continue
-
- if(jobban_isbanned(player, job.title))
- Debug("DO isbanned failed, Player: [player], Job:[job.title]")
- continue
-
- if(!job.player_old_enough(player.client))
- Debug("DO player not old enough, Player: [player], Job:[job.title]")
- continue
-
- if(job.available_in_playtime(player.client))
- Debug("DO player not enough playtime, Player: [player], Job:[job.title]")
- continue
-
- if(player.mind && job.title in player.mind.restricted_roles)
- Debug("DO incompatible with antagonist role, Player: [player], Job:[job.title]")
- continue
-
- if(!is_job_whitelisted(player, job.title))
- Debug("DO player not whitelisted, Player: [player], Job:[job.title]")
- continue
-
- // If the player wants that job on this level, then try give it to him.
- if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
-
- // If the job isn't filled
- if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1)
- Debug("DO pass, Player: [player], Level:[level], Job:[job.title]")
- Debug(" - Job Flag: [job.flag] Job Department: [player.client.prefs.GetJobDepartment(job, level)] Job Current Pos: [job.current_positions] Job Spawn Positions = [job.spawn_positions]")
- AssignRole(player, job.title)
- unassigned -= player
- break
-
- // Hand out random jobs to the people who didn't get any in the last check
- // Also makes sure that they got their preference correct
+ // Loop through all unassigned players
for(var/mob/new_player/player in unassigned)
- if(player.client.prefs.alternate_option == GET_RANDOM_JOB)
- GiveRandomJob(player)
- /*
- Old job system
- for(var/level = 1 to 3)
- for(var/datum/job/job in occupations)
- Debug("Checking job: [job]")
+
+ // Loop through all jobs
+ for(var/datum/job/job in shuffledoccupations) // SHUFFLE ME BABY
if(!job)
continue
- if(!unassigned.len)
- break
- if((job.current_positions >= job.spawn_positions) && job.spawn_positions != -1)
+
+ if(jobban_isbanned(player, job.title))
+ Debug("DO isbanned failed, Player: [player], Job:[job.title]")
continue
- var/list/candidates = FindOccupationCandidates(job, level)
- while(candidates.len && ((job.current_positions < job.spawn_positions) || job.spawn_positions == -1))
- var/mob/new_player/candidate = pick(candidates)
- Debug("Selcted: [candidate], for: [job.title]")
- AssignRole(candidate, job.title)
- candidates -= candidate*/
- Debug("DO, Standard Check end")
+ if(!job.player_old_enough(player.client))
+ Debug("DO player not old enough, Player: [player], Job:[job.title]")
+ continue
- Debug("DO, Running AC2")
+ if(job.available_in_playtime(player.client))
+ Debug("DO player not enough playtime, Player: [player], Job:[job.title]")
+ continue
- // Antags, who have to get in, come first
- for(var/mob/new_player/player in unassigned)
- if(player.mind.special_role)
- GiveRandomJob(player)
- if(player in unassigned)
- AssignRole(player, "Civilian")
+ if(player.mind && job.title in player.mind.restricted_roles)
+ Debug("DO incompatible with antagonist role, Player: [player], Job:[job.title]")
+ continue
- // Then we assign what we can to everyone else.
- for(var/mob/new_player/player in unassigned)
- if(player.client.prefs.alternate_option == BE_ASSISTANT)
- Debug("AC2 Assistant located, Player: [player]")
+ if(!is_job_whitelisted(player, job.title))
+ Debug("DO player not whitelisted, Player: [player], Job:[job.title]")
+ continue
+
+ // If the player wants that job on this level, then try give it to him.
+ if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
+
+ // If the job isn't filled
+ if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1)
+ Debug("DO pass, Player: [player], Level:[level], Job:[job.title]")
+ Debug(" - Job Flag: [job.flag] Job Department: [player.client.prefs.GetJobDepartment(job, level)] Job Current Pos: [job.current_positions] Job Spawn Positions = [job.spawn_positions]")
+ AssignRole(player, job.title)
+ unassigned -= player
+ break
+
+ // Hand out random jobs to the people who didn't get any in the last check
+ // Also makes sure that they got their preference correct
+ for(var/mob/new_player/player in unassigned)
+ if(player.client.prefs.alternate_option == GET_RANDOM_JOB)
+ GiveRandomJob(player)
+
+ Debug("DO, Standard Check end")
+
+ Debug("DO, Running AC2")
+
+ // Antags, who have to get in, come first
+ for(var/mob/new_player/player in unassigned)
+ if(player.mind.special_role)
+ GiveRandomJob(player)
+ if(player in unassigned)
AssignRole(player, "Civilian")
- else if(player.client.prefs.alternate_option == RETURN_TO_LOBBY)
- player.ready = 0
- unassigned -= player
- return 1
+
+ // Then we assign what we can to everyone else.
+ for(var/mob/new_player/player in unassigned)
+ if(player.client.prefs.alternate_option == BE_ASSISTANT)
+ Debug("AC2 Assistant located, Player: [player]")
+ AssignRole(player, "Civilian")
+ else if(player.client.prefs.alternate_option == RETURN_TO_LOBBY)
+ player.ready = 0
+ unassigned -= player
+
+ return 1
- proc/EquipRank(var/mob/living/carbon/human/H, var/rank, var/joined_late = 0)
- if(!H) return null
- var/datum/job/job = GetJob(rank)
- var/list/spawn_in_storage = list()
+/datum/controller/occupations/proc/EquipRank(var/mob/living/carbon/human/H, var/rank, var/joined_late = 0)
+ if(!H)
+ return null
- if(job)
+ var/datum/job/job = GetJob(rank)
- //Equip custom gear loadout.
- var/list/custom_equip_slots = list() //If more than one item takes the same slot, all after the first one spawn in storage.
- var/list/custom_equip_leftovers = list()
- if(H.client.prefs.gear && H.client.prefs.gear.len && job.title != "Cyborg" && job.title != "AI")
- for(var/thing in H.client.prefs.gear)
- var/datum/gear/G = gear_datums[thing]
- if(G)
- var/permitted
- if(G.allowed_roles)
- for(var/job_name in G.allowed_roles)
- if(job.title == job_name)
- permitted = 1
- else
- permitted = 1
+ H.job = rank
- if(G.whitelisted && (G.whitelisted != H.species.name || !is_alien_whitelisted(H, G.whitelisted)))
- permitted = 0
+ if(!joined_late)
+ var/turf/T = null
+ var/obj/S = null
+ for(var/obj/effect/landmark/start/sloc in landmarks_list)
+ if(sloc.name != rank)
+ continue
+ if(locate(/mob/living) in sloc.loc)
+ continue
+ S = sloc
+ break
+ if(!S)
+ S = locate("start*[rank]") // use old stype
+ if(!S) // still no spawn, fall back to the arrivals shuttle
+ for(var/turf/TS in get_area_turfs(/area/shuttle/arrival))
+ if(!TS.density)
+ var/clear = 1
+ for(var/obj/O in TS)
+ if(O.density)
+ clear = 0
+ break
+ if(clear)
+ T = TS
+ continue
- if(!permitted)
- to_chat(H, "Your current job or whitelist status does not permit you to spawn with [thing]!")
- continue
+ if(isturf(S))
+ T = S
+ else if(istype(S, /obj/effect/landmark/start) && isturf(S.loc))
+ T = S.loc
- if(G.slot && !(G.slot in custom_equip_slots))
- // This is a miserable way to fix the loadout overwrite bug, but the alternative requires
- // adding an arg to a bunch of different procs. Will look into it after this merge. ~ Z
- if(G.slot == slot_wear_mask || G.slot == slot_wear_suit || G.slot == slot_head)
- custom_equip_leftovers += thing
- else if(H.equip_to_slot_or_del(G.spawn_item(H), G.slot))
- to_chat(H, "Equipping you with \the [thing]!")
- custom_equip_slots.Add(G.slot)
- else
- custom_equip_leftovers.Add(thing)
- else
- spawn_in_storage += thing
-
- job.equip(H)
- job.apply_fingerprints(H)
-
- //If some custom items could not be equipped before, try again now.
- for(var/thing in custom_equip_leftovers)
- var/datum/gear/G = gear_datums[thing]
- if(G.slot in custom_equip_slots)
- spawn_in_storage += thing
- else
- var/metadata = H.client.prefs.gear[G.display_name]
- if(H.equip_to_slot_or_del(G.spawn_item(H, metadata), G.slot))
- to_chat(H, "Equipping you with \the [thing]!")
- custom_equip_slots.Add(G.slot)
- else
- spawn_in_storage += thing
- else
- to_chat(H, "Your job is [rank] and the game just can't handle it! Please report this bug to an administrator.")
-
- H.job = rank
-
- if(!joined_late)
- var/obj/S = null
- for(var/obj/effect/landmark/start/sloc in landmarks_list)
- if(sloc.name != rank) continue
- if(locate(/mob/living) in sloc.loc) continue
- S = sloc
- break
- if(!S)
- S = locate("start*[rank]") // use old stype
- if(istype(S, /obj/effect/landmark/start) && istype(S.loc, /turf))
- H.loc = S.loc
+ if(T)
+ H.loc = T
// Moving wheelchair if they have one
if(H.buckled && istype(H.buckled, /obj/structure/stool/bed/chair/wheelchair))
H.buckled.loc = H.loc
H.buckled.dir = H.dir
- var/datum/money_account/M = create_account(H.real_name, rand(50,500)*10, null)
- if(H.mind)
- var/remembered_info = ""
+ var/alt_title = null
+ if(H.mind)
+ H.mind.assigned_role = rank
+ alt_title = H.mind.role_alt_title
- remembered_info += "Your account number is: #[M.account_number] "
- remembered_info += "Your account pin is: [M.remote_access_pin] "
- remembered_info += "Your account funds are: $[M.money] "
+ CreateMoneyAccount(H, rank, job)
- if(M.transaction_log.len)
- var/datum/transaction/T = M.transaction_log[1]
- remembered_info += "Your account was created: [T.time], [T.date] at [T.source_terminal] "
- H.mind.store_memory(remembered_info)
+ if(job)
+ var/new_mob = job.equip(H)
+ if(ismob(new_mob))
+ H = new_mob
- H.mind.initial_account = M
+ to_chat(H, "You are the [alt_title ? alt_title : rank].")
+ to_chat(H, "As the [alt_title ? alt_title : rank] you answer directly to [job.supervisors]. Special circumstances may change this.")
+ to_chat(H, "For more information on how the station works, see Standard Operating Procedure (SOP)")
+ if(job.is_service)
+ to_chat(H, "As a member of Service, make sure to read up on your Department SOP")
+ if(job.is_supply)
+ to_chat(H, "As a member of Supply, make sure to read up on your Department SOP")
+ if(job.is_command)
+ to_chat(H, "As an important member of Command, read up on your Department SOP")
+ if(job.is_legal)
+ to_chat(H, "Your job requires complete knowledge of Space Law and Legal Standard Operating Procedure")
+ if(job.is_engineering)
+ to_chat(H, "As a member of Engineering, make sure to read up on your Department SOP")
+ if(job.is_medical)
+ to_chat(H, "As a member of Medbay, make sure to read up on your Department SOP")
+ if(job.is_science)
+ to_chat(H, "As a member of Science, make sure to read up on your Department SOP")
+ if(job.is_security)
+ to_chat(H, "As a member of Security, you are to know Space Law, Legal Standard Operating Procedure, as well as your Department SOP")
+ if(job.req_admin_notify)
+ to_chat(H, "You are playing a job that is important for the game progression. If you have to disconnect, please notify the admins via adminhelp.")
- // If they're head, give them the account info for their department
- if(H.mind && job.head_position)
- var/remembered_info = ""
- var/datum/money_account/department_account = department_accounts[job.department]
-
- if(department_account)
- remembered_info += "Your department's account number is: #[department_account.account_number] "
- remembered_info += "Your department's account pin is: [department_account.remote_access_pin] "
- remembered_info += "Your department's account funds are: $[department_account.money] "
-
- H.mind.store_memory(remembered_info)
-
- spawn(0)
- to_chat(H, "Your account number is: [M.account_number], your account pin is: [M.remote_access_pin]")
-
- var/alt_title = null
- if(H.mind)
- H.mind.assigned_role = rank
- alt_title = H.mind.role_alt_title
-
- switch(rank)
- if("Cyborg")
- return H.Robotize()
- if("AI")
- return H
- if("Clown") //don't need bag preference stuff!
- if(rank=="Clown") // Clowns DO need to breathe, though - N3X
- H.species.equip(H)
- else
- switch(H.backbag) //BS12 EDIT
- if(1)
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
- if(2)
- var/obj/item/weapon/storage/backpack/BPK = new/obj/item/weapon/storage/backpack(H)
- new /obj/item/weapon/storage/box/survival(BPK)
- H.equip_to_slot_or_del(BPK, slot_back,1)
- if(3)
- var/obj/item/weapon/storage/backpack/BPK = new/obj/item/weapon/storage/backpack/satchel_norm(H)
- new /obj/item/weapon/storage/box/survival(BPK)
- H.equip_to_slot_or_del(BPK, slot_back,1)
- if(4)
- var/obj/item/weapon/storage/backpack/BPK = new/obj/item/weapon/storage/backpack/satchel(H)
- new /obj/item/weapon/storage/box/survival(BPK)
- H.equip_to_slot_or_del(BPK, slot_back,1)
- H.species.equip(H)
-
- //Deferred item spawning.
- for(var/thing in spawn_in_storage)
- var/datum/gear/G = gear_datums[thing]
- var/metadata = H.client.prefs.gear[G.display_name]
- var/item = G.spawn_item(null, metadata)
-
- var/atom/placed_in = H.equip_or_collect(item)
- if(placed_in)
- to_chat(H, "Placing \the [item] in your [placed_in.name]!")
- continue
- if(H.equip_to_appropriate_slot(item))
- to_chat(H, "Placing \the [item] in your inventory!")
- continue
- if(H.put_in_hands(item))
- to_chat(H, "Placing \the [item] in your hands!")
- continue
- to_chat(H, "Failed to locate a storage object on your mob, either you spawned with no arms and no backpack or this is a bug.")
- qdel(item)
-
-
- to_chat(H, "You are the [alt_title ? alt_title : rank].")
- to_chat(H, "As the [alt_title ? alt_title : rank] you answer directly to [job.supervisors]. Special circumstances may change this.")
- to_chat(H, "For more information on how the station works, see Standard Operating Procedure (SOP)")
- if(job.is_service)
- to_chat(H, "As a member of Service, make sure to read up on your Department SOP")
- if(job.is_supply)
- to_chat(H, "As a member of Supply, make sure to read up on your Department SOP")
- if(job.is_command)
- to_chat(H, "As an important member of Command, read up on your Department SOP")
- if(job.is_legal)
- to_chat(H, "Your job requires complete knowledge of Space Law and Legal Standard Operating Procedure")
- if(job.is_engineering)
- to_chat(H, "As a member of Engineering, make sure to read up on your Department SOP")
- if(job.is_medical)
- to_chat(H, "As a member of Medbay, make sure to read up on your Department SOP")
- if(job.is_science)
- to_chat(H, "As a member of Science, make sure to read up on your Department SOP")
- if(job.is_security)
- to_chat(H, "As a member of Security, you are to know Space Law, Legal Standard Operating Procedure, as well as your Department SOP")
- if(job.req_admin_notify)
- to_chat(H, "You are playing a job that is important for the game progression. If you have to disconnect, please notify the admins via adminhelp.")
-
- spawnId(H, rank, alt_title)
- H.equip_to_slot_or_del(new /obj/item/device/radio/headset(H), slot_l_ear)
+ if(job && H)
+ job.after_spawn(H)
//Gives glasses to the vision impaired
if(H.disabilities & DISABILITY_FLAG_NEARSIGHTED)
@@ -579,121 +491,107 @@ var/global/datum/controller/occupations/job_master
if(istype(G) && !G.prescription)
G.prescription = 1
G.name = "prescription [G.name]"
- H.regenerate_icons()
-
- H.sec_hud_set_ID()
- H.sec_hud_set_implants()
- return H
+ return H
- proc/spawnId(var/mob/living/carbon/human/H, rank, title)
- if(!H) return 0
- var/obj/item/weapon/card/id/C = null
- var/datum/job/job = null
- for(var/datum/job/J in occupations)
- if(J.title == rank)
- job = J
- break
- if(job)
- if(job.title == "Cyborg")
- return
- else
- C = new job.idtype(H)
- C.access = job.get_access()
+
+/datum/controller/occupations/proc/LoadJobs(jobsfile) //ran during round setup, reads info from jobs.txt -- Urist
+ if(!config.load_jobs_from_txt)
+ return 0
+
+ var/list/jobEntries = file2list(jobsfile)
+
+ for(var/job in jobEntries)
+ if(!job)
+ continue
+
+ job = trim(job)
+ if(!length(job))
+ continue
+
+ var/pos = findtext(job, "=")
+ var/name = null
+ var/value = null
+
+ if(pos)
+ name = copytext(job, 1, pos)
+ value = copytext(job, pos + 1)
else
- C = new /obj/item/weapon/card/id(H)
- if(C)
- C.registered_name = H.real_name
- C.rank = rank
- C.assignment = title ? title : rank
- C.sex = capitalize(H.gender)
- C.age = H.age
- C.name = "[C.registered_name]'s ID Card ([C.assignment])"
- C.photo = get_id_photo(H)
+ continue
- //put the player's account number onto the ID
- if(H.mind && H.mind.initial_account)
- C.associated_account_number = H.mind.initial_account.account_number
+ if(name && value)
+ var/datum/job/J = GetJob(name)
+ if(!J) continue
+ J.total_positions = text2num(value)
+ J.spawn_positions = text2num(value)
+ if(name == "AI" || name == "Cyborg")//I dont like this here but it will do for now
+ J.total_positions = 0
- H.equip_to_slot_or_del(C, slot_wear_id)
-
- H.equip_to_slot_or_del(new /obj/item/device/pda(H), slot_wear_pda)
- if(locate(/obj/item/device/pda,H))
- 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
+ return 1
- proc/LoadJobs(jobsfile) //ran during round setup, reads info from jobs.txt -- Urist
- if(!config.load_jobs_from_txt)
- return 0
+/datum/controller/occupations/proc/HandleFeedbackGathering()
+ for(var/datum/job/job in occupations)
+ var/tmp_str = "|[job.title]|"
- var/list/jobEntries = file2list(jobsfile)
-
- for(var/job in jobEntries)
- if(!job)
+ var/level1 = 0 //high
+ var/level2 = 0 //medium
+ var/level3 = 0 //low
+ var/level4 = 0 //never
+ var/level5 = 0 //banned
+ var/level6 = 0 //account too young
+ for(var/mob/new_player/player in player_list)
+ if(!(player.ready && player.mind && !player.mind.assigned_role))
+ continue //This player is not ready
+ if(jobban_isbanned(player, job.title))
+ level5++
continue
-
- job = trim(job)
- if(!length(job))
+ if(!job.player_old_enough(player.client))
+ level6++
continue
-
- var/pos = findtext(job, "=")
- var/name = null
- var/value = null
-
- if(pos)
- name = copytext(job, 1, pos)
- value = copytext(job, pos + 1)
- else
+ if(job.available_in_playtime(player.client))
+ level6++
continue
+ if(player.client.prefs.GetJobDepartment(job, 1) & job.flag)
+ level1++
+ else if(player.client.prefs.GetJobDepartment(job, 2) & job.flag)
+ level2++
+ else if(player.client.prefs.GetJobDepartment(job, 3) & job.flag)
+ level3++
+ else level4++ //not selected
- if(name && value)
- var/datum/job/J = GetJob(name)
- if(!J) continue
- J.total_positions = text2num(value)
- J.spawn_positions = text2num(value)
- if(name == "AI" || name == "Cyborg")//I dont like this here but it will do for now
- J.total_positions = 0
-
- return 1
+ tmp_str += "HIGH=[level1]|MEDIUM=[level2]|LOW=[level3]|NEVER=[level4]|BANNED=[level5]|YOUNG=[level6]|-"
+ feedback_add_details("job_preferences",tmp_str)
- proc/HandleFeedbackGathering()
- for(var/datum/job/job in occupations)
- var/tmp_str = "|[job.title]|"
+/datum/controller/occupations/proc/CreateMoneyAccount(mob/living/H, rank, datum/job/job)
+ var/datum/money_account/M = create_account(H.real_name, rand(50,500)*10, null)
+ var/remembered_info = ""
- var/level1 = 0 //high
- var/level2 = 0 //medium
- var/level3 = 0 //low
- var/level4 = 0 //never
- var/level5 = 0 //banned
- var/level6 = 0 //account too young
- for(var/mob/new_player/player in player_list)
- if(!(player.ready && player.mind && !player.mind.assigned_role))
- continue //This player is not ready
- if(jobban_isbanned(player, job.title))
- level5++
- continue
- if(!job.player_old_enough(player.client))
- level6++
- continue
- if(job.available_in_playtime(player.client))
- level6++
- continue
- if(player.client.prefs.GetJobDepartment(job, 1) & job.flag)
- level1++
- else if(player.client.prefs.GetJobDepartment(job, 2) & job.flag)
- level2++
- else if(player.client.prefs.GetJobDepartment(job, 3) & job.flag)
- level3++
- else level4++ //not selected
+ remembered_info += "Your account number is: #[M.account_number] "
+ remembered_info += "Your account pin is: [M.remote_access_pin] "
+ remembered_info += "Your account funds are: $[M.money] "
- tmp_str += "HIGH=[level1]|MEDIUM=[level2]|LOW=[level3]|NEVER=[level4]|BANNED=[level5]|YOUNG=[level6]|-"
- feedback_add_details("job_preferences",tmp_str)
+ if(M.transaction_log.len)
+ var/datum/transaction/T = M.transaction_log[1]
+ remembered_info += "Your account was created: [T.time], [T.date] at [T.source_terminal] "
+ H.mind.store_memory(remembered_info)
+
+ // If they're head, give them the account info for their department
+ if(job.head_position)
+ remembered_info = ""
+ var/datum/money_account/department_account = department_accounts[job.department]
+
+ if(department_account)
+ remembered_info += "Your department's account number is: #[department_account.account_number] "
+ remembered_info += "Your department's account pin is: [department_account.remote_access_pin] "
+ remembered_info += "Your department's account funds are: $[department_account.money] "
+
+ H.mind.store_memory(remembered_info)
+
+ H.mind.initial_account = M
+
+ spawn(0)
+ to_chat(H, "Your account number is: [M.account_number], your account pin is: [M.remote_access_pin]")
diff --git a/code/game/jobs/job_exp.dm b/code/game/jobs/job_exp.dm
index e0b403bfce7..c9ce95a86a9 100644
--- a/code/game/jobs/job_exp.dm
+++ b/code/game/jobs/job_exp.dm
@@ -13,13 +13,13 @@
var/jtext
for(var/client/C in clients)
jtext = "No Job"
- if(C.mob.mind.assigned_role)
+ if(C.mob.mind && C.mob.mind.assigned_role)
theirjob = job_master.GetJob(C.mob.mind.assigned_role)
if(theirjob)
jtext = theirjob.title
if(config.use_exp_restrictions && theirjob.exp_requirements && theirjob.exp_type)
jtext += "*"
- if(check_rights(R_ADMIN))
+ if(check_rights(R_ADMIN, 0))
pline = "
"
- for(var/Dt in typesof(/datum/disease/))
- var/datum/disease/Dis = new Dt(0)
- if(istype(Dis, /datum/disease/advance))
- continue // TODO (tm): Add advance diseases to the virus database which no one uses.
- if(!Dis.desc)
- continue
- dat += " [Dis.name]"
- dat += " Back"
- if(6.0)
- dat += "
Medical Robot Monitor
"
- dat += "Back"
- dat += " Medical Robots:"
- var/bdat = null
- for(var/mob/living/simple_animal/bot/medbot/M in world)
+ if(is_away_level(z))
+ to_chat(user, "Unable to establish a connection: You're too far away from the station!")
+ return
+ add_fingerprint(user)
+ ui_interact(user)
- if(M.z != src.z) continue //only find medibots on the same z-level as the computer
- var/turf/bl = get_turf(M)
- if(bl) //if it can't find a turf for the medibot, then it probably shouldn't be showing up
- bdat += "[M.name] - \[[bl.x],[bl.y]\] - [M.on ? "Online" : "Offline"] "
- if((!isnull(M.reagent_glass)) && M.use_beaker)
- bdat += "Reservoir: \[[M.reagent_glass.reagents.total_volume]/[M.reagent_glass.reagents.maximum_volume]\] "
- else
- bdat += "Using Internal Synthesizer. "
- if(!bdat)
- dat += "
"
- if("rank")
- var/list/L = list( "Head of Personnel", "Captain", "AI" )
- //This was so silly before the change. Now it actually works without beating your head against the keyboard. /N
- if((istype(active1, /datum/data/record) && L.Find(rank)))
- temp = "
", buttons)
+ if("rank")
+ var/list/L = list("Head of Personnel", "Captain", "AI")
+ //This was so silly before the change. Now it actually works without beating your head against the keyboard. /N
+ if(istype(active1, /datum/data/record) && L.Find(rank))
+ var/list/buttons = list()
+ for(var/rank in joblist)
+ buttons[++buttons.len] = list("name" = rank, "icon" = null, "href" = "rank=[rank]", "status" = (active1.fields["rank"] == rank ? "selected" : null))
+ setTemp("
Rank
", buttons)
else
- temp = "This function does not appear to be working at the moment. Our apologies."
+ setTemp("
You do not have the required rank to do this!
")
+ if("species")
+ if(istype(active1, /datum/data/record))
+ var/t1 = copytext(trim(sanitize(input("Please enter race:", "General records", active1.fields["species"], null) as message)), 1, MAX_MESSAGE_LEN)
+ if(!t1 || ..() || active1 != a1)
+ return 1
+ active1.fields["species"] = t1
+ return 1
- add_fingerprint(usr)
- updateUsrDialog()
- return
+/obj/machinery/computer/secure_data/proc/setTemp(text, list/buttons = list())
+ temp = list("text" = text, "buttons" = buttons, "has_buttons" = buttons.len > 0)
+
+/obj/machinery/computer/secure_data/proc/update_all_mob_security_hud()
+ for(var/mob/living/carbon/human/H in mob_list)
+ H.sec_hud_set_security_status()
/obj/machinery/computer/secure_data/proc/create_record_photo(datum/data/record/R)
// basically copy-pasted from the camera code but different enough that it has to be redone
@@ -568,8 +468,8 @@ What a mess.*/
var/icon/pc = icon('icons/obj/bureaucracy.dmi', "photo")
small_img.Scale(8, 8)
tiny_img.Scale(4, 4)
- ic.Blend(small_img,ICON_OVERLAY, 10, 13)
- pc.Blend(tiny_img,ICON_OVERLAY, 12, 19)
+ ic.Blend(small_img, ICON_OVERLAY, 10, 13)
+ pc.Blend(tiny_img, ICON_OVERLAY, 12, 19)
var/datum/picture/P = new()
P.fields["name"] = "File Photo - [R.fields["name"]]"
@@ -582,8 +482,8 @@ What a mess.*/
P.fields["pixel_y"] = rand(-10, 10)
P.fields["size"] = 2
- var/obj/item/weapon/photo/Photo = new/obj/item/weapon/photo(loc)
- Photo.construct(P)
+ var/obj/item/weapon/photo/PH = new/obj/item/weapon/photo(loc)
+ PH.construct(P)
/obj/machinery/computer/secure_data/proc/get_record_photo(datum/data/record/R)
// similar to the code to make a photo, but of course the actual rendering is completely different
@@ -607,7 +507,7 @@ What a mess.*/
if(1)
R.fields["name"] = "[pick(pick(first_names_male), pick(first_names_female))] [pick(last_names)]"
if(2)
- R.fields["sex"] = pick("Male", "Female")
+ R.fields["sex"] = pick("Male", "Female")
if(3)
R.fields["age"] = rand(5, 85)
if(4)
@@ -627,3 +527,7 @@ What a mess.*/
/obj/machinery/computer/secure_data/detective_computer
icon = 'icons/obj/computer.dmi'
icon_state = "messyfiles"
+
+#undef SEC_DATA_R_LIST
+#undef SEC_DATA_MAINT
+#undef SEC_DATA_RECORD
\ No newline at end of file
diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm
index 384e9e80179..e98028e3807 100644
--- a/code/game/machinery/computer/skills.dm
+++ b/code/game/machinery/computer/skills.dm
@@ -1,4 +1,6 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
+#define SKILL_DATA_R_LIST 1 // Record list
+#define SKILL_DATA_MAINT 2 // Records maintenance
+#define SKILL_DATA_RECORD 3 // Record
/obj/machinery/computer/skills//TODO:SANITY
name = "employment records console"
@@ -15,372 +17,280 @@
var/rank = null
var/screen = null
var/datum/data/record/active1 = null
- var/a_id = null
var/temp = null
var/printing = null
- var/can_change_id = 0
- var/list/Perp
- var/tempname = null
//Sorting Variables
var/sortBy = "name"
var/order = 1 // -1 = Descending - 1 = Ascending
-/obj/machinery/computer/skills/attackby(obj/item/O as obj, user as mob, params)
+/obj/machinery/computer/skills/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/weapon/card/id) && !scan)
- usr.drop_item()
- O.loc = src
+ user.drop_item()
+ O.forceMove(src)
scan = O
- to_chat(user, "You insert [O].")
+ ui_interact(user)
..()
-/obj/machinery/computer/skills/attack_ai(mob/user as mob)
- return attack_hand(user)
-
//Someone needs to break down the dat += into chunks instead of long ass lines.
-/obj/machinery/computer/skills/attack_hand(mob/user as mob)
+/obj/machinery/computer/skills/attack_hand(mob/user)
if(..())
return
-
- if(is_away_level(src.z))
+ if(is_away_level(z))
to_chat(user, "Unable to establish a connection: You're too far away from the station!")
return
- var/dat
+ add_fingerprint(user)
+ ui_interact(user)
- if(temp)
- dat = "[temp]
", buttons)
else
- temp = "This function does not appear to be working at the moment. Our apologies."
+ setTemp("You do not have the required rank to do this!")
+ if("species")
+ if(istype(active1, /datum/data/record))
+ var/t1 = copytext(trim(sanitize(input("Please enter race:", "General records", active1.fields["species"], null) as message)), 1, MAX_MESSAGE_LEN)
+ if(!t1 || incapable || active1 != a1)
+ return 1
+ active1.fields["species"] = t1
+ return 1
- add_fingerprint(usr)
- updateUsrDialog()
- return
+/obj/machinery/computer/skills/proc/setTemp(text, list/buttons = list())
+ temp = list("text" = text, "buttons" = buttons, "has_buttons" = buttons.len > 0)
/obj/machinery/computer/skills/emp_act(severity)
if(stat & (BROKEN|NOPOWER))
@@ -393,7 +303,7 @@ What a mess.*/
if(1)
R.fields["name"] = "[pick(pick(first_names_male), pick(first_names_female))] [pick(last_names)]"
if(2)
- R.fields["sex"] = pick("Male", "Female")
+ R.fields["sex"] = pick("Male", "Female")
if(3)
R.fields["age"] = rand(5, 85)
if(4)
@@ -409,3 +319,7 @@ What a mess.*/
continue
..(severity)
+
+#undef SKILL_DATA_R_LIST
+#undef SKILL_DATA_MAINT
+#undef SKILL_DATA_RECORD
\ No newline at end of file
diff --git a/code/game/machinery/computer/specops_shuttle.dm b/code/game/machinery/computer/specops_shuttle.dm
index b586fd4194a..d50d0355d5c 100644
--- a/code/game/machinery/computer/specops_shuttle.dm
+++ b/code/game/machinery/computer/specops_shuttle.dm
@@ -89,7 +89,7 @@ var/specops_shuttle_timeleft = 0
for(var/turf/T in get_area_turfs(end_location) )
var/mob/M = locate(/mob) in T
- to_chat(M, "\red You have arrived at Central Command. Operation has ended!")
+ to_chat(M, "You have arrived at Central Command. Operation has ended!")
specops_shuttle_at_station = 0
@@ -137,7 +137,7 @@ var/specops_shuttle_timeleft = 0
if(specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) return
if(!specops_can_move())
- to_chat(usr, "\red The Special Operations shuttle is unable to leave.")
+ to_chat(usr, "The Special Operations shuttle is unable to leave.")
return
//Begin Marauder launchpad.
@@ -231,7 +231,7 @@ var/specops_shuttle_timeleft = 0
for(var/turf/T in get_area_turfs(end_location) )
var/mob/M = locate(/mob) in T
- to_chat(M, "\red You have arrived to [station_name]. Commence operation!")
+ to_chat(M, "You have arrived to [station_name]. Commence operation!")
for(var/obj/machinery/computer/specops_shuttle/S in world)
S.specops_shuttle_timereset = world.time + SPECOPS_RETURN_DELAY
@@ -247,23 +247,23 @@ var/specops_shuttle_timeleft = 0
return 1
/obj/machinery/computer/specops_shuttle/attack_ai(var/mob/user as mob)
- to_chat(user, "\red Access Denied.")
+ to_chat(user, "Access Denied.")
return 1
/obj/machinery/computer/specops_shuttle/attackby(I as obj, user as mob, params)
if(istype(I,/obj/item/weapon/card/emag))
- to_chat(user, "\blue The electronic systems in this console are far too advanced for your primitive hacking peripherals.")
+ to_chat(user, "The electronic systems in this console are far too advanced for your primitive hacking peripherals.")
else
return attack_hand(user)
/obj/machinery/computer/specops_shuttle/attack_hand(var/mob/user as mob)
if(!allowed(user))
- to_chat(user, "\red Access Denied.")
+ to_chat(user, "Access Denied.")
return
//Commented out so admins can do shenanigans at their leisure. Also makes the force-spawned admin ERTs able to use the shuttle.
// if(sent_strike_team == 0 && send_emergency_team == 0)
-// to_chat(usr, "\red The strike team has not yet deployed.")
+// to_chat(usr, "The strike team has not yet deployed.")
// return
if(..())
@@ -294,14 +294,14 @@ var/specops_shuttle_timeleft = 0
if(!specops_shuttle_at_station|| specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) return
if(!specops_can_move())
- to_chat(usr, "\blue Central Command will not allow the Special Operations shuttle to return yet.")
+ to_chat(usr, "Central Command will not allow the Special Operations shuttle to return yet.")
if(world.timeofday <= specops_shuttle_timereset)
if(((world.timeofday - specops_shuttle_timereset)/10) > 60)
- to_chat(usr, "\blue [-((world.timeofday - specops_shuttle_timereset)/10)/60] minutes remain!")
- to_chat(usr, "\blue [-(world.timeofday - specops_shuttle_timereset)/10] seconds remain!")
+ to_chat(usr, "[-((world.timeofday - specops_shuttle_timereset)/10)/60] minutes remain!")
+ to_chat(usr, "[-(world.timeofday - specops_shuttle_timereset)/10] seconds remain!")
return
- to_chat(usr, "\blue The Special Operations shuttle will arrive at Central Command in [(SPECOPS_MOVETIME/10)] seconds.")
+ to_chat(usr, "The Special Operations shuttle will arrive at Central Command in [(SPECOPS_MOVETIME/10)] seconds.")
temp += "Shuttle departing.
OK"
updateUsrDialog()
@@ -315,10 +315,10 @@ var/specops_shuttle_timeleft = 0
if(specops_shuttle_at_station || specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) return
if(!specops_can_move())
- to_chat(usr, "\red The Special Operations shuttle is unable to leave.")
+ to_chat(usr, "The Special Operations shuttle is unable to leave.")
return
- to_chat(usr, "\blue The Special Operations shuttle will arrive on [station_name] in [(SPECOPS_MOVETIME/10)] seconds.")
+ to_chat(usr, "The Special Operations shuttle will arrive on [station_name] in [(SPECOPS_MOVETIME/10)] seconds.")
temp += "Shuttle departing.
OK"
updateUsrDialog()
diff --git a/code/game/machinery/computer/station_alert.dm b/code/game/machinery/computer/station_alert.dm
index c40e7968145..9c2dde8d3b7 100644
--- a/code/game/machinery/computer/station_alert.dm
+++ b/code/game/machinery/computer/station_alert.dm
@@ -24,8 +24,7 @@
/obj/machinery/computer/station_alert/Destroy()
alarm_monitor.unregister(src)
- qdel(alarm_monitor)
- alarm_monitor = null
+ QDEL_NULL(alarm_monitor)
return ..()
/obj/machinery/computer/station_alert/attack_ai(mob/user)
diff --git a/code/game/machinery/computer/store.dm b/code/game/machinery/computer/store.dm
index 31cfb8bfa8c..895bdd6de4a 100644
--- a/code/game/machinery/computer/store.dm
+++ b/code/game/machinery/computer/store.dm
@@ -140,8 +140,8 @@ td.cost.toomuch {
updateUsrDialog()
return
if(!centcomm_store.PlaceOrder(usr,itemID))
- to_chat(usr, "\red Unable to charge your account.")
+ to_chat(usr, "Unable to charge your account.")
else
- to_chat(usr, "\blue You've successfully purchased the item. It should be in your hands or on the floor.")
+ to_chat(usr, "You've successfully purchased the item. It should be in your hands or on the floor.")
src.updateUsrDialog()
return
diff --git a/code/game/machinery/computer/syndicate_specops_shuttle.dm b/code/game/machinery/computer/syndicate_specops_shuttle.dm
index bba953b64e1..14a3fdb72ca 100644
--- a/code/game/machinery/computer/syndicate_specops_shuttle.dm
+++ b/code/game/machinery/computer/syndicate_specops_shuttle.dm
@@ -60,7 +60,7 @@ var/syndicate_elite_shuttle_timeleft = 0
if(syndicate_elite_shuttle_moving_to_station || syndicate_elite_shuttle_moving_to_mothership) return
if(!syndicate_elite_can_move())
- to_chat(usr, "\red The Syndicate Elite shuttle is unable to leave.")
+ to_chat(usr, "The Syndicate Elite shuttle is unable to leave.")
return
sleep(600)
@@ -172,7 +172,7 @@ var/syndicate_elite_shuttle_timeleft = 0
for(var/turf/T in get_area_turfs(end_location) )
var/mob/M = locate(/mob) in T
- to_chat(M, "\red You have arrived to [station_name]. Commence operation!")
+ to_chat(M, "You have arrived to [station_name]. Commence operation!")
/proc/syndicate_elite_can_move()
if(syndicate_elite_shuttle_moving_to_station || syndicate_elite_shuttle_moving_to_mothership) return 0
@@ -182,22 +182,22 @@ var/syndicate_elite_shuttle_timeleft = 0
return attack_hand(user)
/obj/machinery/computer/syndicate_elite_shuttle/attack_ai(var/mob/user as mob)
- to_chat(user, "\red Access Denied.")
+ to_chat(user, "Access Denied.")
return 1
/obj/machinery/computer/syndicate_elite_shuttle/attackby(I as obj, user as mob, params)
if(istype(I,/obj/item/weapon/card/emag))
- to_chat(user, "\blue The electronic systems in this console are far too advanced for your primitive hacking peripherals.")
+ to_chat(user, "The electronic systems in this console are far too advanced for your primitive hacking peripherals.")
else
return attack_hand(user)
/obj/machinery/computer/syndicate_elite_shuttle/attack_hand(var/mob/user as mob)
if(!allowed(user))
- to_chat(user, "\red Access Denied.")
+ to_chat(user, "Access Denied.")
return
// if(sent_syndicate_strike_team == 0)
-// to_chat(usr, "\red The strike team has not yet deployed.")
+// to_chat(usr, "The strike team has not yet deployed.")
// return
if(..())
@@ -227,17 +227,17 @@ var/syndicate_elite_shuttle_timeleft = 0
if(href_list["sendtodock"])
if(!syndicate_elite_shuttle_at_station|| syndicate_elite_shuttle_moving_to_station || syndicate_elite_shuttle_moving_to_mothership) return
- to_chat(usr, "\blue The Syndicate will not allow the Elite Squad shuttle to return.")
+ to_chat(usr, "The Syndicate will not allow the Elite Squad shuttle to return.")
return
else if(href_list["sendtostation"])
if(syndicate_elite_shuttle_at_station || syndicate_elite_shuttle_moving_to_station || syndicate_elite_shuttle_moving_to_mothership) return
if(!specops_can_move())
- to_chat(usr, "\red The Syndicate Elite shuttle is unable to leave.")
+ to_chat(usr, "The Syndicate Elite shuttle is unable to leave.")
return
- to_chat(usr, "\blue The Syndicate Elite shuttle will arrive on [station_name] in [(SYNDICATE_ELITE_MOVETIME/10)] seconds.")
+ to_chat(usr, "The Syndicate Elite shuttle will arrive on [station_name] in [(SYNDICATE_ELITE_MOVETIME/10)] seconds.")
temp = "Shuttle departing.
OK"
updateUsrDialog()
diff --git a/code/game/machinery/computer/vr_control.dm b/code/game/machinery/computer/vr_control.dm
new file mode 100644
index 00000000000..b1fded03b99
--- /dev/null
+++ b/code/game/machinery/computer/vr_control.dm
@@ -0,0 +1,37 @@
+/obj/machinery/computer/vr_control
+ name = "VR console"
+ desc = "A list and control panel for all virtual servers."
+ icon_screen = "comm_logs"
+
+ light_color = LIGHT_COLOR_DARKGREEN
+
+
+/obj/machinery/computer/vr_control/New()
+ ..()
+
+/obj/machinery/computer/vr_control/Destroy()
+ return ..()
+
+/obj/machinery/computer/vr_control/attack_ai(mob/user)
+ attack_hand(user)
+ ui_interact(user)
+
+
+/obj/machinery/computer/vr_control/attack_hand(mob/user)
+ add_fingerprint(user)
+ if(stat & (BROKEN|NOPOWER))
+ return
+ ui_interact(user)
+
+/obj/machinery/computer/vr_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ switch(alert("What would you like to do?", "VR Control", "Join Room", "Make Room", "Cancel"))
+ if("Join Room")
+ spawn_vr_avatar(user, input(user, "Choose a room to join.","Select Level") as null|anything in vr_rooms)
+ qdel(user)
+ if("Make Room")
+ make_vr_room(input(user, "Name your new Room","Name here.") as null|text, input(user, "Choose a Level to load into your new Room.","Select Level") as null|anything in vr_templates)
+ if("Cancel")
+ return
+
+/obj/machinery/computer/vr_control/interact(mob/user)
+
diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm
index 70f0195ce5d..a714e24febc 100644
--- a/code/game/machinery/constructable_frame.dm
+++ b/code/game/machinery/constructable_frame.dm
@@ -66,9 +66,9 @@
if(istype(P, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = P
if(C.amount >= 5)
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, C.usesound, 50, 1)
to_chat(user, "You start to add cables to the frame.")
- if(do_after(user, 20, target = src))
+ if(do_after(user, 20 * C.toolspeed, target = src))
if(state == 1 && C.amount >= 5 && C.use(5))
to_chat(user, "You add cables to the frame.")
state = 2
@@ -86,13 +86,13 @@
return
G.use(5)
to_chat(user, "You add the glass to the frame.")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src), G.usesound, 50, 1)
new /obj/structure/displaycase_frame(src.loc)
qdel(src)
return
if(istype(P, /obj/item/weapon/wrench))
- playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
+ playsound(src.loc, P.usesound, 75, 1)
to_chat(user, "You dismantle the frame.")
new /obj/item/stack/sheet/metal(src.loc, 5)
qdel(src)
@@ -100,7 +100,7 @@
if(istype(P, /obj/item/weapon/circuitboard))
var/obj/item/weapon/circuitboard/B = P
if(B.board_type == "machine")
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, B.usesound, 50, 1)
to_chat(user, "You add the circuit board to the frame.")
circuit = P
user.drop_item()
@@ -114,7 +114,7 @@
else
to_chat(user, "This frame does not accept circuit boards of this type!")
if(istype(P, /obj/item/weapon/wirecutters))
- playsound(src.loc, 'sound/items/Wirecutter.ogg', 50, 1)
+ playsound(src.loc, P.usesound, 50, 1)
to_chat(user, "You remove the cables.")
state = 1
icon_state = "box_0"
@@ -123,7 +123,7 @@
if(3)
if(istype(P, /obj/item/weapon/crowbar))
- playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
+ playsound(src.loc, P.usesound, 50, 1)
state = 2
circuit.loc = src.loc
circuit = null
@@ -145,9 +145,9 @@
component_check = 0
break
if(component_check)
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
+ playsound(src.loc, P.usesound, 50, 1)
var/obj/machinery/new_machine = new src.circuit.build_path(src.loc)
- new_machine.construction()
+ new_machine.on_construction()
for(var/obj/O in new_machine.component_parts)
qdel(O)
new_machine.component_parts = list()
@@ -190,20 +190,20 @@
for(var/I in req_components)
if(istype(P, I) && (req_components[I] > 0) && (!(P.flags & NODROP) || istype(P, /obj/item/stack)))
success=1
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
- if(istype(P, /obj/item/stack/cable_coil))
- var/obj/item/stack/cable_coil/CP = P
- var/camt = min(CP.amount, req_components[I])
- var/obj/item/stack/cable_coil/CC = new /obj/item/stack/cable_coil(src)
- CC.amount = camt
- CC.update_icon()
- CP.use(camt)
- components += CC
+ playsound(src.loc, P.usesound, 50, 1)
+ if(istype(P, /obj/item/stack))
+ var/obj/item/stack/S = P
+ var/camt = min(S.amount, req_components[I])
+ var/obj/item/stack/NS = new P.type(src)
+ NS.amount = camt
+ NS.update_icon()
+ S.use(camt)
+ components += NS
req_components[I] -= camt
update_req_desc()
break
user.drop_item()
- P.loc = src
+ P.forceMove(src)
components += P
req_components[I]--
update_req_desc()
diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm
index de5d69c2bbc..8e026cfd80a 100644
--- a/code/game/machinery/cryo.dm
+++ b/code/game/machinery/cryo.dm
@@ -52,7 +52,7 @@
component_parts += new /obj/item/stack/cable_coil(null, 1)
RefreshParts()
-/obj/machinery/atmospherics/unary/cryo_cell/construction()
+/obj/machinery/atmospherics/unary/cryo_cell/on_construction()
..(dir,dir)
/obj/machinery/atmospherics/unary/cryo_cell/RefreshParts()
@@ -265,7 +265,7 @@
/obj/machinery/atmospherics/unary/cryo_cell/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob, params)
if(istype(G, /obj/item/weapon/reagent_containers/glass))
if(beaker)
- to_chat(user, "\red A beaker is already loaded into the machine.")
+ to_chat(user, "A beaker is already loaded into the machine.")
return
if(!user.drop_item())
to_chat(user, "The [G] is stuck to you!")
@@ -415,10 +415,10 @@
to_chat(usr, "The cryo cell is already occupied!")
return
if(M.abiotic())
- to_chat(usr, "\red Subject may not have abiotic items on.")
+ to_chat(usr, "Subject may not have abiotic items on.")
return
if(!node)
- to_chat(usr, "\red The cell is not correctly connected to its pipe network!")
+ to_chat(usr, "The cell is not correctly connected to its pipe network!")
return
M.stop_pulling()
M.forceMove(src)
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index 807d3caf261..789d4f81b1c 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -29,14 +29,14 @@
var/allow_items = 1
/obj/machinery/computer/cryopod/attack_ai()
- src.attack_hand()
+ attack_hand()
/obj/machinery/computer/cryopod/attack_hand(mob/user = usr)
if(stat & (NOPOWER|BROKEN))
return
user.set_machine(src)
- src.add_fingerprint(usr)
+ add_fingerprint(usr)
var/dat
@@ -60,7 +60,7 @@
var/mob/user = usr
- src.add_fingerprint(user)
+ add_fingerprint(user)
if(href_list["log"])
@@ -120,7 +120,7 @@
I.loc = get_turf(src)
frozen_items -= I
- src.updateUsrDialog()
+ updateUsrDialog()
return
/obj/item/weapon/circuitboard/cryopodcontrol
@@ -178,7 +178,7 @@
var/time_till_despawn = 9000 // This is reduced by 90% if a player manually enters cryo
var/willing_time_divisor = 10
var/time_entered = 0 // Used to keep track of the safe period.
- var/obj/item/device/radio/intercom/announce //
+ var/obj/item/device/radio/intercom/announce
var/obj/machinery/computer/cryopod/control_computer
var/last_no_computer_message = 0
@@ -192,12 +192,18 @@
/obj/item/device/paicard,
/obj/item/weapon/gun,
/obj/item/weapon/pinpointer,
- /obj/item/clothing/suit,
/obj/item/clothing/shoes/magboots,
/obj/item/areaeditor/blueprints,
/obj/item/clothing/head/helmet/space,
+ /obj/item/clothing/suit/space,
+ /obj/item/clothing/suit/armor,
+ /obj/item/weapon/defibrillator/compact,
+ /obj/item/weapon/reagent_containers/hypospray/CMO,
+ /obj/item/clothing/accessory/medal/gold/captain,
+ /obj/item/clothing/gloves/color/black/krav_maga/sec,
/obj/item/weapon/storage/internal,
- /obj/item/device/spacepod_key
+ /obj/item/device/spacepod_key,
+ /obj/item/weapon/nullrod
)
// These items will NOT be preserved
var/list/do_not_preserve_items = list (
@@ -230,8 +236,8 @@
// Don't send messages unless we *need* the computer, and less than five minutes have passed since last time we messaged
if(!control_computer && urgent && last_no_computer_message + 5*60*10 < world.time)
- log_admin("Cryopod in [src.loc.loc] could not find control computer!")
- message_admins("Cryopod in [src.loc.loc] could not find control computer!")
+ log_admin("Cryopod in [loc.loc] could not find control computer!")
+ message_admins("Cryopod in [loc.loc] could not find control computer!")
last_no_computer_message = world.time
return control_computer != null
@@ -296,7 +302,7 @@
cloner.records.Remove(R)
//Delete all items not on the preservation list.
- var/list/items = src.contents
+ var/list/items = contents
items -= occupant // Don't delete the occupant
items -= announce // or the autosay radio.
@@ -322,7 +328,19 @@
control_computer.frozen_items += W
W.loc = null
else
- W.loc = src.loc
+ W.loc = loc
+
+ // Skip past any cult sacrifice objective using this person
+ if(GAMEMODE_IS_CULT && is_sacrifice_target(occupant.mind))
+ var/datum/game_mode/cult/cult_mode = ticker.mode
+ var/list/p_s_t = cult_mode.get_possible_sac_targets()
+ if(p_s_t.len)
+ cult_mode.sacrifice_target = pick(p_s_t)
+ for(var/datum/mind/H in ticker.mode.cult)
+ if(H.current)
+ to_chat(H.current, "[ticker.mode.cultdat.entity_name] murmurs, [occupant] is beyond your reach. Sacrifice [cult_mode.sacrifice_target.current] instead...")
+ else
+ cult_mode.bypass_phase()
//Update any existing objectives involving this mob.
for(var/datum/objective/O in all_objectives)
@@ -333,7 +351,8 @@
else if(O.target && istype(O.target,/datum/mind))
if(O.target == occupant.mind)
if(O.owner && O.owner.current)
- to_chat(O.owner.current, "You get the feeling your target is no longer within reach. Time for Plan [pick("A","B","C","D","X","Y","Z")]. Objectives updated!")
+ to_chat(O.owner.current, " You get the feeling your target is no longer within reach. Time for Plan [pick("A","B","C","D","X","Y","Z")]. Objectives updated!")
+ O.owner.current << 'sound/ambience/alarm4.ogg'
O.target = null
spawn(1) //This should ideally fire after the occupant is deleted.
if(!O) return
@@ -443,7 +462,7 @@
if(do_after(user, 20, target = G:affecting))
if(!M || !G || !G:affecting) return
- if(src.occupant)
+ if(occupant)
to_chat(user, "\The [src] is in use.")
return
@@ -479,7 +498,7 @@
message_admins("[key_name_admin(M)] has entered a stasis pod. (JMP)")
//Despawning occurs when process() is called with an occupant without a client.
- src.add_fingerprint(M)
+ add_fingerprint(M)
/obj/machinery/cryopod/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob)
@@ -530,6 +549,9 @@
willing = 1
if(willing)
+ if(!Adjacent(L))
+ to_chat(user, "You're not close enough to \the [src].")
+ return
if(L == user)
visible_message("[user] starts climbing into the cryo pod.")
else
@@ -538,7 +560,7 @@
if(do_after(user, 20, target = L))
if(!L) return
- if(src.occupant)
+ if(occupant)
to_chat(user, "\The [src] is in use.")
return
L.forceMove(src)
@@ -570,7 +592,7 @@
message_admins("[key_name_admin(L)] has entered a stasis pod.")
//Despawning occurs when process() is called with an occupant without a client.
- src.add_fingerprint(L)
+ add_fingerprint(L)
return
@@ -592,14 +614,14 @@
icon_state = base_icon_state
//Eject any items that aren't meant to be in the pod.
- var/list/items = src.contents
+ var/list/items = contents
if(occupant) items -= occupant
if(announce) items -= announce
for(var/obj/item/W in items)
W.loc = get_turf(src)
- src.go_out()
+ go_out()
add_fingerprint(usr)
name = initial(name)
@@ -613,7 +635,7 @@
if(usr.stat != 0 || !check_occupant_allowed(usr))
return
- if(src.occupant)
+ if(occupant)
to_chat(usr, "\The [src] is in use.")
return
@@ -629,13 +651,13 @@
if(!usr || !usr.client)
return
- if(src.occupant)
+ if(occupant)
to_chat(usr, "\The [src] is in use.")
return
usr.stop_pulling()
usr.forceMove(src)
- src.occupant = usr
+ occupant = usr
time_till_despawn = initial(time_till_despawn) / willing_time_divisor
if(orient_right)
@@ -648,7 +670,7 @@
occupant = usr
time_entered = world.time
- src.add_fingerprint(usr)
+ add_fingerprint(usr)
name = "[name] ([usr.name])"
return
diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm
index b54a2e88a34..5a3d479fd75 100644
--- a/code/game/machinery/deployable.dm
+++ b/code/game/machinery/deployable.dm
@@ -65,11 +65,11 @@ for reference:
/obj/structure/barricade/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, stacktype))
if(src.health < src.maxhealth)
- visible_message("\red [user] begins to repair the [src]!")
- if(do_after(user,20, target = src))
+ visible_message("[user] begins to repair the [src]!")
+ if(do_after(user, 20 * W.toolspeed, target = src))
src.health = src.maxhealth
W:use(1)
- visible_message("\red [user] repairs the [src]!")
+ visible_message("[user] repairs the [src]!")
return
else
return
@@ -77,9 +77,9 @@ for reference:
else if(istype(W, /obj/item/weapon/crowbar))
user.changeNext_move(CLICK_CD_MELEE)
user.visible_message("[user] is prying apart \the [src].", "You begin to pry apart \the [src].")
- playsound(src, 'sound/items/Crowbar.ogg', 200, 1)
+ playsound(src, W.usesound, 200, 1)
- if(do_after(user, 300, target = src) && src && !src.gcDestroyed)
+ if(do_after(user, 300 * W.toolspeed, target = src) && src && !src.gcDestroyed)
user.visible_message("[user] pries apart \the [src].", "You pry apart \the [src].")
dismantle()
return
@@ -115,8 +115,8 @@ for reference:
qdel(src)
return
-/obj/structure/barricade/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)//So bullets will fly over and stuff.
- if(air_group || (height==0))
+/obj/structure/barricade/CanPass(atom/movable/mover, turf/target, height=0)//So bullets will fly over and stuff.
+ if(height==0)
return 1
if(istype(mover) && mover.checkpass(PASSTABLE))
return 1
@@ -189,7 +189,7 @@ for reference:
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(2, 1, src)
s.start()
- visible_message("\red BZZzZZzZZzZT")
+ visible_message("BZZzZZzZZzZT")
return
return
else if(istype(W, /obj/item/weapon/wrench))
@@ -197,12 +197,12 @@ for reference:
src.health = src.maxhealth
src.emagged = 0
src.req_access = list(access_security)
- visible_message("\red [user] repairs the [src]!")
+ visible_message("[user] repairs the [src]!")
return
else if(src.emagged > 0)
src.emagged = 0
src.req_access = list(access_security)
- visible_message("\red [user] repairs the [src]!")
+ visible_message("[user] repairs the [src]!")
return
return
else
@@ -224,14 +224,14 @@ for reference:
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(2, 1, src)
s.start()
- visible_message("\red BZZzZZzZZzZT")
+ visible_message("BZZzZZzZZzZT")
else if(src.emagged == 1)
src.emagged = 2
to_chat(user, "You short out the anchoring mechanism on the [src].")
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(2, 1, src)
s.start()
- visible_message("\red BZZzZZzZZzZT")
+ visible_message("BZZzZZzZZzZT")
ex_act(severity)
switch(severity)
@@ -257,8 +257,8 @@ for reference:
src.explode()
return
- CanPass(atom/movable/mover, turf/target, height=0, air_group=0)//So bullets will fly over and stuff.
- if(air_group || (height==0))
+ CanPass(atom/movable/mover, turf/target, height=0)//So bullets will fly over and stuff.
+ if(height==0)
return 1
if(istype(mover) && mover.checkpass(PASSTABLE))
return 1
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 549c99dfbd1..fe802eb308b 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -34,7 +34,7 @@
var/main_power_timer = null
var/backup_power_timer = null
var/spawnPowerRestoreRunning = 0
- var/welded = null
+ var/welded = FALSE
var/locked = 0
var/lights = 1 // bolt lights show by default
var/datum/wires/airlock/wires = null
@@ -53,8 +53,8 @@
var/frozen = 0 //special condition for airlocks that are frozen shut, this will look weird on not normal airlocks because of a lack of special overlays.
autoclose = 1
explosion_block = 1
- var/doorOpen = 'sound/machines/airlock.ogg'
- var/doorClose = 'sound/machines/airlock.ogg'
+ var/doorOpen = 'sound/machines/airlock_open.ogg'
+ var/doorClose = 'sound/machines/airlock_close.ogg'
var/doorDeni = 'sound/machines/DeniedBeep.ogg' // i'm thinkin' Deni's
var/boltUp = 'sound/machines/BoltsUp.ogg'
var/boltDown = 'sound/machines/BoltsDown.ogg'
@@ -89,6 +89,11 @@
name = "External Airlock"
icon = 'icons/obj/doors/Doorext.dmi'
assembly_type = /obj/structure/door_assembly/door_assembly_ext
+ doorOpen = 'sound/machines/airlock_ext_open.ogg'
+ doorClose = 'sound/machines/airlock_ext_close.ogg'
+
+/obj/machinery/door/airlock/welded
+ welded = 1
/obj/machinery/door/airlock/glass
name = "Glass Airlock"
@@ -184,7 +189,6 @@
opacity = 0
assembly_type = /obj/structure/door_assembly/door_assembly_research
glass = 1
- heat_proof = 1
/obj/machinery/door/airlock/glass_mining
name = "Maintenance Hatch"
@@ -265,8 +269,11 @@
name = "Tranquillite Airlock"
icon = 'icons/obj/doors/Doorfreezer.dmi'
mineral = "tranquillite"
- doorOpen = null
+ doorOpen = null // it's silent!
doorClose = null
+ doorDeni = null
+ boltUp = null
+ boltDown = null
/obj/machinery/door/airlock/sandstone
name = "Sandstone Airlock"
@@ -327,7 +334,7 @@
About the new airlock wires panel:
* An airlock wire dialog can be accessed by the normal way or by using wirecutters or a multitool on the door while the wire-panel is open. This would show the following wires, which you can either wirecut/mend or send a multitool pulse through. There are 9 wires.
* one wire from the ID scanner. Sending a pulse through this flashes the red light on the door (if the door has power). If you cut this wire, the door will stop recognizing valid IDs. (If the door has 0000 access, it still opens and closes, though)
-* two wires for power. Sending a pulse through either one causes a breaker to trip, disabling the door for 10 seconds if backup power is connected, or 1 minute if not (or until backup power comes back on, whichever is shorter). Cutting either one disables the main door power, but unless backup power is also cut, the backup power re-powers the door in 10 seconds. While unpowered, the door may be \red open, but bolts-raising will not work. Cutting these wires may electrocute the user.
+* two wires for power. Sending a pulse through either one causes a breaker to trip, disabling the door for 10 seconds if backup power is connected, or 1 minute if not (or until backup power comes back on, whichever is shorter). Cutting either one disables the main door power, but unless backup power is also cut, the backup power re-powers the door in 10 seconds. While unpowered, the door may be open, but bolts-raising will not work. Cutting these wires may electrocute the user.
* one wire for door bolts. Sending a pulse through this drops door bolts (whether the door is powered or not) or raises them (if it is). Cutting this wire also drops the door bolts, and mending it does not raise them. If the wire is cut, trying to raise the door bolts will not work.
* two wires for backup power. Sending a pulse through either one causes a breaker to trip, but this does not disable it unless main power is down too (in which case it is disabled for 1 minute or however long it takes main power to come back, whichever is shorter). Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user.
* one wire for opening the door. Sending a pulse through this while the door has power makes it open the door if no access is required.
@@ -340,8 +347,7 @@ About the new airlock wires panel:
/obj/machinery/door/airlock/Destroy()
- qdel(wires)
- wires = null
+ QDEL_NULL(wires)
if(main_power_timer)
deltimer(main_power_timer)
main_power_timer = null
@@ -364,7 +370,7 @@ About the new airlock wires panel:
return
else /*if(src.justzap)*/
return
- else if(user.hallucination > 50 && prob(10) && src.operating == 0)
+ else if(user.hallucination > 50 && prob(10) && !operating)
to_chat(user, "You feel a powerful shock course through your body!")
user.adjustStaminaLoss(50)
user.AdjustStunned(5)
@@ -412,10 +418,10 @@ About the new airlock wires panel:
return 0
/obj/machinery/door/airlock/proc/mainPowerCablesCut()
- return src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1) || src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)
+ return src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)
/obj/machinery/door/airlock/proc/backupPowerCablesCut()
- return src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1) || src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2)
+ return src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)
/obj/machinery/door/airlock/proc/loseMainPower()
main_power_lost_until = mainPowerCablesCut() ? -1 : world.time + SecondsToTicks(60)
@@ -557,8 +563,10 @@ About the new airlock wires panel:
return
/obj/machinery/door/airlock/attack_ghost(mob/user)
- ui_interact(user)
-
+ if(p_open)
+ wires.Interact(user)
+ ui_interact(user)
+
/obj/machinery/door/airlock/attack_ai(mob/user)
ui_interact(user)
@@ -637,7 +645,7 @@ About the new airlock wires panel:
if(user)
src.attack_ai(user)
-/obj/machinery/door/airlock/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+/obj/machinery/door/airlock/CanPass(atom/movable/mover, turf/target, height=0)
if(src.isElectrified())
if(istype(mover, /obj/item))
var/obj/item/i = mover
@@ -658,14 +666,14 @@ About the new airlock wires panel:
if(H.getBrainLoss() >= 60)
playsound(src.loc, 'sound/effects/bang.ogg', 25, 1)
if(!istype(H.head, /obj/item/clothing/head/helmet))
- visible_message("\red [user] headbutts the airlock.")
+ visible_message("[user] headbutts the airlock.")
var/obj/item/organ/external/affecting = H.get_organ("head")
H.Stun(5)
H.Weaken(5)
if(affecting.take_damage(10, 0))
H.UpdateDamageIcon()
else
- visible_message("\red [user] headbutts the airlock. Good thing they're wearing a helmet.")
+ visible_message("[user] headbutts the airlock. Good thing they're wearing a helmet.")
return
if(src.p_open)
@@ -678,7 +686,7 @@ About the new airlock wires panel:
if(!issilicon(user) && !isobserver(user))
return STATUS_CLOSE
- if(operating < 0) //emagged
+ if(emagged)
to_chat(user, "Unable to interface: Internal error.")
return STATUS_CLOSE
if(!canAIControl() && !isobserver(user))
@@ -790,7 +798,7 @@ About the new airlock wires panel:
update_icon()
return 1
-/obj/machinery/door/airlock/attackby(C as obj, mob/user as mob, params)
+/obj/machinery/door/airlock/attackby(obj/item/C, mob/user as mob, params)
// to_chat(world, text("airlock attackby src [] obj [] mob []", src, C, user))
if(!istype(usr, /mob/living/silicon))
if(isElectrified())
@@ -800,7 +808,7 @@ About the new airlock wires panel:
return
add_fingerprint(user)
- if((istype(C, /obj/item/weapon/weldingtool) && !( operating ) && density))
+ if((istype(C, /obj/item/weapon/weldingtool) && !operating && density))
var/obj/item/weapon/weldingtool/W = C
if(W.remove_fuel(0,user))
if(frozen)
@@ -825,19 +833,20 @@ About the new airlock wires panel:
else if(istype(C, /obj/item/weapon/pai_cable)) // -- TLE
var/obj/item/weapon/pai_cable/cable = C
cable.plugin(src, user)
- else if(istype(C, /obj/item/weapon/crowbar) || istype(C, /obj/item/weapon/twohanded/fireaxe) )
+ else if(istype(C, /obj/item/weapon/crowbar) || istype(C, /obj/item/weapon/twohanded/fireaxe))
var/beingcrowbarred = null
if(istype(C, /obj/item/weapon/crowbar) )
beingcrowbarred = 1 //derp, Agouri
else
beingcrowbarred = 0
- if( beingcrowbarred && p_open && (operating == -1 || (density && welded && operating != 1 && !arePowerSystemsOn() && !locked)) )
- playsound(loc, 'sound/items/Crowbar.ogg', 100, 1)
+ if( beingcrowbarred && p_open && (emagged || (density && welded && (!operating || emagged) && !arePowerSystemsOn() && !locked)) )
+ playsound(loc, C.usesound, 100, 1)
user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to remove electronics from the airlock assembly.")
- if(do_after(user,40, target = src))
- to_chat(user, "\blue You removed the airlock electronics!")
+ if(do_after(user, 40 * C.toolspeed, target = src))
+ to_chat(user, "You removed the airlock electronics!")
var/obj/structure/door_assembly/da = new assembly_type(loc)
+ da.heat_proof_finished = heat_proof //tracks whether there's rglass in
da.anchored = 1
if(mineral)
da.glass = mineral
@@ -862,16 +871,41 @@ About the new airlock wires panel:
ae = electronics
electronics = null
ae.loc = loc
- if(operating == -1)
+ if(emagged)
ae.icon_state = "door_electronics_smoked"
operating = 0
qdel(src)
return
- else if(arePowerSystemsOn())
- to_chat(user, "\blue The airlock's motors resist your efforts to force it.")
+ if(istype(C, /obj/item/weapon/crowbar/power) && density)
+ if(isElectrified())
+ shock(user, 100)//it's like sticking a fork in a power socket
+ return
+
+ if(locked)
+ to_chat(user, "The bolts are down, it won't budge!")
+ return
+
+ if(welded)
+ to_chat(user, "It's welded, it won't budge!")
+ return
+
+ if(arePowerSystemsOn())
+ var/obj/item/weapon/crowbar/power/P = C
+ playsound(src, 'sound/machines/airlock_alien_prying.ogg', 100, 1) //is it aliens or just the CE being a dick?
+ user.visible_message("[user] starts forcing [src] with \the [P]...", \
+ "You begin forcing [src] with \the [P]...")
+ if(do_after(user, P.airlock_open_time, target = src))
+ user.visible_message("[user] forces [src] with \the [P].", \
+ "You force [src] with \the [P].")
+ open(2)
+ if(density && !open(2))
+ to_chat(user, "Despite your attempts, the [src] refuses to open.")
+ return
+ if(arePowerSystemsOn())
+ to_chat(user, "The airlock's motors resist your efforts to force it.")
else if(locked)
- to_chat(user, "\blue The airlock's bolts prevent it from being forced.")
+ to_chat(user, "The airlock's bolts prevent it from being forced.")
else if( !welded && !operating )
if(density)
if(beingcrowbarred == 0) //being fireaxe'd
@@ -879,7 +913,7 @@ About the new airlock wires panel:
if(F.wielded)
spawn(0) open(1)
else
- to_chat(user, "\red You need to be wielding \the [C] to do that.")
+ to_chat(user, "You need to be wielding \the [C] to do that.")
else
spawn(0) open(1)
else
@@ -888,7 +922,7 @@ About the new airlock wires panel:
if(F.wielded)
spawn(0) close(1)
else
- to_chat(user, "\red You need to be wielding \the [C] to do that.")
+ to_chat(user, "You need to be wielding \the [C] to do that.")
else
spawn(0) close(1)
else
@@ -903,7 +937,7 @@ About the new airlock wires panel:
..()
/obj/machinery/door/airlock/open(var/forced=0)
- if( operating || welded || locked )
+ if(operating || welded || locked || emagged)
return 0
if(!forced)
if( !arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_OPEN_DOOR) )
@@ -918,7 +952,7 @@ About the new airlock wires panel:
return ..()
/obj/machinery/door/airlock/close(var/forced=0, var/override = 0)
- if((operating & !override) || welded || locked)
+ if((operating & !override) || welded || locked || emagged)
return
if(!forced)
//despite the name, this wire is for general door control.
@@ -990,14 +1024,17 @@ About the new airlock wires panel:
/obj/machinery/door/airlock/New()
..()
wires = new(src)
+
+/obj/machinery/door/airlock/initialize()
+ . = ..()
if(closeOtherId != null)
- spawn (5)
- for(var/obj/machinery/door/airlock/A in airlocks)
- if(A.closeOtherId == closeOtherId && A != src)
- closeOther = A
- break
+ for(var/obj/machinery/door/airlock/A in airlocks)
+ if(A.closeOtherId == closeOtherId && A != src)
+ closeOther = A
+ break
if(frozen)
- welded = 1
+ welded = TRUE
+ if(welded)
update_icon()
/obj/machinery/door/airlock/hatch/gamma/attackby(C as obj, mob/user as mob, params)
@@ -1018,7 +1055,7 @@ About the new airlock wires panel:
return
add_fingerprint(user)
- if((istype(C, /obj/item/weapon/weldingtool) && !( operating > 0 ) && density))
+ if((istype(C, /obj/item/weapon/weldingtool) && !operating && density))
var/obj/item/weapon/weldingtool/W = C
if(W.remove_fuel(0,user))
if(frozen)
@@ -1043,7 +1080,7 @@ About the new airlock wires panel:
return
add_fingerprint(user)
- if((istype(C, /obj/item/weapon/weldingtool) && !( operating > 0 ) && density))
+ if((istype(C, /obj/item/weapon/weldingtool) && !operating && density))
var/obj/item/weapon/weldingtool/W = C
if(W.remove_fuel(0,user))
if(frozen)
@@ -1077,6 +1114,8 @@ About the new airlock wires panel:
update_icon()
/obj/machinery/door/airlock/proc/prison_open()
+ if(emagged)
+ return
if(arePowerSystemsOn())
unlock()
open()
diff --git a/code/game/machinery/doors/airlock_control.dm b/code/game/machinery/doors/airlock_control.dm
index 4904c8795fa..17ebdf96ce2 100644
--- a/code/game/machinery/doors/airlock_control.dm
+++ b/code/game/machinery/doors/airlock_control.dm
@@ -26,7 +26,7 @@ obj/machinery/door/airlock/receive_signal(datum/signal/signal)
execute_current_command()
obj/machinery/door/airlock/proc/execute_current_command()
- if(operating)
+ if(operating || emagged)
return //emagged or busy doing something else
if(!cur_command)
@@ -261,7 +261,7 @@ obj/machinery/access_button/attackby(obj/item/I as obj, mob/user as mob, params)
obj/machinery/access_button/attack_hand(mob/user)
add_fingerprint(usr)
if(!allowed(user))
- to_chat(user, "\red Access Denied")
+ to_chat(user, "Access Denied")
else if(radio_connection)
var/datum/signal/signal = new
diff --git a/code/game/machinery/doors/airlock_electronics.dm b/code/game/machinery/doors/airlock_electronics.dm
index acad5a5a563..b39e3798ae1 100644
--- a/code/game/machinery/doors/airlock_electronics.dm
+++ b/code/game/machinery/doors/airlock_electronics.dm
@@ -14,6 +14,8 @@
var/last_configurator = null
var/locked = TRUE
var/const/max_brain_damage = 60 // Maximum brain damage a mob can have until it can't use the electronics
+ toolspeed = 1
+ usesound = 'sound/items/Deconstruct.ogg'
/obj/item/weapon/airlock_electronics/attack_self(mob/user)
if(!ishuman(user) && !isrobot(user))
diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm
index 66547ff0759..7ec9630a54c 100644
--- a/code/game/machinery/doors/brigdoors.dm
+++ b/code/game/machinery/doors/brigdoors.dm
@@ -37,6 +37,7 @@
Radio = new /obj/item/device/radio(src)
Radio.listening = 0
Radio.config(list("Security" = 0))
+ Radio.follow_target = src
pixel_x = ((dir & 3)? (0) : (dir == 4 ? 32 : -32))
pixel_y = ((dir & 3)? (dir ==1 ? 24 : -32) : (0))
@@ -62,6 +63,10 @@
stat |= BROKEN
update_icon()
+/obj/machinery/door_timer/Destroy()
+ QDEL_NULL(Radio)
+ targets.Cut()
+ return ..()
//Main door timer loop, if it's timing and time is >0 reduce time by 1.
// if it's less than 0, open door, reset timer
@@ -185,7 +190,7 @@
if(..())
return
interact(user)
-
+
/obj/machinery/door_timer/interact(mob/user)
// Used for the 'time left' display
var/second = round(timeleft() % 60)
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 0d1488acad6..d6b295e1811 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -21,7 +21,9 @@
var/autoclose_timer
var/glass = 0
var/normalspeed = 1
- var/heat_proof = 0 // For glass airlocks/opacity firedoors
+ var/auto_close_time = 150
+ var/auto_close_time_dangerous = 5
+ var/heat_proof = 0 // For rglass-windowed airlocks and firedoors
var/emergency = 0
var/air_properties_vary_with_direction = 0
var/block_air_zones = 1 //If set, air zones cannot merge across the door even when it is opened.
@@ -37,7 +39,15 @@
else
layer = open_layer
+ update_dir()
+ update_freelook_sight()
+ airlocks += src
+/obj/machinery/door/setDir(newdir)
+ ..()
+ update_dir()
+
+/obj/machinery/door/proc/update_dir()
if(width > 1)
if(dir in list(EAST, WEST))
bound_width = width * world.icon_size
@@ -46,10 +56,6 @@
bound_width = world.icon_size
bound_height = width * world.icon_size
- update_freelook_sight()
- airlocks += src
- return
-
/obj/machinery/door/initialize()
air_update_turf(1)
..()
@@ -65,7 +71,8 @@
return ..()
/obj/machinery/door/Bumped(atom/AM)
- if(p_open || operating) return
+ if(p_open || operating || emagged)
+ return
if(isliving(AM))
var/mob/living/M = AM
if(world.time - M.last_bumped <= 10) return //Can bump-open one airlock per second. This is to prevent shock spam.
@@ -85,8 +92,7 @@
return
-/obj/machinery/door/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if(air_group) return 0
+/obj/machinery/door/CanPass(atom/movable/mover, turf/target, height=0)
if(istype(mover) && mover.checkpass(PASSGLASS))
return !opacity
return !density
@@ -94,14 +100,14 @@
/obj/machinery/door/CanAtmosPass()
return !density
-/obj/machinery/door/proc/bumpopen(mob/user as mob)
+/obj/machinery/door/proc/bumpopen(mob/user)
if(operating)
return
add_fingerprint(user)
if(!requiresID())
user = null
- if(density)
+ if(density && !emagged)
if(allowed(user) || emergency == 1)
open()
if(istype(user, /mob/living/simple_animal/bot))
@@ -116,8 +122,8 @@
/obj/machinery/door/attack_ghost(mob/user)
if(user.can_advanced_admin_interact())
- return attack_hand(user)
-
+ return attack_hand(user)
+
/obj/machinery/door/attack_hand(mob/user)
return attackby(user, user)
@@ -130,11 +136,12 @@
if(istype(I, /obj/item/device/detective_scanner))
return
- if(operating || isrobot(user))
+ if(isrobot(user))
return //borgs can't attack doors open because it conflicts with their AI-like interaction with them.
add_fingerprint(user)
-
+ if(operating || emagged)
+ return
if(density && (istype(I, /obj/item/weapon/card/emag) || istype(I, /obj/item/weapon/melee/energy/blade)))
emag_act(user)
return 1
@@ -149,12 +156,12 @@
if(density)
do_animate("deny")
-/obj/machinery/door/emag_act(user as mob)
+/obj/machinery/door/emag_act(mob/user)
if(density)
flick("door_spark", src)
sleep(6)
open()
- operating = -1
+ emagged = 1
return 1
/obj/machinery/door/blob_act()
@@ -211,11 +218,11 @@
/obj/machinery/door/proc/open()
if(!density)
return 1
- if(operating > 0)
+ if(operating)
return
if(!ticker)
return 0
- if(!operating) operating = 1
+ operating = 1
do_animate("opening")
set_opacity(0)
@@ -231,14 +238,14 @@
// The `addtimer` system has the advantage of being cancelable
if(autoclose)
- autoclose_timer = addtimer(src, "autoclose", normalspeed ? 150 : 5, unique = 1)
+ autoclose_timer = addtimer(src, "autoclose", normalspeed ? auto_close_time : auto_close_time_dangerous, unique = 1)
return 1
/obj/machinery/door/proc/close()
if(density)
return 1
- if(operating > 0)
+ if(operating)
return
operating = 1
@@ -303,7 +310,7 @@
if(!glass && cameranet)
cameranet.updateVisibility(src, 0)
-/obj/machinery/door/BlockSuperconductivity()
+/obj/machinery/door/BlockSuperconductivity() // All non-glass airlocks block heat, this is intended.
if(opacity || heat_proof)
return 1
return 0
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index 526ad96cde4..dbbe53055a4 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -13,32 +13,45 @@
icon = 'icons/obj/doors/Doorfireglass.dmi'
icon_state = "door_open"
opacity = 0
- density = 0
- heat_proof = 1
- glass = 1
+ density = FALSE
+ heat_proof = TRUE
+ glass = TRUE
power_channel = ENVIRON
closed_layer = 3.11
+ auto_close_time = 50
- var/assembly_type = /obj/structure/firelock_frame
+ var/can_force = TRUE
+ var/force_open_time = 300
+ var/can_crush = TRUE
+ var/assembly_type = /obj/structure/firelock_frame
var/nextstate = null
- var/welded = 0
- var/boltslocked = 1
- var/can_deconstruct = 1
+ var/welded = FALSE
+ var/boltslocked = TRUE
+ var/can_deconstruct = TRUE
+ var/active_alarm = FALSE
/obj/machinery/door/firedoor/Bumped(atom/AM)
- if(p_open || operating)
+ if(p_open || operating)
return
- if(!density)
+ if(!density)
return ..()
return 0
+/obj/machinery/door/firedoor/ex_act(severity)
+ switch(severity)
+ if(1.0)
+ qdel(src)
+ if(2.0)
+ if(prob(50))
+ qdel(src)
+
/obj/machinery/door/firedoor/power_change()
if(powered(power_channel))
stat &= ~NOPOWER
latetoggle()
else
stat |= NOPOWER
- return
+ update_icon()
/obj/machinery/door/firedoor/attackby(obj/item/weapon/C as obj, mob/user as mob, params)
add_fingerprint(user)
@@ -59,12 +72,12 @@
if(boltslocked)
to_chat(user, "There are screws locking the bolts in place!")
return
- playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(get_turf(src), C.usesound, 50, 1)
user.visible_message("[user] starts undoing [src]'s bolts...", \
"You start unfastening [src]'s floor bolts...")
- if(!do_after(user, 50, target = src))
+ if(!do_after(user, 50 * C.toolspeed, target = src))
return
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src), C.usesound, 50, 1)
user.visible_message("[user] unfastens [src]'s bolts.", \
"You undo [src]'s floor bolts.")
deconstruct(TRUE)
@@ -72,7 +85,7 @@
else if(istype(C, /obj/item/weapon/screwdriver))
user.visible_message("[user] [boltslocked ? "unlocks" : "locks"] [src]'s bolts...", \
"You [boltslocked ? "unlock" : "lock"] [src]'s floor bolts...")
- playsound(get_turf(src), 'sound/items/Screwdriver.ogg', 50, 1)
+ playsound(get_turf(src), C.usesound, 50, 1)
boltslocked = !boltslocked
return
else
@@ -81,30 +94,42 @@
if(istype(C, /obj/item/weapon/crowbar) || istype(C, /obj/item/weapon/twohanded/fireaxe))
if(istype(C, /obj/item/weapon/twohanded/fireaxe))
- var/obj/item/weapon/twohanded/fireaxe/F = C
+ var/obj/item/weapon/twohanded/fireaxe/F = C
if(!F.wielded)
return
+ user.visible_message("[user] forces \the [src] with [C].",
+ "You force \the [src] with [C].")
if(density)
open()
else
close()
-/obj/machinery/door/firedoor/attack_hand(mob/user)
- add_fingerprint(user)
- if(welded || operating || stat & NOPOWER)
+/obj/machinery/door/firedoor/attack_hand(mob/user)
+ if(operating || !density)
return
- if(density)
- open()
- else
- close()
-
+
+ add_fingerprint(user)
+ user.changeNext_move(CLICK_CD_MELEE)
+
+ if(can_force && (!glass || user.a_intent != I_HELP))
+ user.visible_message("[user] begins forcing \the [src].", \
+ "You begin forcing \the [src].")
+ if(do_after(user, force_open_time, target = src))
+ user.visible_message("[user] forces \the [src].", \
+ "You force \the [src].")
+ open()
+ else if(glass)
+ user.visible_message("[user] bangs on \the [src].",
+ "You bang on \the [src].")
+ playsound(get_turf(src), 'sound/effects/Glassknock.ogg', 10, 1)
+
/obj/machinery/door/firedoor/attack_ai(mob/user)
- attack_hand(user)
-
+ forcetoggle()
+
/obj/machinery/door/firedoor/attack_ghost(mob/user)
if(user.can_advanced_admin_interact())
- attack_hand(user)
+ forcetoggle(TRUE)
/obj/machinery/door/firedoor/attack_alien(mob/user)
add_fingerprint(user)
@@ -117,11 +142,15 @@
switch(animation)
if("opening")
flick("door_opening", src)
+ playsound(src, 'sound/machines/airlock_ext_open.ogg', 30, 1)
if("closing")
flick("door_closing", src)
+ playsound(src, 'sound/machines/airlock_ext_close.ogg', 30, 1)
/obj/machinery/door/firedoor/update_icon()
overlays.Cut()
+ if(active_alarm && !(stat & NOPOWER))
+ overlays += image('icons/obj/doors/Doorfire.dmi', "alarmlights")
if(density)
icon_state = "door_closed"
if(welded)
@@ -131,26 +160,51 @@
if(welded)
overlays += "welded_open"
-/obj/machinery/door/firedoor/open()
+/obj/machinery/door/firedoor/proc/activate_alarm()
+ active_alarm = TRUE
+ update_icon()
+
+/obj/machinery/door/firedoor/proc/deactivate_alarm()
+ active_alarm = FALSE
+ update_icon()
+
+/obj/machinery/door/firedoor/open(auto_close = TRUE)
. = ..()
- latetoggle()
+ latetoggle(auto_close)
+
+ if(auto_close)
+ autoclose = TRUE
/obj/machinery/door/firedoor/close()
. = ..()
+ if(can_crush)
+ crush()
latetoggle()
-/obj/machinery/door/firedoor/proc/latetoggle()
+/obj/machinery/door/firedoor/autoclose()
+ if(active_alarm)
+ . = ..()
+
+/obj/machinery/door/firedoor/proc/latetoggle(auto_close = TRUE)
if(operating || stat & NOPOWER || !nextstate)
return
switch(nextstate)
if(OPEN)
nextstate = null
- open()
+ open(auto_close)
if(CLOSED)
nextstate = null
close()
-
-/obj/machinery/door/firedoor/proc/deconstruct(disassembled = TRUE)
+
+/obj/machinery/door/firedoor/proc/forcetoggle(magic = FALSE, auto_close = TRUE)
+ if(!magic && (operating || stat & NOPOWER))
+ return
+ if(density)
+ open(auto_close)
+ else
+ close()
+
+/obj/machinery/door/firedoor/deconstruct(disassembled = TRUE)
if(can_deconstruct)
var/obj/structure/firelock_frame/F = new assembly_type(get_turf(src))
if(disassembled)
@@ -159,10 +213,11 @@
F.constructionStep = CONSTRUCTION_WIRES_EXPOSED
F.update_icon()
qdel(src)
-
-/obj/machinery/door/firedoor/border_only
+
+/obj/machinery/door/firedoor/border_only
icon = 'icons/obj/doors/edge_Doorfire.dmi'
flags = ON_BORDER
+ can_crush = FALSE
/obj/machinery/door/firedoor/border_only/CanPass(atom/movable/mover, turf/target, height=0)
if(istype(mover) && mover.checkpass(PASSGLASS))
@@ -189,10 +244,11 @@
/obj/machinery/door/firedoor/heavy
name = "heavy firelock"
icon = 'icons/obj/doors/Doorfire.dmi'
- glass = 0
+ glass = FALSE
opacity = 1
assembly_type = /obj/structure/firelock_frame/heavy
-
+ can_force = FALSE
+
/obj/machinery/door/firedoor/heavy/ex_act(severity)
switch(severity)
if(1.0)
@@ -205,6 +261,8 @@
desc = "A circuit board used in construction of firelocks."
w_class = 2
materials = list(MAT_METAL=50, MAT_GLASS=50)
+ toolspeed = 1
+ usesound = 'sound/items/Deconstruct.ogg'
/obj/structure/firelock_frame
name = "firelock frame"
@@ -215,7 +273,7 @@
density = 1
var/constructionStep = CONSTRUCTION_NOCIRCUIT
var/reinforced = 0
-
+
/obj/structure/firelock_frame/heavy
name = "heavy firelock frame"
reinforced = 1
@@ -242,14 +300,14 @@
switch(constructionStep)
if(CONSTRUCTION_PANEL_OPEN)
if(istype(C, /obj/item/weapon/crowbar))
- playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1)
+ playsound(get_turf(src), C.usesound, 50, 1)
user.visible_message("[user] starts prying something out from [src]...", \
"You begin prying out the wire cover...")
- if(!do_after(user, 50, target = src))
+ if(!do_after(user, 50 * C.toolspeed, target = src))
return
if(constructionStep != CONSTRUCTION_PANEL_OPEN)
return
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src), C.usesound, 50, 1)
user.visible_message("[user] pries out a metal plate from [src], exposing the wires.", \
"You remove the cover plate from [src], exposing the wires.")
constructionStep = CONSTRUCTION_WIRES_EXPOSED
@@ -259,16 +317,16 @@
if(locate(/obj/machinery/door/firedoor) in get_turf(src))
to_chat(user, "There's already a firelock there.")
return
- playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(get_turf(src), C.usesound, 50, 1)
user.visible_message("[user] starts bolting down [src]...", \
"You begin bolting [src]...")
- if(!do_after(user, 30, target = src))
+ if(!do_after(user, 30 * C.toolspeed, target = src))
return
if(locate(/obj/machinery/door/firedoor) in get_turf(src))
return
user.visible_message("[user] finishes the firelock.", \
"You finish the firelock.")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src), C.usesound, 50, 1)
if(reinforced)
new /obj/machinery/door/firedoor/heavy(get_turf(src))
else
@@ -285,23 +343,23 @@
return
user.visible_message("[user] begins reinforcing [src]...", \
"You begin reinforcing [src]...")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
- if(do_after(user, 60, target = src))
+ playsound(get_turf(src), C.usesound, 50, 1)
+ if(do_after(user, 60 * C.toolspeed, target = src))
if(constructionStep != CONSTRUCTION_PANEL_OPEN || reinforced || P.get_amount() < 2 || !P)
return
user.visible_message("[user] reinforces [src].", \
"You reinforce [src].")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src), C.usesound, 50, 1)
P.use(2)
reinforced = 1
return
if(CONSTRUCTION_WIRES_EXPOSED)
if(istype(C, /obj/item/weapon/wirecutters))
- playsound(get_turf(src), 'sound/items/Wirecutter.ogg', 50, 1)
+ playsound(get_turf(src), C.usesound, 50, 1)
user.visible_message("[user] starts cutting the wires from [src]...", \
"You begin removing [src]'s wires...")
- if(!do_after(user, 60, target = src))
+ if(!do_after(user, 60 * C.toolspeed, target = src))
return
if(constructionStep != CONSTRUCTION_WIRES_EXPOSED)
return
@@ -315,14 +373,14 @@
if(istype(C, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/W = C
if(W.remove_fuel(1, user))
- playsound(get_turf(src), 'sound/items/Welder2.ogg', 50, 1)
+ playsound(get_turf(src), C.usesound, 50, 1)
user.visible_message("[user] starts welding a metal plate into [src]...", \
"You begin welding the cover plate back onto [src]...")
- if(!do_after(user, 80, target = src))
+ if(!do_after(user, 80 * C.toolspeed, target = src))
return
if(constructionStep != CONSTRUCTION_WIRES_EXPOSED)
return
- playsound(get_turf(src), 'sound/items/Welder2.ogg', 50, 1)
+ playsound(get_turf(src), C.usesound, 50, 1)
user.visible_message("[user] welds the metal plate into [src].", \
"You weld [src]'s cover plate into place, hiding the wires.")
constructionStep = CONSTRUCTION_PANEL_OPEN
@@ -332,15 +390,15 @@
if(istype(C, /obj/item/weapon/crowbar))
user.visible_message("[user] begins removing the circuit board from [src]...", \
"You begin prying out the circuit board from [src]...")
- playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1)
- if(!do_after(user, 50, target = src))
+ playsound(get_turf(src), C.usesound, 50, 1)
+ if(!do_after(user, 50 * C.toolspeed, target = src))
return
if(constructionStep != CONSTRUCTION_GUTTED)
return
user.visible_message("[user] removes [src]'s circuit board.", \
"You remove the circuit board from [src].")
new /obj/item/weapon/firelock_electronics(get_turf(src))
- playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1)
+ playsound(get_turf(src), C.usesound, 50, 1)
constructionStep = CONSTRUCTION_NOCIRCUIT
update_icon()
return
@@ -351,13 +409,13 @@
return
user.visible_message("[user] begins wiring [src]...", \
"You begin adding wires to [src]...")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
- if(do_after(user, 60, target = src))
+ playsound(get_turf(src), B.usesound, 50, 1)
+ if(do_after(user, 60 * B.toolspeed, target = src))
if(constructionStep != CONSTRUCTION_GUTTED || B.get_amount() < 5 || !B)
return
user.visible_message("[user] adds wires to [src].", \
"You wire [src].")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src), B.usesound, 50, 1)
B.use(5)
constructionStep = CONSTRUCTION_WIRES_EXPOSED
update_icon()
@@ -366,16 +424,16 @@
if(istype(C, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/W = C
if(W.remove_fuel(1,user))
- playsound(get_turf(src), 'sound/items/Welder2.ogg', 50, 1)
+ playsound(get_turf(src), W.usesound, 50, 1)
user.visible_message("[user] begins cutting apart [src]'s frame...", \
"You begin slicing [src] apart...")
- if(!do_after(user, 80, target = src))
+ if(!do_after(user, 80 * W.toolspeed, target = src))
return
if(constructionStep != CONSTRUCTION_NOCIRCUIT)
return
user.visible_message("[user] cuts apart [src]!", \
"You cut [src] into metal.")
- playsound(get_turf(src), 'sound/items/Welder2.ogg', 50, 1)
+ playsound(get_turf(src), W.usesound, 50, 1)
var/turf/T = get_turf(src)
new /obj/item/stack/sheet/metal(T, 3)
if(reinforced)
@@ -385,8 +443,8 @@
if(istype(C, /obj/item/weapon/firelock_electronics))
user.visible_message("[user] starts adding [C] to [src]...", \
"You begin adding a circuit board to [src]...")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
- if(!do_after(user, 40, target = src))
+ playsound(get_turf(src), C.usesound, 50, 1)
+ if(!do_after(user, 40 * C.toolspeed, target = src))
return
if(constructionStep != CONSTRUCTION_NOCIRCUIT)
return
@@ -394,8 +452,8 @@
qdel(C)
user.visible_message("[user] adds a circuit to [src].", \
"You insert and secure [C].")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src), C.usesound, 50, 1)
constructionStep = CONSTRUCTION_GUTTED
update_icon()
return
- return ..()
\ No newline at end of file
+ return ..()
diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm
index de3c4514bb5..1f83484ae70 100644
--- a/code/game/machinery/doors/poddoor.dm
+++ b/code/game/machinery/doors/poddoor.dm
@@ -3,8 +3,9 @@
desc = "That looks like it doesn't open easily."
icon = 'icons/obj/doors/rapid_pdoor.dmi'
icon_state = "pdoor1"
- var/id_tag = 1.0
explosion_block = 3
+ heat_proof = 1
+ var/id_tag = 1.0
var/protected = 1
/obj/machinery/door/poddoor/preopen
@@ -46,25 +47,25 @@
src.add_fingerprint(user)
if(!( istype(C, /obj/item/weapon/crowbar) || (istype(C, /obj/item/weapon/twohanded/fireaxe) && C:wielded == 1) ))
return
- if((src.density && (stat & NOPOWER) && !( src.operating )))
+ if((src.density && (stat & NOPOWER) && !operating))
spawn( 0 )
- src.operating = 1
+ operating = 1
flick("pdoorc0", src)
src.icon_state = "pdoor0"
src.set_opacity(0)
sleep(15)
src.density = 0
- src.operating = 0
+ operating = 0
return
return
/obj/machinery/door/poddoor/open()
- if(src.operating == 1) //doors can still open when emag-disabled
+ if(operating || emagged) //doors can still open when emag-disabled
return
if(!ticker)
return 0
- if(!src.operating) //in case of emag
- src.operating = 1
+ if(!operating) //in case of emag
+ operating = 1
flick("pdoorc0", src)
src.icon_state = "pdoor0"
src.set_opacity(0)
@@ -74,17 +75,17 @@
air_update_turf(1)
update_freelook_sight()
- if(operating == 1) //emag again
- src.operating = 0
+ if(operating) //emag again
+ operating = 0
if(autoclose)
spawn(150)
autoclose()
return 1
/obj/machinery/door/poddoor/close()
- if(src.operating)
+ if(operating)
return
- src.operating = 1
+ operating = 1
flick("pdoorc1", src)
src.icon_state = "pdoor1"
src.set_opacity(initial(opacity))
@@ -95,7 +96,7 @@
src.density = 1
sleep(5)
- src.operating = 0
+ operating = 0
return
/obj/machinery/door/poddoor/multi_tile // Whoever wrote the old code for multi-tile spesspod doors needs to burn in hell.
diff --git a/code/game/machinery/doors/shutters.dm b/code/game/machinery/doors/shutters.dm
index 5375e9fe084..08f67863760 100644
--- a/code/game/machinery/doors/shutters.dm
+++ b/code/game/machinery/doors/shutters.dm
@@ -30,7 +30,7 @@
return
/obj/machinery/door/poddoor/shutters/open()
- if(operating == 1) //doors can still open when emag-disabled
+ if(operating || emagged) //doors can still open when emag-disabled
return
if(!ticker)
return 0
@@ -44,7 +44,7 @@
air_update_turf(1)
update_freelook_sight()
- if(operating == 1) //emag again
+ if(operating) //emag again
operating = 0
if(autoclose)
spawn(150)
diff --git a/code/game/machinery/doors/unpowered.dm b/code/game/machinery/doors/unpowered.dm
index 90e71dc7b83..a8236f0817c 100644
--- a/code/game/machinery/doors/unpowered.dm
+++ b/code/game/machinery/doors/unpowered.dm
@@ -3,20 +3,18 @@
var/locked = 0
explosion_block = 1
- Bumped(atom/AM)
- if(src.locked)
- return
- ..()
+/obj/machinery/door/unpowered/Bumped(atom/AM)
+ if(locked)
return
+ ..()
- attackby(obj/item/I as obj, mob/user as mob, params)
- if(istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade)) return
- if(src.locked) return
- ..()
+/obj/machinery/door/unpowered/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/weapon/card/emag) || istype(I, /obj/item/weapon/melee/energy/blade))
return
-
-
+ if(locked)
+ return
+ return ..()
/obj/machinery/door/unpowered/shuttle
icon = 'icons/turf/shuttle.dmi'
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index 74a65f1a93d..2cd5f0a7a34 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -25,9 +25,7 @@
density = 0
if(health == 0)
playsound(src, "shatter", 70, 1)
- if(electronics)
- qdel(electronics)
- electronics = null
+ QDEL_NULL(electronics)
return ..()
@@ -97,7 +95,7 @@
return 1
/obj/machinery/door/window/open(var/forced=0)
- if(operating == 1) //doors can still open when emag-disabled
+ if(operating) //doors can still open when emag-disabled
return 0
if(!ticker)
return 0
@@ -119,7 +117,7 @@
air_update_turf(1)
update_freelook_sight()
- if(operating == 1) //emag again
+ if(operating) //emag again
operating = 0
return 1
@@ -192,7 +190,7 @@
/obj/machinery/door/window/attack_ai(mob/user)
return attack_hand(user)
-
+
/obj/machinery/door/window/attack_ghost(mob/user)
if(user.can_advanced_admin_interact())
return attack_hand(user)
@@ -227,18 +225,20 @@
/obj/machinery/door/window/attack_hand(mob/user as mob)
return attackby(user, user)
-/obj/machinery/door/window/emag_act(user as mob, weapon as obj)
- if(density)
- operating = -1
+/obj/machinery/door/window/emag_act(mob/user, obj/weapon)
+ if(!operating && density && !emagged)
+ operating = 1
flick("[base_state]spark", src)
sleep(6)
+ operating = 0
desc += " Its access panel is smoking slightly."
if(istype(weapon, /obj/item/weapon/melee/energy/blade))
+ var/obj/item/weapon/melee/energy/blade/B
var/datum/effect/system/spark_spread/spark_system = new /datum/effect/system/spark_spread()
spark_system.set_up(5, 0, loc)
spark_system.start()
playsound(loc, "sparks", 50, 1)
- playsound(loc, 'sound/weapons/blade1.ogg', 50, 1)
+ playsound(loc, B.usesound, 50, 1)
visible_message(" The glass door was sliced open by [user]!")
open(2)
emagged = 1
@@ -264,17 +264,17 @@
if(density || operating)
to_chat(user, "You need to open the door to access the maintenance panel.")
return
- playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1)
+ playsound(loc, I.usesound, 50, 1)
p_open = !( p_open )
to_chat(user, "You [p_open ? "open":"close"] the maintenance panel of the [name].")
return
if(istype(I, /obj/item/weapon/crowbar))
if(p_open && !density && !operating)
- playsound(loc, 'sound/items/Crowbar.ogg', 100, 1)
+ playsound(loc, I.usesound, 100, 1)
user.visible_message("[user] removes the electronics from the [name].", \
"You start to remove electronics from the [name].")
- if(do_after(user,40, target = src))
+ if(do_after(user, 40 * I.toolspeed, target = src))
if(p_open && !density && !operating && loc)
var/obj/structure/windoor_assembly/WA = new /obj/structure/windoor_assembly(loc)
switch(base_state)
diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm
index 777c2c1bfd5..a54cf0d7e74 100644
--- a/code/game/machinery/doppler_array.dm
+++ b/code/game/machinery/doppler_array.dm
@@ -20,7 +20,7 @@ var/list/doppler_arrays = list()
/obj/machinery/doppler_array/process()
return PROCESS_KILL
-/obj/machinery/doppler_array/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
+/obj/machinery/doppler_array/attackby(var/obj/item/O, var/mob/user, params)
if(istype(O, /obj/item/weapon/wrench))
if(!anchored && !isinspace())
anchored = 1
@@ -30,7 +30,7 @@ var/list/doppler_arrays = list()
anchored = 0
power_change()
to_chat(user, "You unfasten [src].")
- playsound(loc, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(loc, O.usesound, 50, 1)
/obj/machinery/doppler_array/verb/rotate()
set name = "Rotate Tachyon-doppler Dish"
diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm
index 3e77a7548b3..586b45f0a13 100644
--- a/code/game/machinery/firealarm.dm
+++ b/code/game/machinery/firealarm.dm
@@ -44,7 +44,7 @@ FIRE ALARM
icon_state = "firex"
else if(stat & NOPOWER)
icon_state = "firep"
- else if(!src.detecting)
+ else if(!detecting)
icon_state = "fire1"
else
icon_state = "fire0"
@@ -61,15 +61,15 @@ FIRE ALARM
if(!emagged && detecting && temperature > T0C + 200)
alarm() // added check of detector status here
-/obj/machinery/firealarm/attack_ai(mob/user as mob)
- src.add_hiddenprint(user)
- return src.attack_hand(user)
+/obj/machinery/firealarm/attack_ai(mob/user)
+ add_hiddenprint(user)
+ return attack_hand(user)
-/obj/machinery/firealarm/attack_ghost(mob/user as mob)
- return src.attack_hand(user)
+/obj/machinery/firealarm/attack_ghost(mob/user)
+ ui_interact(user)
/obj/machinery/firealarm/bullet_act(BLAH)
- return src.alarm()
+ return alarm()
/obj/machinery/firealarm/emp_act(severity)
@@ -77,8 +77,8 @@ FIRE ALARM
alarm(rand(30/severity, 60/severity))
..()
-/obj/machinery/firealarm/attackby(obj/item/W as obj, mob/user as mob, params)
- src.add_fingerprint(user)
+/obj/machinery/firealarm/attackby(obj/item/W, mob/user, params)
+ add_fingerprint(user)
if(istype(W, /obj/item/weapon/screwdriver) && buildstage == 2)
wiresexposed = !wiresexposed
@@ -91,13 +91,13 @@ FIRE ALARM
if(istype(W, /obj/item/device/multitool))
detecting = !detecting
if(detecting)
- user.visible_message("\red [user] has reconnected [src]'s detecting unit!", "You have reconnected [src]'s detecting unit.")
+ user.visible_message("[user] has reconnected [src]'s detecting unit!", "You have reconnected [src]'s detecting unit.")
else
- user.visible_message("\red [user] has disconnected [src]'s detecting unit!", "You have disconnected [src]'s detecting unit.")
+ user.visible_message("[user] has disconnected [src]'s detecting unit!", "You have disconnected [src]'s detecting unit.")
else if(istype(W, /obj/item/weapon/wirecutters)) // cutting the wires out
to_chat(user, "You cut the wires!")
- playsound(src.loc, 'sound/items/Wirecutter.ogg', 50, 1)
+ playsound(loc, W.usesound, 50, 1)
var/obj/item/stack/cable_coil/new_coil = new /obj/item/stack/cable_coil()
new_coil.amount = 5
new_coil.loc = user.loc
@@ -111,17 +111,18 @@ FIRE ALARM
return
buildstage = 2
+ playsound(get_turf(src), W.usesound, 50, 1)
to_chat(user, "You wire \the [src]!")
update_icon()
else if(istype(W, /obj/item/weapon/crowbar))
to_chat(user, "You pry out the circuit!")
- playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1)
- if(do_after(user, 20, target = src))
+ playsound(get_turf(src), W.usesound, 50, 1)
+ if(do_after(user, 20 * W.toolspeed, target = src))
if(buildstage != 1)
return
var/obj/item/weapon/firealarm_electronics/circuit = new /obj/item/weapon/firealarm_electronics()
- circuit.loc = user.loc
+ circuit.forceMove(get_turf(src))
buildstage = 0
update_icon()
if(0)
@@ -134,7 +135,7 @@ FIRE ALARM
else if(istype(W, /obj/item/weapon/wrench))
to_chat(user, "You remove the fire alarm assembly from the wall!")
new /obj/item/mounted/frame/firealarm(get_turf(user))
- playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(get_turf(src), W.usesound, 50, 1)
qdel(src)
return
@@ -164,7 +165,7 @@ FIRE ALARM
stat |= NOPOWER
update_icon()
-/obj/machinery/firealarm/attack_hand(mob/user as mob)
+/obj/machinery/firealarm/attack_hand(mob/user)
if(stat & (NOPOWER|BROKEN) || buildstage != 2)
return 1
@@ -220,10 +221,10 @@ FIRE ALARM
else if(href_list["tp"])
var/tp = text2num(href_list["tp"])
time += tp
- time = min(max(round(src.time), 0), 120)
+ time = min(max(round(time), 0), 120)
/obj/machinery/firealarm/proc/reset()
- if(!( src.working ))
+ if(!( working ))
return
var/area/A = get_area(src)
A.fire_reset()
@@ -232,23 +233,23 @@ FIRE ALARM
return
/obj/machinery/firealarm/proc/alarm(var/duration = 0)
- if(!( src.working))
+ if(!( working))
return
var/area/A = get_area(src)
for(var/obj/machinery/firealarm/FA in A)
fire_alarm.triggerAlarm(loc, FA, duration)
update_icon()
- //playsound(src.loc, 'sound/ambience/signal.ogg', 75, 0)
+ //playsound(loc, 'sound/ambience/signal.ogg', 75, 0)
return
-/obj/machinery/firealarm/New(loc, dir, building)
+/obj/machinery/firealarm/New(location, direction, building)
..()
- if(loc)
- src.loc = loc
+ if(location)
+ loc = location
- if(dir)
- src.dir = dir
+ if(direction)
+ dir = direction
if(building)
buildstage = 0
@@ -256,11 +257,11 @@ FIRE ALARM
pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24)
pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0
- if(is_station_contact(src.z))
+ if(is_station_contact(z))
if(security_level)
- src.overlays += image('icons/obj/monitors.dmi', "overlay_[get_security_level()]")
+ overlays += image('icons/obj/monitors.dmi', "overlay_[get_security_level()]")
else
- src.overlays += image('icons/obj/monitors.dmi', "overlay_green")
+ overlays += image('icons/obj/monitors.dmi', "overlay_green")
update_icon()
@@ -275,6 +276,8 @@ Just a object used in constructing fire alarms
desc = "A circuit. It has a label on it, it says \"Can handle heat levels up to 40 degrees celsius!\""
w_class = 2
materials = list(MAT_METAL=50, MAT_GLASS=50)
+ toolspeed = 1
+ usesound = 'sound/items/Deconstruct.ogg'
/obj/machinery/partyalarm
name = "\improper PARTY BUTTON"
@@ -299,7 +302,7 @@ Just a object used in constructing fire alarms
return
master_area=A
-/obj/machinery/partyalarm/attack_hand(mob/user as mob)
+/obj/machinery/partyalarm/attack_hand(mob/user)
if((user.stat && !isobserver(user)) || stat & (NOPOWER|BROKEN))
return
diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm
index 2cf45577183..1b685f50197 100644
--- a/code/game/machinery/flasher.dm
+++ b/code/game/machinery/flasher.dm
@@ -43,9 +43,9 @@
add_fingerprint(user)
disable = !disable
if(disable)
- user.visible_message("\red [user] has disconnected the [src]'s flashbulb!", "\red You disconnect the [src]'s flashbulb!")
+ user.visible_message("[user] has disconnected the [src]'s flashbulb!", "You disconnect the [src]'s flashbulb!")
if(!disable)
- user.visible_message("\red [user] has connected the [src]'s flashbulb!", "\red You connect the [src]'s flashbulb!")
+ user.visible_message("[user] has connected the [src]'s flashbulb!", "You connect the [src]'s flashbulb!")
//Let the AI trigger them directly.
/obj/machinery/flasher/attack_ai(mob/user)
@@ -101,11 +101,11 @@
anchored = !anchored
if(!anchored)
- user.show_message(text("\red [src] can now be moved."))
+ user.show_message(text("[src] can now be moved."))
overlays.Cut()
else if(anchored)
- user.show_message(text("\red [src] is now secured."))
+ user.show_message(text("[src] is now secured."))
overlays += "[base_state]-s"
// Flasher button
diff --git a/code/game/machinery/floodlight.dm b/code/game/machinery/floodlight.dm
index cee7706d256..f872fbcef2d 100644
--- a/code/game/machinery/floodlight.dm
+++ b/code/game/machinery/floodlight.dm
@@ -20,9 +20,7 @@
..()
/obj/machinery/floodlight/Destroy()
- if(cell)
- qdel(cell)
- cell = null
+ QDEL_NULL(cell)
return ..()
/obj/machinery/floodlight/proc/updateicon()
@@ -59,7 +57,7 @@
if(on)
on = 0
- to_chat(user, "\blue You turn off the light")
+ to_chat(user, "You turn off the light")
set_light(0)
else
if(!cell)
@@ -67,7 +65,7 @@
if(cell.charge <= 0)
return
on = 1
- to_chat(user, "\blue You turn on the light")
+ to_chat(user, "You turn on the light")
set_light(brightness_on)
updateicon()
@@ -76,14 +74,14 @@
/obj/machinery/floodlight/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/weapon/wrench))
if(!anchored && !isinspace())
- playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(src.loc, W.usesound, 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)
+ playsound(src.loc, W.usesound, 50, 1)
user.visible_message( \
"[user] loosens \the [src]'s casters.", \
" You have loosened \the [src]'s casters.", \
diff --git a/code/game/machinery/guestpass.dm b/code/game/machinery/guestpass.dm
index e3f0abad69a..bc70868cf8f 100644
--- a/code/game/machinery/guestpass.dm
+++ b/code/game/machinery/guestpass.dm
@@ -182,7 +182,7 @@
pass.reason = reason
pass.name = "guest pass #[number]"
else
- to_chat(usr, "\red Cannot issue pass without issuing ID.")
+ to_chat(usr, "Cannot issue pass without issuing ID.")
updateUsrDialog()
return
diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm
index 7cb51574a60..219f1613d99 100755
--- a/code/game/machinery/igniter.dm
+++ b/code/game/machinery/igniter.dm
@@ -74,10 +74,10 @@
add_fingerprint(user)
src.disable = !src.disable
if(src.disable)
- user.visible_message("\red [user] has disabled the [src]!", "\red You disable the connection to the [src].")
+ user.visible_message("[user] has disabled the [src]!", "You disable the connection to the [src].")
icon_state = "[base_state]-d"
if(!src.disable)
- user.visible_message("\red [user] has reconnected the [src]!", "\red You fix the connection to the [src].")
+ user.visible_message("[user] has reconnected the [src]!", "You fix the connection to the [src].")
if(src.powered())
icon_state = "[base_state]"
else
diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm
index 9e4e8d5745c..26785e248b1 100644
--- a/code/game/machinery/iv_drip.dm
+++ b/code/game/machinery/iv_drip.dm
@@ -3,7 +3,6 @@
icon = 'icons/obj/iv_drip.dmi'
icon_state = "iv_drip"
anchored = 0
- density = 1
var/mob/living/carbon/human/attached = null
var/mode = 1 // 1 is injecting, 0 is taking blood.
var/obj/item/weapon/reagent_containers/beaker = null
@@ -16,9 +15,7 @@
/obj/machinery/iv_drip/Destroy()
attached = null
- if(beaker)
- qdel(beaker)
- beaker = null
+ QDEL_NULL(beaker)
return ..()
/obj/machinery/iv_drip/update_icon()
diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm
index 330fc5e1104..644b5a73ab9 100644
--- a/code/game/machinery/lightswitch.dm
+++ b/code/game/machinery/lightswitch.dm
@@ -152,8 +152,8 @@
return 1
if(istype(W, /obj/item/weapon/wrench))
- playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
- if(do_after(user, 30, target = src))
+ playsound(get_turf(src), W.usesound, 50, 1)
+ if(do_after(user, 30 * W.toolspeed, target = src))
to_chat(user, "You detach \the [src] from the wall.")
new/obj/item/mounted/frame/light_switch(get_turf(src))
qdel(src)
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index e62e54a3a78..514b5459973 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -260,13 +260,13 @@ Class Procs:
if(!O)
return 1
if(!canLink(O))
- to_chat(usr, "\red You can't link with that device.")
+ to_chat(usr, "You can't link with that device.")
return 1
if(unlinkFrom(usr, O))
- to_chat(usr, "\blue A green light flashes on \the [P], confirming the link was removed.")
+ to_chat(usr, "A green light flashes on \the [P], confirming the link was removed.")
else
- to_chat(usr, "\red A red light flashes on \the [P]. It appears something went wrong when unlinking the two devices.")
+ to_chat(usr, "A red light flashes on \the [P]. It appears something went wrong when unlinking the two devices.")
update_mt_menu=1
if("link" in href_list)
@@ -274,25 +274,25 @@ Class Procs:
if(!O)
return 1
if(!canLink(O,href_list))
- to_chat(usr, "\red You can't link with that device.")
+ to_chat(usr, "You can't link with that device.")
return 1
if(isLinkedWith(O))
- to_chat(usr, "\red A red light flashes on \the [P]. The two devices are already linked.")
+ to_chat(usr, "A red light flashes on \the [P]. The two devices are already linked.")
return 1
if(linkWith(usr, O, href_list))
- to_chat(usr, "\blue A green light flashes on \the [P], confirming the link was added.")
+ to_chat(usr, "A green light flashes on \the [P], confirming the link was added.")
else
- to_chat(usr, "\red A red light flashes on \the [P]. It appears something went wrong when linking the two devices.")
+ to_chat(usr, "A red light flashes on \the [P]. It appears something went wrong when linking the two devices.")
update_mt_menu=1
if("buffer" in href_list)
P.buffer = src
- to_chat(usr, "\blue A green light flashes, and the device appears in the multitool buffer.")
+ to_chat(usr, "A green light flashes, and the device appears in the multitool buffer.")
update_mt_menu=1
if("flush" in href_list)
- to_chat(usr, "\blue A green light flashes, and the device disappears from the multitool buffer.")
+ to_chat(usr, "A green light flashes, and the device disappears from the multitool buffer.")
P.buffer = null
update_mt_menu=1
@@ -395,16 +395,19 @@ Class Procs:
/obj/machinery/proc/default_deconstruction_crowbar(var/obj/item/weapon/crowbar/C, var/ignore_panel = 0)
if(istype(C) && (panel_open || ignore_panel))
- playsound(loc, 'sound/items/Crowbar.ogg', 50, 1)
- spawn_frame()
- for(var/obj/item/I in component_parts)
- if(I.reliability != 100 && crit_fail)
- I.crit_fail = 1
- I.forceMove(loc)
- qdel(src)
+ playsound(loc, C.usesound, 50, 1)
+ deconstruct()
return 1
return 0
+/obj/machinery/proc/deconstruct(disassembled = TRUE)
+ on_deconstruction()
+ spawn_frame()
+ for(var/obj/item/I in component_parts)
+ if(I.reliability != 100 && crit_fail)
+ I.crit_fail = 1
+ I.forceMove(loc)
+ qdel(src)
/obj/machinery/proc/spawn_frame()
var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(loc)
@@ -413,7 +416,7 @@ Class Procs:
/obj/machinery/proc/default_deconstruction_screwdriver(var/mob/user, var/icon_state_open, var/icon_state_closed, var/obj/item/weapon/screwdriver/S)
if(istype(S))
- playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1)
+ playsound(loc, S.usesound, 50, 1)
if(!panel_open)
panel_open = 1
icon_state = icon_state_open
@@ -427,7 +430,7 @@ Class Procs:
/obj/machinery/proc/default_change_direction_wrench(var/mob/user, var/obj/item/weapon/wrench/W)
if(panel_open && istype(W))
- playsound(loc, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(loc, W.usesound, 50, 1)
dir = turn(dir,-90)
to_chat(user, "You rotate [src].")
return 1
@@ -436,14 +439,14 @@ Class Procs:
/obj/proc/default_unfasten_wrench(mob/user, obj/item/weapon/wrench/W, time = 20)
if(istype(W))
to_chat(user, "Now [anchored ? "un" : ""]securing [name].")
- playsound(loc, 'sound/items/Ratchet.ogg', 50, 1)
- if(do_after(user, time, target = src))
+ playsound(loc, W.usesound, 50, 1)
+ if(do_after(user, time * W.toolspeed, target = src))
to_chat(user, "You've [anchored ? "un" : ""]secured [name].")
anchored = !anchored
if(istype(src, /obj/machinery))
var/obj/machinery/M = src
M.power_change() //Turn on or off the machine depending on the status of power in the new area.
- playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(loc, W.usesound, 50, 1)
return 1
return 0
@@ -490,18 +493,6 @@ Class Procs:
if(user.research_scanner && component_parts)
display_parts(user)
-/obj/machinery/proc/dismantle()
- playsound(loc, 'sound/items/Crowbar.ogg', 50, 1)
- var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(loc)
- M.state = 2
- M.icon_state = "box_1"
- for(var/obj/I in component_parts)
- if(I.reliability != 100 && crit_fail)
- I.crit_fail = 1
- I.loc = loc
- qdel(src)
- return 1
-
/obj/machinery/proc/on_assess_perp(mob/living/carbon/human/perp)
return 0
@@ -573,19 +564,20 @@ Class Procs:
return 0
//called on machinery construction (i.e from frame to machinery) but not on initialization
-/obj/machinery/proc/construction()
+/obj/machinery/proc/on_construction()
+ return
+
+/obj/machinery/proc/on_deconstruction()
return
/obj/machinery/proc/can_be_overridden()
. = 1
-/obj/machinery/tesla_act(var/power)
+/obj/machinery/tesla_act(power, explosive = FALSE)
..()
- if(prob(85))
- emp_act(2)
+ if(prob(85) && explosive)
+ explosion(loc, 1, 2, 4, flame_range = 2, adminlog = 0, smoke = 0)
else if(prob(50))
- ex_act(3)
- else if(prob(90))
- ex_act(2)
+ emp_act(2)
else
- ex_act(1)
+ ex_act(2)
diff --git a/code/game/machinery/mass_driver.dm b/code/game/machinery/mass_driver.dm
index 7953f738a40..1d5f4e8cba8 100644
--- a/code/game/machinery/mass_driver.dm
+++ b/code/game/machinery/mass_driver.dm
@@ -22,8 +22,8 @@
if(istype(W, /obj/item/weapon/screwdriver))
to_chat(user, "You begin to unscrew the bolts off the [src]...")
- playsound(get_turf(src), 'sound/items/Screwdriver.ogg', 50, 1)
- if(do_after(user, 30, target = src))
+ playsound(get_turf(src), W.usesound, 50, 1)
+ if(do_after(user, 30 * W.toolspeed, target = src))
var/obj/machinery/mass_driver_frame/F = new(get_turf(src))
F.dir = src.dir
F.anchored = 1
@@ -106,17 +106,17 @@
if(!WT.remove_fuel(0, user))
to_chat(user, "The welding tool must be on to complete this task.")
return 1
- playsound(get_turf(src), 'sound/items/Welder.ogg', 50, 1)
+ playsound(get_turf(src), WT.usesound, 50, 1)
to_chat(user, "You begin to cut the frame apart...")
- if(do_after(user, 30, target = src) && (build == 0))
+ if(do_after(user, 30 * WT.toolspeed, target = src) && (build == 0))
to_chat(user, "You detach the plasteel sheets from each others.")
new /obj/item/stack/sheet/plasteel(get_turf(src),3)
qdel(src)
return 1
if(istype(W, /obj/item/weapon/wrench))
to_chat(user, "You begin to anchor \the [src] on the floor.")
- playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
- if(do_after(user, 10, target = src) && (build == 0))
+ playsound(get_turf(src), W.usesound, 50, 1)
+ if(do_after(user, 10 * W.toolspeed, target = src) && (build == 0))
to_chat(user, "You anchor \the [src]!")
anchored = 1
build++
@@ -125,8 +125,8 @@
if(1) // Fixed to the floor
if(istype(W, /obj/item/weapon/wrench))
to_chat(user, "You begin to de-anchor \the [src] from the floor.")
- playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
- if(do_after(user, 10, target = src) && (build == 1))
+ playsound(get_turf(src), W.usesound, 50, 1)
+ if(do_after(user, 10 * W.toolspeed, target = src) && (build == 1))
build--
update_icon()
anchored = 0
@@ -137,9 +137,9 @@
if(!WT.remove_fuel(0, user))
to_chat(user, "The welding tool must be on to complete this task.")
return 1
- playsound(get_turf(src), 'sound/items/Welder.ogg', 50, 1)
+ playsound(get_turf(src), WT.usesound, 50, 1)
to_chat(user, "You begin to weld \the [src] to the floor...")
- if(do_after(user, 40, target = src) && (build == 1))
+ if(do_after(user, 40 * WT.toolspeed, target = src) && (build == 1))
to_chat(user, "You welded \the [src] to the floor.")
build++
update_icon()
@@ -150,17 +150,17 @@
if(!WT.remove_fuel(0, user))
to_chat(user, "The welding tool must be on to complete this task.")
return 1
- playsound(get_turf(src), 'sound/items/Welder.ogg', 50, 1)
+ playsound(get_turf(src), WT.usesound, 50, 1)
to_chat(user, "You begin to unweld \the [src] to the floor...")
- if(do_after(user, 40, target = src) && (build == 2))
+ if(do_after(user, 40 * WT.toolspeed, target = src) && (build == 2))
to_chat(user, "You unwelded \the [src] to the floor.")
build--
update_icon()
if(istype(W, /obj/item/stack/cable_coil))
- var/obj/item/stack/cable_coil/C=W
+ var/obj/item/stack/cable_coil/C = W
to_chat(user, "You start adding cables to \the [src]...")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
- if(do_after(user, 20, target = src) && (C.amount >= 3) && (build == 2))
+ playsound(get_turf(src), C.usesound, 50, 1)
+ if(do_after(user, 20 * C.toolspeed, target = src) && (C.amount >= 3) && (build == 2))
C.use(3)
to_chat(user, "You've added cables to \the [src].")
build++
@@ -168,18 +168,18 @@
if(3) // Wired
if(istype(W, /obj/item/weapon/wirecutters))
to_chat(user, "You begin to remove the wiring from \the [src].")
- if(do_after(user, 10, target = src) && (build == 3))
+ if(do_after(user, 10 * W.toolspeed, target = src) && (build == 3))
new /obj/item/stack/cable_coil(loc,3)
- playsound(get_turf(src), 'sound/items/Wirecutter.ogg', 50, 1)
+ playsound(get_turf(src), W.usesound, 50, 1)
to_chat(user, "You've removed the cables from \the [src].")
build--
update_icon()
return 1
if(istype(W, /obj/item/stack/rods))
- var/obj/item/stack/rods/R=W
+ var/obj/item/stack/rods/R = W
to_chat(user, "You begin to complete \the [src]...")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
- if(do_after(user, 20, target = src) && (R.amount >= 3) && (build == 3))
+ playsound(get_turf(src), R.usesound, 50, 1)
+ if(do_after(user, 20 * R.toolspeed, target = src) && (R.amount >= 3) && (build == 3))
R.use(3)
to_chat(user, "You've added the grille to \the [src].")
build++
@@ -188,15 +188,15 @@
if(4) // Grille in place
if(istype(W, /obj/item/weapon/crowbar))
to_chat(user, "You begin to pry off the grille from \the [src]...")
- playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1)
- if(do_after(user, 30, target = src) && (build == 4))
+ playsound(get_turf(src), W.usesound, 50, 1)
+ if(do_after(user, 30 * W.toolspeed, target = src) && (build == 4))
new /obj/item/stack/rods(loc,2)
build--
update_icon()
return 1
if(istype(W, /obj/item/weapon/screwdriver))
to_chat(user, "You finalize the Mass Driver...")
- playsound(get_turf(src), 'sound/items/Screwdriver.ogg', 50, 1)
+ playsound(get_turf(src), W.usesound, 50, 1)
var/obj/machinery/mass_driver/M = new(get_turf(src))
M.dir = src.dir
qdel(src)
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index 4c14df16ec3..6040f72ab6b 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -3,28 +3,25 @@
//###-Agouri###################################
/datum/feed_message
- var/author =""
- var/body =""
- var/message_type ="Story"
- //var/parent_channel
- var/backup_body =""
- var/backup_author =""
+ var/author = ""
+ var/body = ""
+ var/message_type = "Story"
+ var/backup_body = ""
+ var/backup_author = ""
var/is_admin_message = 0
var/icon/img = null
var/icon/backup_img
var/view_count = 0
/datum/feed_channel
- var/channel_name=""
+ var/channel_name = ""
var/list/datum/feed_message/messages = list()
- //var/message_count = 0
- var/locked=0
- var/author=""
- var/backup_author=""
- var/censored=0
- var/is_admin_channel=0
+ var/locked = 0
+ var/author = ""
+ var/backup_author = ""
+ var/censored = 0
+ var/is_admin_channel = 0
var/total_view_count = 0
- //var/page = null //For newspapers
/datum/feed_message/proc/clear()
author = ""
@@ -59,468 +56,278 @@ var/datum/feed_network/news_network = new /datum/feed_network //The global n
var/list/obj/machinery/newscaster/allCasters = list() //Global list that will contain reference to all newscasters in existence.
+#define NEWSCASTER_MAIN 0 // Main menu
+#define NEWSCASTER_FC_LIST 1 // Feed channel list
+#define NEWSCASTER_CREATE_FC 2 // Create feed channel
+#define NEWSCASTER_CREATE_FM 3 // Create feed message
+#define NEWSCASTER_PRINT 4 // Print newspaper
+#define NEWSCASTER_VIEW_FC 5 // Read feed channel
+#define NEWSCASTER_NT_CENSOR 6 // Nanotrasen Feed Censorship Tool
+#define NEWSCASTER_D_NOTICE 7 // Nanotrasen D-Notice Handler
+#define NEWSCASTER_CENSOR_FC 8 // Censor feed channel
+#define NEWSCASTER_D_NOTICE_FC 9 // D-Notice feed channel
+#define NEWSCASTER_W_ISSUE_H 10 // Wanted Issue handler
+#define NEWSCASTER_W_ISSUE 11 // STATIONWIDE WANTED ISSUE
+
/obj/machinery/newscaster
name = "newscaster"
desc = "A standard Nanotrasen-licensed newsfeed handler for use in commercial space stations. All the news you absolutely have no use for, in one place!"
icon = 'icons/obj/terminals.dmi'
icon_state = "newscaster_normal"
- var/isbroken = 0 //1 if someone banged it with something heavy
- var/ispowered = 1 //starts powered, changes with power_change()
- //var/list/datum/feed_channel/channel_list = list() //This list will contain the names of the feed channels. Each name will refer to a data region where the messages of the feed channels are stored.
- //OBSOLETE: We're now using a global news network
- var/screen = 0 //Or maybe I'll make it into a list within a list afterwards... whichever I prefer, go fuck yourselves :3
- // 0 = welcome screen - main menu
- // 1 = view feed channels
- // 2 = create feed channel
- // 3 = create feed story
- // 4 = feed story submited sucessfully
- // 5 = feed channel created successfully
- // 6 = ERROR: Cannot create feed story
- // 7 = ERROR: Cannot create feed channel
- // 8 = print newspaper
- // 9 = viewing channel feeds
- // 10 = censor feed story
- // 11 = censor feed channel
- //Holy shit this is outdated, made this when I was still starting newscasters :3
- var/paper_remaining = 0
+ var/screen = NEWSCASTER_MAIN
+ var/paper_remaining = 15
var/securityCaster = 0
// 0 = Caster cannot be used to issue wanted posters
// 1 = the opposite
var/unit_no = 0 //Each newscaster has a unit number
- //var/datum/feed_message/wanted //We're gonna use a feed_message to store data of the wanted person because fields are similar
- //var/wanted_issue = 0 //OBSOLETE
- // 0 = there's no WANTED issued, we don't need a special icon_state
- // 1 = Guess what.
var/alert_delay = 500
var/alert = 0
// 0 = there hasn't been a news/wanted update in the last alert_delay
// 1 = there has
var/scanned_user = "Unknown" //Will contain the name of the person who currently uses the newscaster
- var/msg = ""; //Feed message
+ var/msg = "" //Feed message
var/obj/item/weapon/photo/photo = null
- var/channel_name = ""; //the feed channel which will be receiving the feed, or being created
- var/c_locked=0; //Will our new channel be locked to public submissions?
- var/hitstaken = 0 //Death at 3 hits from an item with force>=15
+ var/channel_name = "" //the feed channel which will be receiving the feed, or being created
+ var/c_locked = 0 //Will our new channel be locked to public submissions?
+ var/hitstaken = 0 //Death at 3 hits from an item with force>=15
var/datum/feed_channel/viewing_channel = null
var/silence = 0
+ var/temp = null
+ var/temp_back_screen = NEWSCASTER_MAIN
+
+ var/static/REDACTED = "\[REDACTED\]"
light_range = 0
anchored = 1
-/obj/machinery/newscaster/security_unit //Security unit
+/obj/machinery/newscaster/security_unit
name = "Security Newscaster"
securityCaster = 1
-/obj/machinery/newscaster/New() //Constructor, ho~
+/obj/machinery/newscaster/New()
allCasters += src
- paper_remaining = 15 // Will probably change this to something better
- for(var/obj/machinery/newscaster/NEWSCASTER in allCasters) // Let's give it an appropriate unit number
- unit_no++
+ unit_no = allCasters.len
update_icon() //for any custom ones on the map...
- ..() //I just realised the newscasters weren't in the global machines list. The superconstructor call will tend to that
+ ..()
/obj/machinery/newscaster/Destroy()
allCasters -= src
viewing_channel = null
- photo = null
+ QDEL_NULL(photo)
return ..()
/obj/machinery/newscaster/update_icon()
- if(!ispowered || isbroken)
+ overlays.Cut()
+ if(inoperable())
icon_state = "newscaster_off"
- if(isbroken) //If the thing is smashed, add crack overlay on top of the unpowered sprite.
- overlays.Cut()
+ if(stat & BROKEN) //If the thing is smashed, add crack overlay on top of the unpowered sprite.
overlays += image(icon, "crack3")
- return
+ else
+ if(!news_network.wanted_issue) //wanted icon state, there can be no overlays on it as it's a priority message
+ icon_state = "newscaster_normal"
+ if(alert) //new message alert overlay
+ overlays += "newscaster_alert"
+ else
+ icon_state = "newscaster_wanted"
- overlays.Cut() //reset overlays
-
- if(news_network.wanted_issue) //wanted icon state, there can be no overlays on it as it's a priority message
- icon_state = "newscaster_wanted"
- return
-
- if(alert) //new message alert overlay
- overlays += "newscaster_alert"
-
- if(hitstaken > 0) //Cosmetic damage overlay
- overlays += image(icon, "crack[hitstaken]")
-
- icon_state = "newscaster_normal"
- return
+ if(hitstaken > 0) //Cosmetic damage overlay
+ overlays += image(icon, "crack[hitstaken]")
/obj/machinery/newscaster/power_change()
- if(isbroken) //Broken shit can't be powered.
- return
- if( powered() )
- ispowered = 1
- stat &= ~NOPOWER
- update_icon()
- else
- spawn(rand(0, 15))
- ispowered = 0
- stat |= NOPOWER
- update_icon()
-
+ ..()
+ update_icon()
/obj/machinery/newscaster/ex_act(severity)
switch(severity)
- if(1.0)
+ if(1)
qdel(src)
return
- if(2.0)
- isbroken=1
+ if(2)
+ stat |= BROKEN
if(prob(50))
qdel(src)
else
update_icon() //can't place it above the return and outside the if-else. or we might get runtimes of null.update_icon() if(prob(50)) goes in.
- return
else
if(prob(50))
- isbroken=1
+ stat |= BROKEN
update_icon()
- return
- return
-/obj/machinery/newscaster/attack_ai(mob/user)
- return attack_hand(user)
-
/obj/machinery/newscaster/attack_ghost(mob/user)
- return attack_hand(user)
+ ui_interact(user)
-/obj/machinery/newscaster/attack_hand(mob/user) //########### THE MAIN BEEF IS HERE! And in the proc below this...############
- interact(user)
-
-/obj/machinery/newscaster/interact(mob/user)
- if(!ispowered || isbroken)
+/obj/machinery/newscaster/attack_hand(mob/user)
+ if(..())
return
+ ui_interact(user)
- if(ishuman(user) || issilicon(user) || isobserver(user))
- var/dat
- dat = text("Newscaster
"
- dat+=" Return "
- if(6)
- dat+="ERROR: Could not submit Feed story to Network. "
- if(channel_name=="")
- dat+="Invalid receiving channel name. "
- if(scanned_user=="Unknown")
- dat+="Channel author unverified. "
- if(msg == "" || msg == "\[REDACTED\]")
- dat+="Invalid message body. "
-
- dat+=" Return "
- if(7)
- dat+="ERROR: Could not submit Feed Channel to Network. "
- //var/list/existing_channels = list() //Let's get dem existing channels - OBSOLETE
- var/list/existing_authors = list()
- for(var/datum/feed_channel/FC in news_network.network_channels)
- //existing_channels += FC.channel_name //OBSOLETE
- if(FC.author == "\[REDACTED\]")
- existing_authors += FC.backup_author
- else
- existing_authors += FC.author
- if(scanned_user in existing_authors)
- dat+="There already exists a Feed channel under your name. "
- if(channel_name=="" || channel_name == "\[REDACTED\]")
- dat+="Invalid channel name. "
- var/check = 0
- for(var/datum/feed_channel/FC in news_network.network_channels)
- if(FC.channel_name == channel_name)
- check = 1
- break
- if(check)
- dat+="Channel name already in use. "
- if(scanned_user=="Unknown")
- dat+="Channel author unverified. "
- dat+=" Return "
- if(8)
- var/total_num=length(news_network.network_channels)
- var/active_num=total_num
- var/message_num=0
- for(var/datum/feed_channel/FC in news_network.network_channels)
- if(!FC.censored)
- message_num += length(FC.messages) //Dont forget, datum/feed_channel's var messages is a list of datum/feed_message
- else
- active_num--
- dat+="Network currently serves a total of [total_num] Feed channels, [active_num] of which are active, and a total of [message_num] Feed Stories." //TODO: CONTINUE
- dat+="
Liquid Paper remaining: [(paper_remaining) *100 ] cm^3"
- dat+="
Print Paper"
- dat+=" Cancel"
- if(9)
- dat+="[viewing_channel.channel_name]: \[created by: [viewing_channel.author]\] "
- dat+="Feed view count: [viewing_channel.total_view_count]"
- viewing_channel.total_view_count++
- if(viewing_channel.censored)
- dat+="ATTENTION: This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice. "
- dat+="No further feed story additions are allowed while the D-Notice is in effect.
"
- dat+="\[[MESSAGE.message_type] by [MESSAGE.author]\] "
- dat+="Message view count: [MESSAGE.view_count] "
- MESSAGE.view_count++
- dat+=" Refresh"
- dat+=" Back"
- if(10)
- dat+="Nanotrasen Feed Censorship Tool "
- dat+="NOTE: Due to the nature of news Feeds, total deletion of a Feed Story is not possible. "
- dat+="Keep in mind that users attempting to view a censored feed will instead see the \[REDACTED\] tag above it."
- dat+="Select Feed channel to get Stories from: "
- if(isemptylist(news_network.network_channels))
- dat+="No feed channels found active... "
- else
- for(var/datum/feed_channel/CHANNEL in news_network.network_channels)
- dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()] "
- dat+=" Cancel"
- if(11)
- dat+="Nanotrasen D-Notice Handler"
- dat+="A D-Notice is to be bestowed upon the channel if the handling Authority deems it as harmful for the station's"
- dat+="morale, integrity or disciplinary behaviour. A D-Notice will render a channel unable to be updated by anyone, without deleting any feed"
- dat+="stories it might contain at the time. You can lift a D-Notice if you have the required access at any time."
- if(isemptylist(news_network.network_channels))
- dat+="No feed channels found active... "
- else
- for(var/datum/feed_channel/CHANNEL in news_network.network_channels)
- dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()] "
-
- dat+=" Back"
- if(12)
- dat+="[viewing_channel.channel_name]: \[ created by: [viewing_channel.author] \] "
- dat+="[(viewing_channel.author=="\[REDACTED\]") ? ("Undo Author censorship") : ("Censor channel Author")]"
-
-
- if( isemptylist(viewing_channel.messages) )
- dat+="No feed messages found in channel... "
- else
- for(var/datum/feed_message/MESSAGE in viewing_channel.messages)
- 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)
- dat+="[viewing_channel.channel_name]: \[ created by: [viewing_channel.author] \] "
- dat+="Channel messages listed below. If you deem them dangerous to the station, you can Bestow a D-Notice upon the channel."
- if(viewing_channel.censored)
- dat+="ATTENTION: This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice. "
- dat+="No further feed story additions are allowed while the D-Notice is in effect.
"
- else
- if( isemptylist(viewing_channel.messages) )
- dat+="No feed messages found in channel... "
- else
- for(var/datum/feed_message/MESSAGE in viewing_channel.messages)
- dat+="-[MESSAGE.body] \[[MESSAGE.message_type] by [MESSAGE.author]\] "
-
- dat+=" Back"
- if(14)
- dat+="Wanted Issue Handler:"
- var/wanted_already = 0
- var/end_param = 1
- if(news_network.wanted_issue)
- wanted_already = 1
- end_param = 2
-
- if(wanted_already)
- dat+=" A wanted issue is already in Feed Circulation. You can edit or cancel it below."
- dat+=""
- dat+="Criminal Name: [channel_name] "
- dat+="Description: [msg] "
- dat+="Attach Photo: [(photo ? "Photo Attached" : "No Photo")]"
- if(wanted_already)
- dat+="Wanted Issue created by: [news_network.wanted_issue.backup_author] "
- else
- dat+="Wanted Issue will be created under prosecutor: [scanned_user] "
- dat+=" [(wanted_already) ? ("Edit Issue") : ("Submit")]"
- if(wanted_already)
- dat+=" Take down Issue"
- dat+=" Cancel"
- if(15)
- dat+="Wanted issue for [channel_name] is now in Network Circulation.
"
+ temp_back_screen = NEWSCASTER_MAIN
else
- var/choice = alert("Please confirm Wanted Issue [(input_param==1) ? ("creation.") : ("edit.")]","Network Security Handler","Confirm","Cancel")
- if(choice=="Confirm")
- if(input_param==1) //If input_param == 1 we're submitting a new wanted issue. At 2 we're just editing an existing one. See the else below
- var/datum/feed_message/WANTED = new /datum/feed_message
- WANTED.author = channel_name
- WANTED.body = msg
- WANTED.backup_author = scanned_user //I know, a bit wacky
+ var/choice = alert("Please confirm wanted issue [input_param == 1 ? "creation." : "edit."]", "Network Security Handler", "Confirm", "Cancel")
+ if(choice == "Confirm")
+ if(input_param == 1) //input_param == 1: new wanted issue, input_param == 2: editing an existing one
+ var/datum/feed_message/W = new /datum/feed_message
+ W.author = channel_name
+ W.body = msg
+ W.backup_author = scanned_user //I know, a bit wacky
if(photo)
- WANTED.img = photo.img
- news_network.wanted_issue = WANTED
- for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
- NEWSCASTER.newsAlert()
- NEWSCASTER.update_icon()
- screen = 15
+ W.img = photo.img
+ news_network.wanted_issue = W
+ for(var/obj/machinery/newscaster/NS in allCasters)
+ NS.newsAlert()
+ NS.update_icon()
+ temp = "Wanted issue for [channel_name] is now in Network Circulation."
+ temp_back_screen = NEWSCASTER_MAIN
else
if(news_network.wanted_issue.is_admin_message)
alert("The wanted issue has been distributed by a Nanotrasen higherup. You cannot edit it.","Ok")
@@ -626,154 +430,160 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
news_network.wanted_issue.backup_author = scanned_user
if(photo)
news_network.wanted_issue.img = photo.img
- screen = 19
-
- updateUsrDialog()
+ temp = "Wanted issue for [channel_name] successfully edited."
+ temp_back_screen = NEWSCASTER_MAIN
else if(href_list["cancel_wanted"])
if(news_network.wanted_issue.is_admin_message)
- alert("The wanted issue has been distributed by a Nanotrasen higherup. You cannot take it down.","Ok")
+ alert("The wanted issue has been distributed by a Nanotrasen higherup. You cannot take it down.", "Ok")
return
- var/choice = alert("Please confirm Wanted Issue removal","Network Security Handler","Confirm","Cancel")
- if(choice=="Confirm")
+ var/choice = alert("Please confirm wanted issue removal", "Network Security Handler", "Confirm", "Cancel")
+ if(choice == "Confirm")
news_network.wanted_issue = null
- for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
- NEWSCASTER.update_icon()
- screen=17
- updateUsrDialog()
+ for(var/obj/machinery/newscaster/NC in allCasters)
+ NC.update_icon()
+ temp = "Wanted Issue successfully deleted from Circulation"
+ temp_back_screen = NEWSCASTER_MAIN
else if(href_list["view_wanted"])
- screen=18
- updateUsrDialog()
+ screen = NEWSCASTER_W_ISSUE
else if(href_list["censor_channel_author"])
var/datum/feed_channel/FC = locate(href_list["censor_channel_author"])
- if(FC.is_admin_channel)
- alert("This channel was created by a Nanotrasen Officer. You cannot censor it.","Ok")
- return
- if(FC.author != "\[REDACTED\]")
- FC.backup_author = FC.author
- FC.author = "\[REDACTED\]"
- else
- FC.author = FC.backup_author
- updateUsrDialog()
+ if(FC)
+ if(FC.is_admin_channel)
+ alert("This channel was created by a Nanotrasen Officer. You cannot censor it.","Ok")
+ return
+ if(FC.author != REDACTED)
+ FC.backup_author = FC.author
+ FC.author = REDACTED
+ else
+ FC.author = FC.backup_author
else if(href_list["censor_channel_story_author"])
- var/datum/feed_message/MSG = locate(href_list["censor_channel_story_author"])
- if(MSG.is_admin_message)
- alert("This message was created by a Nanotrasen Officer. You cannot censor its author.","Ok")
- return
- if(MSG.author != "\[REDACTED\]")
- MSG.backup_author = MSG.author
- MSG.author = "\[REDACTED\]"
- else
- MSG.author = MSG.backup_author
- updateUsrDialog()
+ var/datum/feed_message/M = locate(href_list["censor_channel_story_author"])
+ if(M)
+ if(M.is_admin_message)
+ alert("This message was created by a Nanotrasen Officer. You cannot censor its author.","Ok")
+ return
+ if(M.author != REDACTED)
+ M.backup_author = M.author
+ M.author = REDACTED
+ else
+ M.author = M.backup_author
else if(href_list["censor_channel_story_body"])
- var/datum/feed_message/MSG = locate(href_list["censor_channel_story_body"])
- if(MSG.is_admin_message)
- alert("This channel was created by a Nanotrasen Officer. You cannot censor it.","Ok")
- return
- if(MSG.img != null)
- MSG.backup_img = MSG.img
- MSG.img = null
- else
- MSG.img = MSG.backup_img
- if(MSG.body != "\[REDACTED\]")
- MSG.backup_body = MSG.body
- MSG.body = "\[REDACTED\]"
- else
- MSG.body = MSG.backup_body
- updateUsrDialog()
+ var/datum/feed_message/M = locate(href_list["censor_channel_story_body"])
+ if(M)
+ if(M.is_admin_message)
+ alert("This channel was created by a Nanotrasen Officer. You cannot censor it.","Ok")
+ return
+ if(M.img != null)
+ M.backup_img = M.img
+ M.img = null
+ else
+ M.img = M.backup_img
+ if(M.body != REDACTED)
+ M.backup_body = M.body
+ M.body = REDACTED
+ else
+ M.body = M.backup_body
else if(href_list["pick_d_notice"])
var/datum/feed_channel/FC = locate(href_list["pick_d_notice"])
- viewing_channel = FC
- screen=13
- updateUsrDialog()
+ if(FC)
+ viewing_channel = FC
+ screen = NEWSCASTER_D_NOTICE_FC
else if(href_list["toggle_d_notice"])
var/datum/feed_channel/FC = locate(href_list["toggle_d_notice"])
- if(FC.is_admin_channel)
- alert("This channel was created by a Nanotrasen Officer. You cannot place a D-Notice upon it.","Ok")
- return
- FC.censored = !FC.censored
- updateUsrDialog()
+ if(FC)
+ if(FC.is_admin_channel)
+ alert("This channel was created by a Nanotrasen Officer. You cannot place a D-Notice upon it.", "Ok")
+ return
+ FC.censored = !FC.censored
else if(href_list["view"])
- screen=1
- updateUsrDialog()
+ screen = NEWSCASTER_FC_LIST
else if(href_list["setScreen"]) //Brings us to the main menu and resets all fields~
screen = text2num(href_list["setScreen"])
- if(screen == 0)
- scanned_user = "Unknown";
- msg = "";
- c_locked=0;
- channel_name="";
+ if(screen == NEWSCASTER_MAIN)
+ scanned_user = "Unknown"
+ msg = ""
+ c_locked = 0
+ channel_name = ""
viewing_channel = null
- updateUsrDialog()
+ temp = null
+ temp_back_screen = NEWSCASTER_MAIN
else if(href_list["show_channel"])
var/datum/feed_channel/FC = locate(href_list["show_channel"])
- viewing_channel = FC
- screen = 9
- updateUsrDialog()
+ if(FC)
+ viewing_channel = FC
+ viewing_channel.total_view_count++
+ for(var/datum/feed_message/M in viewing_channel.messages)
+ M.view_count++
+ screen = NEWSCASTER_VIEW_FC
else if(href_list["pick_censor_channel"])
var/datum/feed_channel/FC = locate(href_list["pick_censor_channel"])
- viewing_channel = FC
- screen = 12
- updateUsrDialog()
+ if(FC)
+ viewing_channel = FC
+ screen = NEWSCASTER_CENSOR_FC
else if(href_list["refresh"])
- updateUsrDialog()
+ if(can_scan(usr))
+ scan_user(usr) //Newscaster scans you
-/obj/machinery/newscaster/attackby(obj/item/I as obj, mob/living/user as mob, params)
+ nanomanager.update_uis(src)
+ return 1
+
+/obj/machinery/newscaster/attackby(obj/item/I, mob/living/user, params)
if(istype(I, /obj/item/weapon/wrench))
to_chat(user, "Now [anchored ? "un" : ""]securing [name]")
- playsound(loc, 'sound/items/Ratchet.ogg', 50, 1)
- if(do_after(user, 60, target = src))
+ playsound(loc, I.usesound, 50, 1)
+ if(do_after(user, 60 * I.toolspeed, target = src))
new /obj/item/mounted/frame/newscaster_frame(loc)
- playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(loc, I.usesound, 50, 1)
qdel(src)
return
- if(isbroken)
+ if(stat & BROKEN)
playsound(loc, 'sound/effects/hit_on_shattered_glass.ogg', 100, 1)
- visible_message("[user.name] further abuses the shattered [name].", null, 5 )
+ visible_message("[user.name] further abuses the shattered [name].", null, 5)
else
if(istype(I, /obj/item/weapon) )
var/obj/item/weapon/W = I
if(W.damtype == STAMINA)
return
- if(W.force <15)
- visible_message("[user.name] hits the [name] with the [W.name] with no visible effect.", null , 5 )
+ if(W.force < 15)
+ visible_message("[user.name] hits the [name] with the [W.name] with no visible effect.", null , 5)
playsound(loc, 'sound/effects/Glasshit.ogg', 100, 1)
else
hitstaken++
- if(hitstaken==3)
- visible_message("[user.name] smashes the [name]!", null, 5 )
- isbroken=1
+ if(hitstaken == 3)
+ visible_message("[user.name] smashes the [name]!", null, 5)
+ stat |= BROKEN
playsound(loc, 'sound/effects/Glassbr3.ogg', 100, 1)
else
- visible_message("[user.name] forcefully slams the [name] with the [I.name]!", null, 5 )
+ visible_message("[user.name] forcefully slams the [name] with the [I.name]!", null, 5)
playsound(loc, 'sound/effects/Glasshit.ogg', 100, 1)
else
- to_chat(user, "This does nothing.")
+ to_chat(user, "This does nothing.")
update_icon()
+ ..()
-/obj/machinery/newscaster/proc/AttachPhoto(mob/user as mob)
+/obj/machinery/newscaster/proc/AttachPhoto(mob/user)
if(photo)
if(!issilicon(user))
- photo.loc = loc
+ photo.forceMove(get_turf(src))
user.put_in_inactive_hand(photo)
photo = null
if(istype(user.get_active_hand(), /obj/item/weapon/photo))
photo = user.get_active_hand()
user.drop_item()
- photo.loc = src
- else if(istype(user,/mob/living/silicon))
+ photo.forceMove(src)
+ else if(issilicon(user))
var/mob/living/silicon/tempAI = user
var/obj/item/device/camera/siliconcam/camera = tempAI.aiCamera
@@ -960,7 +770,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
scanned_user = "[ai_user.name] ([ai_user.job])"
else
scanned_user = "Unknown"
-
+
/obj/machinery/newscaster/proc/can_scan(mob/user)
if(ishuman(user) || issilicon(user))
return TRUE
diff --git a/code/game/machinery/overview.dm b/code/game/machinery/overview.dm
index 734bb09f60b..e98c4e90c30 100644
--- a/code/game/machinery/overview.dm
+++ b/code/game/machinery/overview.dm
@@ -258,7 +258,7 @@
else
colour = rgb(255,128,128)
- //if(istype(AM, /obj/effect/blob))
+ //if(istype(AM, /obj/structure/blob))
// colour = rgb(255,0,255)
var/area/A = T.loc
diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm
index bf2eedeaf23..5bd7861623b 100644
--- a/code/game/machinery/pipe/construction.dm
+++ b/code/game/machinery/pipe/construction.dm
@@ -153,11 +153,11 @@
src.pipe_type = PIPE_OMNI_FILTER
else if(istype(make_from, /obj/machinery/atmospherics/binary/circulator))
src.pipe_type = PIPE_CIRCULATOR
-
+
var/obj/machinery/atmospherics/trinary/triP = make_from
if(istype(triP) && triP.flipped)
src.flipped = 1
-
+
var/obj/machinery/atmospherics/binary/circulator/circP = make_from
if(istype(circP) && circP.side == circP.CIRC_RIGHT)
src.flipped = 1
@@ -282,7 +282,7 @@
PIPE_INSULATED_BENT, \
PIPE_SUPPLY_BENT, \
PIPE_SCRUBBERS_BENT)
-
+
// rotate the pipe item clockwise
/obj/item/pipe/verb/rotate()
@@ -292,7 +292,7 @@
if( usr.stat || usr.restrained() )
return
-
+
if(pipe_type == PIPE_CIRCULATOR)
flip()
return
@@ -302,7 +302,7 @@
fixdir()
return
-
+
/obj/item/pipe/verb/flip()
set category = "Object"
set name = "Flip Pipe"
@@ -342,11 +342,11 @@
/obj/item/pipe/proc/get_pipe_dir()
if(!dir)
return 0
-
+
var/direct = dir
if(flipped)
- direct = turn(dir, 45)
-
+ direct = turn(dir, 45)
+
var/flip = turn(direct, 180)
var/cw = turn(direct, -90)
var/acw = turn(direct, 90)
@@ -415,7 +415,7 @@
return dir
else
return 0
-
+
/obj/item/pipe/proc/unflip(var/direction)
if(!(direction in cardinal))
return turn(direction, 45)
@@ -440,12 +440,12 @@
if(!istype(W, /obj/item/weapon/wrench))
return ..()
-
+
if(!isturf(src.loc))
return 1
fixdir()
-
+
var/pipe_dir = get_pipe_dir()
for(var/obj/machinery/atmospherics/M in src.loc)
@@ -456,79 +456,79 @@
switch(pipe_type) //What kind of heartless person thought of doing this?
if(PIPE_SIMPLE_STRAIGHT, PIPE_SIMPLE_BENT)
var/obj/machinery/atmospherics/pipe/simple/P = new( src.loc )
- P.construction(dir, pipe_dir, color)
+ P.on_construction(dir, pipe_dir, color)
if(PIPE_SUPPLY_STRAIGHT, PIPE_SUPPLY_BENT)
var/obj/machinery/atmospherics/pipe/simple/hidden/supply/P = new( src.loc )
- P.construction(dir, pipe_dir, color)
+ P.on_construction(dir, pipe_dir, color)
if(PIPE_SCRUBBERS_STRAIGHT, PIPE_SCRUBBERS_BENT)
var/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers/P = new( src.loc )
- P.construction(dir, pipe_dir, color)
+ P.on_construction(dir, pipe_dir, color)
if(PIPE_UNIVERSAL)
var/obj/machinery/atmospherics/pipe/simple/hidden/universal/P = new( src.loc )
- P.construction(dir, pipe_dir, color)
+ P.on_construction(dir, pipe_dir, color)
if(PIPE_HE_STRAIGHT, PIPE_HE_BENT)
var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/P = new ( src.loc )
P.initialize_directions_he = pipe_dir
- P.construction(dir, pipe_dir, color)
+ P.on_construction(dir, pipe_dir, color)
if(PIPE_CONNECTOR) // connector
var/obj/machinery/atmospherics/unary/portables_connector/C = new( src.loc )
if(pipename)
C.name = pipename
- C.construction(dir, pipe_dir, color)
+ C.on_construction(dir, pipe_dir, color)
if(PIPE_MANIFOLD) //manifold
var/obj/machinery/atmospherics/pipe/manifold/M = new( src.loc )
- M.construction(dir, pipe_dir, color)
+ M.on_construction(dir, pipe_dir, color)
if(PIPE_SUPPLY_MANIFOLD) //manifold
var/obj/machinery/atmospherics/pipe/manifold/hidden/supply/M = new( src.loc )
- M.construction(dir, pipe_dir, color)
+ M.on_construction(dir, pipe_dir, color)
if(PIPE_SCRUBBERS_MANIFOLD) //manifold
var/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers/M = new( src.loc )
- M.construction(dir, pipe_dir, color)
+ M.on_construction(dir, pipe_dir, color)
if(PIPE_MANIFOLD4W) //4-way manifold
var/obj/machinery/atmospherics/pipe/manifold4w/M = new( src.loc )
- M.construction(dir, pipe_dir, color)
-
+ M.on_construction(dir, pipe_dir, color)
+
if(PIPE_SUPPLY_MANIFOLD4W) //4-way manifold
var/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply/M = new( src.loc )
- M.construction(dir, pipe_dir, color)
+ M.on_construction(dir, pipe_dir, color)
if(PIPE_SCRUBBERS_MANIFOLD4W) //4-way manifold
var/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers/M = new( src.loc )
- M.construction(dir, pipe_dir, color)
+ M.on_construction(dir, pipe_dir, color)
if(PIPE_JUNCTION)
var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/P = new ( src.loc )
P.initialize_directions_he = src.get_hdir()
- P.construction(dir, get_pdir(), color)
+ P.on_construction(dir, get_pdir(), color)
if(PIPE_UVENT) //unary vent
var/obj/machinery/atmospherics/unary/vent_pump/V = new( src.loc )
- V.construction(dir, pipe_dir, color)
+ V.on_construction(dir, pipe_dir, color)
if(PIPE_MVALVE) //manual valve
var/obj/machinery/atmospherics/binary/valve/V = new( src.loc)
if(pipename)
V.name = pipename
- V.construction(dir, get_pdir(), color)
-
+ V.on_construction(dir, get_pdir(), color)
+
if(PIPE_DVALVE)
var/obj/machinery/atmospherics/binary/valve/digital/V = new( src.loc )
if(pipename)
V.name = pipename
- V.construction(dir, get_pdir(), color)
-
+ V.on_construction(dir, get_pdir(), color)
+
if(PIPE_PUMP) //gas pump
var/obj/machinery/atmospherics/binary/pump/P = new(src.loc)
- P.construction(dir, pipe_dir, color)
+ P.on_construction(dir, pipe_dir, color)
if(PIPE_GAS_FILTER, PIPE_GAS_MIXER, PIPE_TVALVE, PIPE_DTVALVE)
var/obj/machinery/atmospherics/trinary/P
@@ -544,86 +544,86 @@
P.flipped = flipped
if(pipename)
P.name = pipename
- P.construction(unflip(dir), pipe_dir, color)
-
+ P.on_construction(unflip(dir), pipe_dir, color)
+
if(PIPE_CIRCULATOR) //circulator
var/obj/machinery/atmospherics/binary/circulator/C = new(src.loc)
if(flipped)
C.side = C.CIRC_RIGHT
if(pipename)
C.name = pipename
- C.construction(C.dir, C.initialize_directions, color)
+ C.on_construction(C.dir, C.initialize_directions, color)
if(PIPE_SCRUBBER) //scrubber
var/obj/machinery/atmospherics/unary/vent_scrubber/S = new(src.loc)
if(pipename)
S.name = pipename
- S.construction(dir, pipe_dir, color)
+ S.on_construction(dir, pipe_dir, color)
if(PIPE_INSULATED_STRAIGHT, PIPE_INSULATED_BENT)
var/obj/machinery/atmospherics/pipe/simple/insulated/P = new( src.loc )
- P.construction(dir, pipe_dir, color)
+ P.on_construction(dir, pipe_dir, color)
if(PIPE_CAP)
var/obj/machinery/atmospherics/pipe/cap/C = new(src.loc)
- C.construction(dir, pipe_dir, color)
+ C.on_construction(dir, pipe_dir, color)
if(PIPE_SUPPLY_CAP)
var/obj/machinery/atmospherics/pipe/cap/hidden/supply/C = new(src.loc)
- C.construction(dir, pipe_dir, color)
+ C.on_construction(dir, pipe_dir, color)
if(PIPE_SCRUBBERS_CAP)
var/obj/machinery/atmospherics/pipe/cap/hidden/scrubbers/C = new(src.loc)
- C.construction(dir, pipe_dir, color)
+ C.on_construction(dir, pipe_dir, color)
if(PIPE_PASSIVE_GATE) //passive gate
var/obj/machinery/atmospherics/binary/passive_gate/P = new(src.loc)
if(pipename)
P.name = pipename
- P.construction(dir, pipe_dir, color)
+ P.on_construction(dir, pipe_dir, color)
if(PIPE_VOLUME_PUMP) //volume pump
var/obj/machinery/atmospherics/binary/volume_pump/P = new(src.loc)
if(pipename)
P.name = pipename
- P.construction(dir, pipe_dir, color)
+ P.on_construction(dir, pipe_dir, color)
if(PIPE_HEAT_EXCHANGE) // heat exchanger
var/obj/machinery/atmospherics/unary/heat_exchanger/C = new( src.loc )
if(pipename)
C.name = pipename
- C.construction(dir, pipe_dir, color)
+ C.on_construction(dir, pipe_dir, color)
if(PIPE_INJECTOR) // air injector
var/obj/machinery/atmospherics/unary/outlet_injector/P = new( src.loc )
if(pipename)
P.name = pipename
- P.construction(dir, pipe_dir, color)
-
+ P.on_construction(dir, pipe_dir, color)
+
if(PIPE_DP_VENT)
var/obj/machinery/atmospherics/binary/dp_vent_pump/P = new(src.loc)
if(pipename)
P.name = pipename
- P.construction(dir, pipe_dir, color)
-
+ P.on_construction(dir, pipe_dir, color)
+
if(PIPE_PASV_VENT)
var/obj/machinery/atmospherics/unary/passive_vent/P = new(src.loc)
if(pipename)
P.name = pipename
- P.construction(dir, pipe_dir, color)
+ P.on_construction(dir, pipe_dir, color)
if(PIPE_OMNI_MIXER)
var/obj/machinery/atmospherics/omni/mixer/P = new(loc)
- P.construction(dir, pipe_dir, color)
-
+ P.on_construction(dir, pipe_dir, color)
+
if(PIPE_OMNI_FILTER)
var/obj/machinery/atmospherics/omni/filter/P = new(loc)
- P.construction(dir, pipe_dir, color)
+ P.on_construction(dir, pipe_dir, color)
- playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(src.loc, W.usesound, 50, 1)
user.visible_message( \
"[user] fastens the [src].", \
- "\blue You have fastened the [src].", \
+ "You have fastened the [src].", \
"You hear ratchet.")
qdel(src) // remove the pipe item
@@ -643,11 +643,11 @@
if(!istype(W, /obj/item/weapon/wrench))
return ..()
if(!locate(/obj/machinery/atmospherics/pipe, src.loc))
- to_chat(user, "\red You need to fasten it to a pipe")
+ to_chat(user, "You need to fasten it to a pipe")
return 1
- new/obj/machinery/meter( src.loc )
- playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
- to_chat(user, "\blue You have fastened the meter to the pipe")
+ new /obj/machinery/meter(loc)
+ playsound(src.loc, W.usesound, 50, 1)
+ to_chat(user, "You have fastened the meter to the pipe.")
qdel(src)
/obj/item/pipe_gsensor
@@ -663,8 +663,8 @@
if(!istype(W, /obj/item/weapon/wrench))
return ..()
new/obj/machinery/air_sensor( src.loc )
- playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
- to_chat(user, "\blue You have fastened the gas sensor")
+ playsound(get_turf(src), W.usesound, 50, 1)
+ to_chat(user, "You have fastened the gas sensor.")
qdel(src)
#undef PIPE_SIMPLE_STRAIGHT
diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm
index d7ac49381b9..37836e8f798 100644
--- a/code/game/machinery/pipe/pipe_dispenser.dm
+++ b/code/game/machinery/pipe/pipe_dispenser.dm
@@ -112,9 +112,9 @@
return
else if(istype(W, /obj/item/weapon/wrench))
if(unwrenched==0)
- playsound(loc, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(loc, W.usesound, 50, 1)
to_chat(user, "You begin to unfasten \the [src] from the floor...")
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * W.toolspeed, target = src))
user.visible_message( \
"[user] unfastens \the [src].", \
"You have unfastened \the [src]. Now it can be pulled somewhere else.", \
@@ -125,9 +125,9 @@
if(usr.machine==src)
usr << browse(null, "window=pipedispenser")
else /*if(unwrenched==1)*/
- playsound(loc, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(loc, W.usesound, 50, 1)
to_chat(user, "You begin to fasten \the [src] to the floor...")
- if(do_after(user, 20, target = src))
+ if(do_after(user, 20 * W.toolspeed, target = src))
user.visible_message( \
"[user] fastens \the [src].", \
"You have fastened \the [src]. Now it can dispense pipes.", \
diff --git a/code/game/machinery/podmen.dm b/code/game/machinery/podmen.dm
index c0ca39c3e12..af24a856115 100644
--- a/code/game/machinery/podmen.dm
+++ b/code/game/machinery/podmen.dm
@@ -76,9 +76,9 @@ Growing it to term with nothing injected will grab a ghost from the observers. *
if(beingharvested)
- to_chat(user, ("\red You can only harvest the pod once!"))
+ to_chat(user, ("You can only harvest the pod once!"))
else
- user.visible_message("\blue [user] carefully begins to open the pod...","\blue You carefully begin to open the pod...")
+ user.visible_message("[user] carefully begins to open the pod...","You carefully begin to open the pod...")
beingharvested = 1
//If a sample is injected (and revival is allowed) the plant will be controlled by the original donor.
@@ -123,7 +123,7 @@ Growing it to term with nothing injected will grab a ghost from the observers. *
ticker.mode:update_all_cult_icons() //So the icon actually appears
// -- End mode specific stuff
- to_chat(podman, "\green You awaken slowly, feeling your sap stir into sluggish motion as the warm air caresses your bark.")
+ to_chat(podman, "You awaken slowly, feeling your sap stir into sluggish motion as the warm air caresses your bark.")
if(source && ckey && podman.ckey == ckey)
to_chat(podman, "Memories of a life as [source] drift oddly through a mind unsuited for them, like a skin of oil over a fathomless lake.")
to_chat(podman, "You are now one of the Dionaea, a race of drifting interstellar plantlike creatures that sometimes share their seeds with human traders.")
@@ -132,5 +132,5 @@ Growing it to term with nothing injected will grab a ghost from the observers. *
else
new /mob/living/carbon/monkey/diona(parent.loc)
- parent.visible_message("\blue The pod disgorges a fully-formed plant creature!")
+ parent.visible_message("The pod disgorges a fully-formed plant creature!")
parent.update_tray()
diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm
index 28b3cfe7132..03f5cc1f8c8 100644
--- a/code/game/machinery/portable_turret.dm
+++ b/code/game/machinery/portable_turret.dm
@@ -20,7 +20,7 @@
var/health = 80 //the turret's health
var/locked = 1 //if the turret's behaviour control access is locked
var/controllock = 0 //if the turret responds to control panels
-
+
var/installation = /obj/item/weapon/gun/energy/gun/turret //the type of weapon installed
var/gun_charge = 0 //the charge of the gun inserted
var/projectile = null //holder for bullettype
@@ -56,7 +56,7 @@
var/screen = 0 // Screen 0: main control, screen 1: access levels
var/one_access = 0 // Determines if access control is set to req_one_access or req_access
-
+
var/syndicate = 0 //is the turret a syndicate turret?
var/faction = ""
var/emp_vulnerable = 1 // Can be empd
@@ -94,8 +94,7 @@
setup()
/obj/machinery/porta_turret/Destroy()
- qdel(spark_system)
- spark_system = null
+ QDEL_NULL(spark_system)
return ..()
/obj/machinery/porta_turret/centcom/New()
@@ -337,7 +336,7 @@ var/list/turret_icons
//If the turret is destroyed, you can remove it with a crowbar to
//try and salvage its components
to_chat(user, "You begin prying the metal coverings off.")
- if(do_after(user, 20, target = src))
+ if(do_after(user, 20 * I.toolspeed, target = src))
if(prob(70))
to_chat(user, "You remove the turret and salvage some components.")
if(installation)
@@ -369,15 +368,15 @@ var/list/turret_icons
)
wrenching = 1
- if(do_after(user, 50, target = src))
+ if(do_after(user, 50 * I.toolspeed, target = src))
//This code handles moving the turret around. After all, it's a portable turret!
if(!anchored)
- playsound(loc, 'sound/items/Ratchet.ogg', 100, 1)
+ playsound(loc, I.usesound, 100, 1)
anchored = 1
update_icon()
to_chat(user, "You secure the exterior bolts on the turret.")
else if(anchored)
- playsound(loc, 'sound/items/Ratchet.ogg', 100, 1)
+ playsound(loc, I.usesound, 100, 1)
anchored = 0
to_chat(user, "You unsecure the exterior bolts on the turret.")
update_icon()
@@ -549,8 +548,8 @@ var/list/turret_icons
/obj/machinery/porta_turret/proc/in_faction(mob/living/target)
if(!(faction in target.faction))
return 0
- return 1
-
+ return 1
+
/obj/machinery/porta_turret/proc/assess_and_assign(var/mob/living/L, var/list/targets, var/list/secondarytargets)
switch(assess_living(L))
if(TURRET_PRIORITY_TARGET)
@@ -582,7 +581,7 @@ var/list/turret_icons
if(emagged) // If emagged not even the dead get a rest
return L.stat ? TURRET_SECONDARY_TARGET : TURRET_PRIORITY_TARGET
-
+
if(in_faction(L))
return TURRET_NOT_TARGET
@@ -778,14 +777,14 @@ var/list/turret_icons
switch(build_step)
if(0) //first step
if(istype(I, /obj/item/weapon/wrench) && !anchored)
- playsound(loc, 'sound/items/Ratchet.ogg', 100, 1)
+ playsound(loc, I.usesound, 100, 1)
to_chat(user, "You secure the external bolts.")
anchored = 1
build_step = 1
return
else if(istype(I, /obj/item/weapon/crowbar) && !anchored)
- playsound(loc, 'sound/items/Crowbar.ogg', 75, 1)
+ playsound(loc, I.usesound, 75, 1)
to_chat(user, "You dismantle the turret construction.")
new /obj/item/stack/sheet/metal( loc, 5)
qdel(src) // qdel
@@ -803,7 +802,7 @@ var/list/turret_icons
return
else if(istype(I, /obj/item/weapon/wrench))
- playsound(loc, 'sound/items/Ratchet.ogg', 75, 1)
+ playsound(loc, I.usesound, 75, 1)
to_chat(user, "You unfasten the external bolts.")
anchored = 0
build_step = 0
@@ -812,7 +811,7 @@ var/list/turret_icons
if(2)
if(istype(I, /obj/item/weapon/wrench))
- playsound(loc, 'sound/items/Ratchet.ogg', 100, 1)
+ playsound(loc, I.usesound, 100, 1)
to_chat(user, "You bolt the metal armor into place.")
build_step = 3
return
@@ -825,8 +824,8 @@ var/list/turret_icons
to_chat(user, "You need more fuel to complete this task.")
return
- playsound(loc, pick('sound/items/Welder.ogg', 'sound/items/Welder2.ogg'), 50, 1)
- if(do_after(user, 20, target = src))
+ playsound(loc, WT.usesound, 50, 1)
+ if(do_after(user, 20 * WT.toolspeed, target = src))
if(!src || !WT.remove_fuel(5, user)) return
build_step = 1
to_chat(user, "You remove the turret's interior metal armor.")
@@ -857,7 +856,7 @@ var/list/turret_icons
return
else if(istype(I, /obj/item/weapon/wrench))
- playsound(loc, 'sound/items/Ratchet.ogg', 100, 1)
+ playsound(loc, I.usesound, 100, 1)
to_chat(user, "You remove the turret's metal armor bolts.")
build_step = 2
return
@@ -876,7 +875,7 @@ var/list/turret_icons
if(5)
if(istype(I, /obj/item/weapon/screwdriver))
- playsound(loc, 'sound/items/Screwdriver.ogg', 100, 1)
+ playsound(loc, I.usesound, 100, 1)
build_step = 6
to_chat(user, "You close the internal access hatch.")
return
@@ -894,7 +893,7 @@ var/list/turret_icons
return
else if(istype(I, /obj/item/weapon/screwdriver))
- playsound(loc, 'sound/items/Screwdriver.ogg', 100, 1)
+ playsound(loc, I.usesound, 100, 1)
build_step = 5
to_chat(user, "You open the internal access hatch.")
return
@@ -906,8 +905,8 @@ var/list/turret_icons
if(WT.get_fuel() < 5)
to_chat(user, "You need more fuel to complete this task.")
- playsound(loc, pick('sound/items/Welder.ogg', 'sound/items/Welder2.ogg'), 50, 1)
- if(do_after(user, 30, target = src))
+ playsound(loc, WT.usesound, 50, 1)
+ if(do_after(user, 30 * WT.toolspeed, target = src))
if(!src || !WT.remove_fuel(5, user))
return
build_step = 8
@@ -924,7 +923,7 @@ var/list/turret_icons
qdel(src) // qdel
else if(istype(I, /obj/item/weapon/crowbar))
- playsound(loc, 'sound/items/Crowbar.ogg', 75, 1)
+ playsound(loc, I.usesound, 75, 1)
to_chat(user, "You pry off the turret's exterior armor.")
new /obj/item/stack/sheet/metal(loc, 2)
build_step = 6
@@ -967,46 +966,46 @@ var/list/turret_icons
/atom/movable/porta_turret_cover
icon = 'icons/obj/turrets.dmi'
-
+
// Syndicate turrets
/obj/machinery/porta_turret/syndicate
projectile = /obj/item/projectile/bullet
eprojectile = /obj/item/projectile/bullet
shot_sound = 'sound/weapons/Gunshot.ogg'
eshot_sound = 'sound/weapons/Gunshot.ogg'
-
+
icon_state = "syndieturret0"
var/icon_state_initial = "syndieturret0"
var/icon_state_active = "syndieturret1"
var/icon_state_destroyed = "syndieturret2"
-
+
syndicate = 1
installation = null
always_up = 1
use_power = 0
has_cover = 0
raised = 1
- scan_range = 9
-
+ scan_range = 9
+
faction = "syndicate"
emp_vulnerable = 0
-
+
lethal = 1
check_arrest = 0
check_records = 0
check_weapons = 0
check_access = 0
- check_anomalies = 1
+ check_anomalies = 1
check_synth = 1
ailock = 1
-
+
/obj/machinery/porta_turret/syndicate/New()
..()
if(req_one_access && req_one_access.len)
req_one_access.Cut()
req_access = list(access_syndicate)
one_access = 0
-
+
/obj/machinery/porta_turret/syndicate/update_icon()
if(stat & BROKEN)
icon_state = icon_state_destroyed
@@ -1025,7 +1024,7 @@ var/list/turret_icons
health = 40
projectile = /obj/item/projectile/bullet/weakbullet3
eprojectile = /obj/item/projectile/bullet/weakbullet3
-
+
/obj/machinery/porta_turret/syndicate/interior
name = "machine gun turret (.45)"
desc = "Syndicate interior defense turret chambered for .45 rounds. Designed to down intruders without damaging the hull."
diff --git a/code/game/machinery/programmable_unloader.dm b/code/game/machinery/programmable_unloader.dm
index e41dfd2f79f..c86d745c05a 100644
--- a/code/game/machinery/programmable_unloader.dm
+++ b/code/game/machinery/programmable_unloader.dm
@@ -198,12 +198,12 @@
/obj/machinery/programmable/attackby(obj/item/I as obj, mob/user as mob, params)
if(istype(I,/obj/item/weapon/wrench)) // code borrowed from pipe dispenser
if(unwrenched==0)
- playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
- to_chat(user, "\blue You begin to unfasten \the [src] from the floor...")
- if(do_after(user, 40, target = src))
+ playsound(src.loc, I.usesound, 50, 1)
+ to_chat(user, "You begin to unfasten \the [src] from the floor...")
+ if(do_after(user, 40 * I.toolspeed, target = src))
user.visible_message( \
"[user] unfastens \the [src].", \
- "\blue You have unfastened \the [src]. Now it can be pulled somewhere else.", \
+ "You have unfastened \the [src]. Now it can be pulled somewhere else.", \
"You hear ratchet.")
src.anchored = 0
src.stat |= MAINT
@@ -211,12 +211,12 @@
if(usr.machine==src)
usr << browse(null, "window=pipedispenser")
else /* unwrenched */
- playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
- to_chat(user, "\blue You begin to fasten \the [src] to the floor...")
- if(do_after(user, 20, target = src))
+ playsound(src.loc, I.usesound, 50, 1)
+ to_chat(user, "You begin to fasten \the [src] to the floor...")
+ if(do_after(user, 20 * I.toolspeed, target = src))
user.visible_message( \
"[user] fastens \the [src].", \
- "\blue You fastened \the [src] into place.", \
+ "You fastened \the [src] into place.", \
"You hear ratchet.")
src.anchored = 1
src.input = get_step(src.loc,src.indir)
@@ -237,9 +237,10 @@
to_chat(user, "You open \the [src]'s maintenance panel.")
if(istype(I,/obj/item/weapon/crowbar))
if(open)
- to_chat(user, "\blue You begin to pry out the [src]'s circuits.")
- if(do_after(user,40, target = src))
- to_chat(user, "\blue You remove the circuitboard.")
+ to_chat(user, "You begin to pry out the [src]'s circuits.")
+ if(do_after(user, 40 * I.toolspeed, target = src))
+ to_chat(user, "You remove the circuitboard.")
+ playsound(loc, I.usesound, 50, 1)
circuit_removed = 1
use_power = 0
on = 0
@@ -515,7 +516,7 @@
if(damage < 5)
visible_message("[H] gives \the [src] a weak punch.")
if(prob(10))
- visible_message("\blue \The [src] feints at [H], as though mocking \him.")
+ visible_message("\The [src] feints at [H], as though mocking \him.")
else if(damage < 10)
visible_message("[H] hits \the [src] with a solid [pick("punch","jab","smack")].")
else if(damage < 15)
@@ -532,11 +533,11 @@
damage -= 5
if(newsleep)
if(emagged)
- visible_message("\red \The [src]'s lights glow a bloodthirsty red. It refuses to stop!")
+ visible_message("\The [src]'s lights glow a bloodthirsty red. It refuses to stop!")
sleep = 0
else
sleep += newsleep
- visible_message("\blue \The [src]'s lights dim for a moment and it beeps, signifying a valid hit.")
+ visible_message("\The [src]'s lights dim for a moment and it beeps, signifying a valid hit.")
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
return
diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm
index 6db7199a7f0..94513623cfb 100644
--- a/code/game/machinery/recharger.dm
+++ b/code/game/machinery/recharger.dm
@@ -1,70 +1,78 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
-
/obj/machinery/recharger
name = "recharger"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "recharger0"
+ desc = "A charging dock for energy based weaponry."
anchored = 1
use_power = 1
- idle_power_usage = 40
- active_power_usage = 2500
+ idle_power_usage = 4
+ active_power_usage = 250
var/obj/item/charging = null
+ var/list/allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/device/modular_computer, /obj/item/weapon/rcs)
+ var/icon_state_off = "rechargeroff"
var/icon_state_charged = "recharger2"
var/icon_state_charging = "recharger1"
var/icon_state_idle = "recharger0"
-/obj/machinery/recharger/attackby(obj/item/weapon/G as obj, mob/user as mob, params)
- if(istype(user,/mob/living/silicon))
- return
-
- if(!user.canUnEquip(G, 0))
- to_chat(user, "[G] is stuck to your hand, you can't put it in [src]!")
- return
-
- if(istype(G, /obj/item/weapon/gun/energy) || istype(G, /obj/item/weapon/melee/baton) || istype(G,/obj/item/device/laptop) || istype(G, /obj/item/weapon/rcs))
+/obj/machinery/recharger/attackby(obj/item/weapon/G, mob/user, params)
+ if(iswrench(G))
if(charging)
- return
-
- // Checks to make sure he's not in space doing it, and that the area got proper power.
- var/area/a = get_area(src)
- if(!isarea(a))
- to_chat(user, "\red The [name] blinks red as you try to insert the item!")
- return
- if(a.power_equip == 0 && a.requires_power)
- to_chat(user, "\red The [name] blinks red as you try to insert the item!")
- return
-
- if(istype(G, /obj/item/weapon/gun/energy))
- var/obj/item/weapon/gun/energy/E = G
- if(!E.can_charge)
- to_chat(user, "Your gun has no external power connector.")
- return
-
- if(istype(G, /obj/item/device/laptop))
- var/obj/item/device/laptop/L = G
- if(!L.stored_computer.battery)
- to_chat(user, "There's no battery in it!")
- return
-
- user.drop_item()
- G.loc = src
- charging = G
- use_power = 2
- update_icon()
- else if(istype(G, /obj/item/weapon/wrench))
- if(charging)
- to_chat(user, "\red Remove the weapon first!")
+ to_chat(user, "Remove the charging item first!")
return
anchored = !anchored
- to_chat(user, "You [anchored ? "attached" : "detached"] the recharger.")
- playsound(loc, 'sound/items/Ratchet.ogg', 75, 1)
+ power_change()
+ to_chat(user, "You [anchored ? "attached" : "detached"] [src].")
+ playsound(loc, G.usesound, 75, 1)
+ return
+
+ var/allowed = is_type_in_list(G, allowed_devices)
+
+ if(allowed)
+ if(anchored)
+ if(charging)
+ return 1
+
+ //Checks to make sure he's not in space doing it, and that the area got proper power.
+ var/area/a = get_area(src)
+ if(!isarea(a) || a.power_equip == 0)
+ to_chat(user, "[src] blinks red as you try to insert [G].")
+ return 1
+
+ if(istype(G, /obj/item/weapon/gun/energy))
+ var/obj/item/weapon/gun/energy/E = G
+ if(!E.can_charge)
+ to_chat(user, "Your gun has no external power connector.")
+ return 1
+
+ if(!user.drop_item())
+ return 1
+ G.forceMove(src)
+ charging = G
+ use_power = 2
+ update_icon()
+ else
+ to_chat(user, "[src] isn't connected to anything!")
+ return 1
+ else
+ ..()
+
+/obj/machinery/recharger/attack_hand(mob/user)
+ if(issilicon(user))
+ return
-/obj/machinery/recharger/attack_hand(mob/user as mob)
add_fingerprint(user)
-
if(charging)
charging.update_icon()
- charging.loc = loc
+ charging.forceMove(loc)
+ user.put_in_hands(charging)
+ charging = null
+ use_power = 1
+ update_icon()
+
+/obj/machinery/recharger/attack_tk(mob/user)
+ if(charging)
+ charging.update_icon()
+ charging.forceMove(loc)
charging = null
use_power = 1
update_icon()
@@ -73,43 +81,42 @@
if(stat & (NOPOWER|BROKEN) || !anchored)
return
+ var/using_power = 0
if(charging)
if(istype(charging, /obj/item/weapon/gun/energy))
var/obj/item/weapon/gun/energy/E = charging
if(E.power_supply.charge < E.power_supply.maxcharge)
- E.power_supply.give(1000)
- icon_state = icon_state_charging
- use_power(2500)
- else
- icon_state = icon_state_charged
- return
+ E.power_supply.give(E.power_supply.chargerate)
+ use_power(250)
+ using_power = 1
+
+
if(istype(charging, /obj/item/weapon/melee/baton))
var/obj/item/weapon/melee/baton/B = charging
- if(B.bcell && B.bcell.charge < B.bcell.maxcharge)
- B.bcell.charge += 1750
- icon_state = icon_state_charging
- use_power(2000)
- else
- icon_state = icon_state_charged
- return
- if(istype(charging, /obj/item/device/laptop))
- var/obj/item/device/laptop/L = charging
- if(L.stored_computer.battery.charge < L.stored_computer.battery.maxcharge)
- L.stored_computer.battery.give(1000)
- icon_state = icon_state_charging
- use_power(2500)
- else
- icon_state = icon_state_charged
+ if(B.bcell)
+ if(B.bcell.give(B.bcell.chargerate))
+ use_power(200)
+ using_power = 1
+
+ if(istype(charging, /obj/item/device/modular_computer))
+ var/obj/item/device/modular_computer/C = charging
+ var/obj/item/weapon/computer_hardware/battery/battery_module = C.all_components[MC_CELL]
+ if(battery_module)
+ var/obj/item/weapon/computer_hardware/battery/B = battery_module
+ if(B.battery)
+ if(B.battery.charge < B.battery.maxcharge)
+ B.battery.give(B.battery.chargerate)
+ use_power(200)
+ using_power = 1
+
if(istype(charging, /obj/item/weapon/rcs))
var/obj/item/weapon/rcs/R = charging
- if(R.rcell && R.rcell.charge < R.rcell.maxcharge)
- R.rcell.charge += 1750
- icon_state = icon_state_charging
- use_power(2000)
- else
- icon_state = icon_state_charged
- return
+ if(R.rcell)
+ if(R.rcell.give(R.rcell.chargerate))
+ use_power(200)
+ using_power = 1
+ update_icon(using_power)
/obj/machinery/recharger/emp_act(severity)
if(stat & (NOPOWER|BROKEN) || !anchored)
@@ -127,17 +134,23 @@
B.bcell.charge = 0
..(severity)
-/obj/machinery/recharger/update_icon() //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier.
+/obj/machinery/recharger/update_icon(using_power = 0) //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier.
+ if(stat & (NOPOWER|BROKEN) || !anchored)
+ icon_state = icon_state_off
+ return
if(charging)
- icon_state = icon_state_charging
- else
- icon_state = icon_state_idle
+ if(using_power)
+ icon_state = icon_state_charging
+ else
+ icon_state = icon_state_charged
+ return
+ icon_state = icon_state_idle
// Atlantis: No need for that copy-pasta code, just use var to store icon_states instead.
obj/machinery/recharger/wallcharger
name = "wall recharger"
- icon = 'icons/obj/stationobjs.dmi'
icon_state = "wrecharger0"
+ icon_state_off = "wrechargeroff"
icon_state_idle = "wrecharger0"
icon_state_charging = "wrecharger1"
icon_state_charged = "wrecharger2"
diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index 343841b639c..f0a635c73a8 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -159,10 +159,7 @@
R.adjustFireLoss(-(repairs))
R.updatehealth()
if(R.cell)
- if(R.cell.charge >= R.cell.maxcharge)
- R.cell.charge = R.cell.maxcharge
- else
- R.cell.charge = min(R.cell.charge + recharge_speed, R.cell.maxcharge)
+ R.cell.charge = min(R.cell.charge + recharge_speed, R.cell.maxcharge)
else if(istype(occupant, /mob/living/carbon/human))
var/mob/living/carbon/human/H = occupant
if(H.get_int_organ(/obj/item/organ/internal/cell) && H.nutrition < 450)
@@ -192,8 +189,8 @@
// Engineering
if(istype(O,/obj/item/stack/sheet))
var/obj/item/stack/sheet/S = O
- if(S.amount < 50)
- S.amount += 1 * coeff
+ if(S.amount < S.max_amount)
+ S.amount += round(min(1 * coeff, S.max_amount - S.amount))
// Security
if(istype(O,/obj/item/device/flash))
var/obj/item/device/flash/F = O
diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm
index 4a9d8c439ae..698c1c5fe91 100644
--- a/code/game/machinery/recycler.dm
+++ b/code/game/machinery/recycler.dm
@@ -29,8 +29,7 @@ var/const/SAFETY_COOLDOWN = 100
update_icon()
/obj/machinery/recycler/Destroy()
- qdel(materials)
- materials = null
+ QDEL_NULL(materials)
return ..()
/obj/machinery/recycler/RefreshParts()
diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm
index a3f7ee5189a..6028f39af6d 100644
--- a/code/game/machinery/shieldgen.dm
+++ b/code/game/machinery/shieldgen.dm
@@ -29,8 +29,8 @@
..()
move_update_air(T)
-/obj/machinery/shield/CanPass(atom/movable/mover, turf/target, height, air_group)
- if(!height || air_group) return 0
+/obj/machinery/shield/CanPass(atom/movable/mover, turf/target, height)
+ if(!height) return 0
else return ..()
/obj/machinery/shield/CanAtmosPass(var/turf/T)
@@ -49,7 +49,7 @@
if(src.health <= 0)
- visible_message("\blue The [src] dissipates")
+ visible_message("The [src] dissipates")
qdel(src)
return
@@ -62,7 +62,7 @@
health -= Proj.damage
..()
if(health <=0)
- visible_message("\blue The [src] dissipates")
+ visible_message("The [src] dissipates")
qdel(src)
return
opacity = 1
@@ -109,7 +109,7 @@
//Handle the destruction of the shield
if(src.health <= 0)
- visible_message("\blue The [src] dissipates")
+ visible_message("The [src] dissipates")
qdel(src)
return
@@ -218,14 +218,14 @@
return
if(src.active)
- user.visible_message("\blue [bicon(src)] [user] deactivated the shield generator.", \
- "\blue [bicon(src)] You deactivate the shield generator.", \
+ user.visible_message("[bicon(src)] [user] deactivated the shield generator.", \
+ "[bicon(src)] You deactivate the shield generator.", \
"You hear heavy droning fade out.")
src.shields_down()
else
if(anchored)
- user.visible_message("\blue [bicon(src)] [user] activated the shield generator.", \
- "\blue [bicon(src)] You activate the shield generator.", \
+ user.visible_message("[bicon(src)] [user] activated the shield generator.", \
+ "[bicon(src)] You activate the shield generator.", \
"You hear heavy droning.")
src.shields_up()
else
@@ -238,24 +238,25 @@
update_icon()
else if(istype(W, /obj/item/weapon/screwdriver))
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1)
+ playsound(src.loc, W.usesound, 100, 1)
if(is_open)
- to_chat(user, "\blue You close the panel.")
+ to_chat(user, "You close the panel.")
is_open = 0
else
- to_chat(user, "\blue You open the panel and expose the wiring.")
+ to_chat(user, "You open the panel and expose the wiring.")
is_open = 1
else if(istype(W, /obj/item/stack/cable_coil) && malfunction && is_open)
var/obj/item/stack/cable_coil/coil = W
- to_chat(user, "\blue You begin to replace the wires.")
+ to_chat(user, "You begin to replace the wires.")
//if(do_after(user, min(60, round( ((maxhealth/health)*10)+(malfunction*10) ), target = src)) //Take longer to repair heavier damage
- if(do_after(user, 30, target = src))
+ if(do_after(user, 30 * coil.toolspeed, target = src))
if(!src || !coil) return
coil.use(1)
health = max_health
malfunction = 0
- to_chat(user, "\blue You repair the [src]!")
+ playsound(loc, coil.usesound, 50, 1)
+ to_chat(user, "You repair the [src]!")
update_icon()
else if(istype(W, /obj/item/weapon/wrench))
@@ -263,16 +264,16 @@
to_chat(user, "The bolts are covered, unlocking this would retract the covers.")
return
if(anchored)
- playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
- to_chat(user, "\blue You unsecure the [src] from the floor!")
+ playsound(src.loc, W.usesound, 100, 1)
+ to_chat(user, "You unsecure the [src] from the floor!")
if(active)
- to_chat(user, "\blue The [src] shuts off!")
+ to_chat(user, "The [src] shuts off!")
src.shields_down()
anchored = 0
else
if(istype(get_turf(src), /turf/space)) return //No wrenching these in space!
- playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
- to_chat(user, "\blue You secure the [src] to the floor!")
+ playsound(src.loc, W.usesound, 100, 1)
+ to_chat(user, "You secure the [src] to the floor!")
anchored = 1
@@ -281,7 +282,7 @@
src.locked = !src.locked
to_chat(user, "The controls are now [src.locked ? "locked." : "unlocked."]")
else
- to_chat(user, "\red Access denied.")
+ to_chat(user, "Access denied.")
else
..()
@@ -349,13 +350,13 @@
/obj/machinery/shieldwallgen/attack_hand(mob/user as mob)
if(state != 1)
- to_chat(user, "\red The shield generator needs to be firmly secured to the floor first.")
+ to_chat(user, "The shield generator needs to be firmly secured to the floor first.")
return 1
if(src.locked && !istype(user, /mob/living/silicon))
- to_chat(user, "\red The controls are locked!")
+ to_chat(user, "The controls are locked!")
return 1
if(power != 1)
- to_chat(user, "\red The shield generator needs to be powered by wire underneath.")
+ to_chat(user, "The shield generator needs to be powered by wire underneath.")
return 1
if(src.active >= 1)
@@ -401,7 +402,7 @@
src.active = 2
if(src.active >= 1)
if(src.power == 0)
- src.visible_message("\red The [src.name] shuts down due to lack of power!", \
+ src.visible_message("The [src.name] shuts down due to lack of power!", \
"You hear heavy droning fade out")
icon_state = "Shield_Gen"
src.active = 0
@@ -460,14 +461,14 @@
else if(state == 0)
state = 1
- playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
+ playsound(src.loc, W.usesound, 75, 1)
to_chat(user, "You secure the external reinforcing bolts to the floor.")
src.anchored = 1
return
else if(state == 1)
state = 0
- playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
+ playsound(src.loc, W.usesound, 75, 1)
to_chat(user, "You undo the external reinforcing bolts.")
src.anchored = 0
return
@@ -477,7 +478,7 @@
src.locked = !src.locked
to_chat(user, "Controls are now [src.locked ? "locked." : "unlocked."]")
else
- to_chat(user, "\red Access denied.")
+ to_chat(user, "Access denied.")
else
add_fingerprint(user)
@@ -599,8 +600,8 @@
return
-/obj/machinery/shieldwall/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if(air_group || (height==0)) return 1
+/obj/machinery/shieldwall/CanPass(atom/movable/mover, turf/target, height=0)
+ if(height==0) return 1
if(istype(mover) && mover.checkpass(PASSGLASS))
return prob(20)
diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm
index 91e60dfaec5..600dc3704fa 100644
--- a/code/game/machinery/spaceheater.dm
+++ b/code/game/machinery/spaceheater.dm
@@ -20,9 +20,7 @@
return
/obj/machinery/space_heater/Destroy()
- if(cell)
- qdel(cell)
- cell = null
+ QDEL_NULL(cell)
return ..()
/obj/machinery/space_heater/update_icon()
@@ -64,13 +62,13 @@
C.loc = src
C.add_fingerprint(usr)
- user.visible_message("\blue [user] inserts a power cell into [src].", "\blue You insert the power cell into [src].")
+ user.visible_message("[user] inserts a power cell into [src].", "You insert the power cell into [src].")
else
to_chat(user, "The hatch must be open to insert a power cell.")
return
else if(istype(I, /obj/item/weapon/screwdriver))
open = !open
- user.visible_message("\blue [user] [open ? "opens" : "closes"] the hatch on the [src].", "\blue You [open ? "open" : "close"] the hatch on the [src].")
+ user.visible_message("[user] [open ? "opens" : "closes"] the hatch on the [src].", "You [open ? "open" : "close"] the hatch on the [src].")
update_icon()
if(!open && user.machine == src)
user << browse(null, "window=spaceheater")
@@ -107,7 +105,7 @@
else
on = !on
- user.visible_message("\blue [user] switches [on ? "on" : "off"] the [src].","\blue You switch [on ? "on" : "off"] the [src].")
+ user.visible_message("[user] switches [on ? "on" : "off"] the [src].","You switch [on ? "on" : "off"] the [src].")
update_icon()
return
@@ -132,7 +130,7 @@
usr.put_in_hands(cell)
cell.add_fingerprint(usr)
cell = null
- usr.visible_message("\blue [usr] removes the power cell from \the [src].", "\blue You remove the power cell from \the [src].")
+ usr.visible_message("[usr] removes the power cell from \the [src].", "You remove the power cell from \the [src].")
if("cellinstall")
@@ -144,7 +142,7 @@
C.loc = src
C.add_fingerprint(usr)
- usr.visible_message("\blue [usr] inserts a power cell into \the [src].", "\blue You insert the power cell into \the [src].")
+ usr.visible_message("[usr] inserts a power cell into \the [src].", "You insert the power cell into \the [src].")
updateDialog()
else
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index b50fc3566d8..eee465e062a 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -41,33 +41,33 @@
MASK_TYPE = /obj/item/clothing/mask/gas
/obj/machinery/suit_storage_unit/engine
- SUIT_TYPE = /obj/item/clothing/suit/space/rig/engineering
- HELMET_TYPE = /obj/item/clothing/head/helmet/space/rig/engineering
+ SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/engineering
+ HELMET_TYPE = /obj/item/clothing/head/helmet/space/hardsuit/engineering
MASK_TYPE = /obj/item/clothing/mask/breath
/obj/machinery/suit_storage_unit/ce
- SUIT_TYPE = /obj/item/clothing/suit/space/rig/elite
- HELMET_TYPE = /obj/item/clothing/head/helmet/space/rig/elite
+ SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/elite
+ HELMET_TYPE = /obj/item/clothing/head/helmet/space/hardsuit/elite
MASK_TYPE = /obj/item/clothing/mask/breath
/obj/machinery/suit_storage_unit/security
- SUIT_TYPE = /obj/item/clothing/suit/space/rig/security
- HELMET_TYPE = /obj/item/clothing/head/helmet/space/rig/security
+ SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/security
+ HELMET_TYPE = /obj/item/clothing/head/helmet/space/hardsuit/security
MASK_TYPE = /obj/item/clothing/mask/gas/sechailer
/obj/machinery/suit_storage_unit/atmos
- SUIT_TYPE = /obj/item/clothing/suit/space/rig/atmos
- HELMET_TYPE = /obj/item/clothing/head/helmet/space/rig/atmos
+ SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/atmos
+ HELMET_TYPE = /obj/item/clothing/head/helmet/space/hardsuit/atmos
MASK_TYPE = /obj/item/clothing/mask/gas
/obj/machinery/suit_storage_unit/mining
- SUIT_TYPE = /obj/item/clothing/suit/space/rig/mining
- HELMET_TYPE = /obj/item/clothing/head/helmet/space/rig/mining
+ SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/mining
+ HELMET_TYPE = /obj/item/clothing/head/helmet/space/hardsuit/mining
MASK_TYPE = /obj/item/clothing/mask/breath
/obj/machinery/suit_storage_unit/cmo
- SUIT_TYPE = /obj/item/clothing/suit/space/rig/medical
- HELMET_TYPE = /obj/item/clothing/head/helmet/space/rig/medical
+ SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/medical
+ HELMET_TYPE = /obj/item/clothing/head/helmet/space/hardsuit/medical
MASK_TYPE = /obj/item/clothing/mask/breath
/obj/machinery/suit_storage_unit/New()
@@ -503,7 +503,7 @@
return
if(istype(I, /obj/item/weapon/screwdriver))
src.panelopen = !src.panelopen
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1)
+ playsound(src.loc, I.usesound, 100, 1)
to_chat(user, text("You [] the unit's maintenance panel.",(src.panelopen ? "open up" : "close") ))
src.updateUsrDialog()
return
@@ -628,7 +628,7 @@
var/target_species = "Human"
var/mob/living/carbon/human/occupant = null
- var/obj/item/clothing/suit/space/rig/suit = null
+ var/obj/item/clothing/suit/space/hardsuit/suit = null
var/obj/item/clothing/head/helmet/space/helmet = null
/obj/machinery/suit_cycler/engineering
@@ -667,11 +667,11 @@
return
if(locked)
- to_chat(user, "\red The suit cycler is locked.")
+ to_chat(user, "The suit cycler is locked.")
return
if(src.contents.len > 0)
- to_chat(user, "\red There is no room inside the cycler for [G.affecting.name].")
+ to_chat(user, "There is no room inside the cycler for [G.affecting.name].")
return
visible_message("[user] starts putting [G.affecting.name] into the suit cycler.")
@@ -698,7 +698,7 @@
else if(istype(I,/obj/item/clothing/head/helmet/space))
if(locked)
- to_chat(user, "\red The suit cycler is locked.")
+ to_chat(user, "The suit cycler is locked.")
return
if(helmet)
@@ -714,17 +714,17 @@
src.updateUsrDialog()
return
- else if(istype(I,/obj/item/clothing/suit/space/rig))
+ else if(istype(I,/obj/item/clothing/suit/space/hardsuit))
if(locked)
- to_chat(user, "\red The suit cycler is locked.")
+ to_chat(user, "The suit cycler is locked.")
return
if(suit)
to_chat(user, "The cycler already contains a hardsuit.")
return
- var/obj/item/clothing/suit/space/rig/S = I
+ var/obj/item/clothing/suit/space/hardsuit/S = I
if(S.helmet)
to_chat(user, "\The [S] will not fit into the cycler with a helmet attached.")
@@ -747,11 +747,11 @@
/obj/machinery/suit_cycler/emag_act(user as mob)
if(emagged)
- to_chat(user, "\red The cycler has already been subverted.")
+ to_chat(user, "The cycler has already been subverted.")
return
//Clear the access reqs, disable the safeties, and open up all paintjobs.
- to_chat(user, "\red You run the sequencer across the interface, corrupting the operating protocols.")
+ to_chat(user, "You run the sequencer across the interface, corrupting the operating protocols.")
departments = list("Engineering","Mining","Medical","Security","Atmos","^%###^%$")
emagged = 1
safeties = 0
@@ -875,12 +875,12 @@
locked = !locked
to_chat(usr, "You [locked ? "" : "un"]lock \the [src].")
else
- to_chat(usr, "\red Access denied.")
+ to_chat(usr, "Access denied.")
else if(href_list["begin_decontamination"])
if(safeties && occupant)
- to_chat(usr, "\red The cycler has detected an occupant. Please remove the occupant before commencing the decontamination cycle.")
+ to_chat(usr, "The cycler has detected an occupant. Please remove the occupant before commencing the decontamination cycle.")
return
active = 1
@@ -979,7 +979,7 @@
/obj/machinery/suit_cycler/proc/eject_occupant(mob/user as mob)
if(locked || active)
- to_chat(user, "\red The cycler is locked.")
+ to_chat(user, "The cycler is locked.")
return
if(!occupant)
@@ -1049,60 +1049,60 @@
if("Engineering")
if(helmet)
helmet.name = "engineering hardsuit helmet"
- helmet.icon_state = "rig0-engineering"
+ helmet.icon_state = "hardsuit0-engineering"
helmet.item_state = "eng_helm"
helmet.item_color = "engineering"
if(suit)
suit.name = "engineering hardsuit"
- suit.icon_state = "rig-engineering"
+ suit.icon_state = "hardsuit-engineering"
suit.item_state = "eng_hardsuit"
if("Mining")
if(helmet)
helmet.name = "mining hardsuit helmet"
- helmet.icon_state = "rig0-mining"
+ helmet.icon_state = "hardsuit0-mining"
helmet.item_state = "mining_helm"
helmet.item_color = "mining"
if(suit)
suit.name = "mining hardsuit"
- suit.icon_state = "rig-mining"
+ suit.icon_state = "hardsuit-mining"
suit.item_state = "mining_hardsuit"
if("Medical")
if(helmet)
helmet.name = "medical hardsuit helmet"
- helmet.icon_state = "rig0-medical"
+ helmet.icon_state = "hardsuit0-medical"
helmet.item_state = "medical_helm"
helmet.item_color = "medical"
if(suit)
suit.name = "medical hardsuit"
- suit.icon_state = "rig-medical"
+ suit.icon_state = "hardsuit-medical"
suit.item_state = "medical_hardsuit"
if("Security")
if(helmet)
helmet.name = "security hardsuit helmet"
- helmet.icon_state = "rig0-sec"
+ helmet.icon_state = "hardsuit0-sec"
helmet.item_state = "sec_helm"
helmet.item_color = "sec"
if(suit)
suit.name = "security hardsuit"
- suit.icon_state = "rig-sec"
+ suit.icon_state = "hardsuit-sec"
suit.item_state = "sec_hardsuit"
if("Atmos")
if(helmet)
helmet.name = "atmospherics hardsuit helmet"
- helmet.icon_state = "rig0-atmos"
+ helmet.icon_state = "hardsuit0-atmos"
helmet.item_state = "atmos_helm"
helmet.item_color = "atmos"
if(suit)
suit.name = "atmospherics hardsuit"
- suit.icon_state = "rig-atmos"
+ suit.icon_state = "hardsuit-atmos"
suit.item_state = "atmos_hardsuit"
if("^%###^%$")
if(helmet)
helmet.name = "blood-red hardsuit helmet"
- helmet.icon_state = "rig0-syndie"
+ helmet.icon_state = "hardsuit0-syndie"
helmet.item_state = "syndie_helm"
helmet.item_color = "syndie"
if(suit)
suit.name = "blood-red hardsuit"
suit.item_state = "syndie_hardsuit"
- suit.icon_state = "rig-syndie"
+ suit.icon_state = "hardsuit-syndie"
diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm
index f9355a98d37..8fb2d173b6f 100644
--- a/code/game/machinery/syndicatebomb.dm
+++ b/code/game/machinery/syndicatebomb.dm
@@ -41,8 +41,7 @@
..()
/obj/machinery/syndicatebomb/Destroy()
- qdel(wires)
- wires = null
+ QDEL_NULL(wires)
return ..()
/obj/machinery/syndicatebomb/examine(mob/user)
@@ -59,14 +58,14 @@
to_chat(user, "The bomb must be placed on solid ground to attach it")
else
to_chat(user, "You firmly wrench the bomb to the floor")
- playsound(loc, 'sound/items/ratchet.ogg', 50, 1)
+ playsound(loc, I.usesound, 50, 1)
anchored = 1
if(active)
to_chat(user, "The bolts lock in place")
else
if(!active)
to_chat(user, "You wrench the bomb from the floor")
- playsound(loc, 'sound/items/ratchet.ogg', 50, 1)
+ playsound(loc, I.usesound, 50, 1)
anchored = 0
else
to_chat(user, "The bolts are locked down!")
@@ -89,7 +88,7 @@
else
to_chat(user, "There isn't anything in here to remove!")
else if(open_panel)
- to_chat(user, "The wires conneting the shell to the explosives are holding it down!")
+ to_chat(user, "The wires connecting the shell to the explosives are holding it down!")
else
to_chat(user, "The cover is screwed on, it won't pry off!")
else if(istype(I, /obj/item/weapon/bombcore))
@@ -103,37 +102,50 @@
else
..()
-/obj/machinery/syndicatebomb/attack_hand(var/mob/user)
+/obj/machinery/syndicatebomb/attack_ghost(mob/user)
+ interact(user)
+
+/obj/machinery/syndicatebomb/attack_hand(mob/user)
interact(user)
/obj/machinery/syndicatebomb/attack_ai()
return
-/obj/machinery/syndicatebomb/interact(var/mob/user)
+/obj/machinery/syndicatebomb/interact(mob/user)
if(wires && open_panel)
wires.Interact(user)
- if(!open_panel)
+ if(!open_panel && can_interact(user))
if(!active)
spawn()
settings(user)
return
else if(anchored)
to_chat(user, "The bomb is bolted to the floor!")
- return
-/obj/machinery/syndicatebomb/proc/settings(var/mob/user)
+/obj/machinery/syndicatebomb/proc/can_interact(mob/user)
+ if(user.can_advanced_admin_interact())
+ return TRUE
+ if(!isliving(user))
+ return FALSE
+ if(user.incapacitated())
+ return FALSE
+ if(!Adjacent(user))
+ return FALSE
+ return TRUE
+
+/obj/machinery/syndicatebomb/proc/settings(mob/user)
var/newtime = input(user, "Please set the timer.", "Timer", "[timer]") as num
newtime = Clamp(newtime, 120, 60000)
- if(in_range(src, user) && isliving(user)) //No running off and setting bombs from across the station
+ if(can_interact(user)) //No running off and setting bombs from across the station
timer = newtime
- src.loc.visible_message("[bicon(src)] timer set for [timer] seconds.")
- if(alert(user,"Would you like to start the countdown now?",,"Yes","No") == "Yes" && in_range(src, user) && isliving(user))
+ loc.visible_message("[bicon(src)] timer set for [timer] seconds.")
+ if(alert(user,"Would you like to start the countdown now?",,"Yes","No") == "Yes" && can_interact(user))
if(defused || active)
if(defused)
- src.loc.visible_message("[bicon(src)] Device error: User intervention required.")
+ loc.visible_message("[bicon(src)] Device error: User intervention required.")
return
else
- src.loc.visible_message("[bicon(src)] [timer] seconds until detonation, please clear the area.")
+ loc.visible_message("[bicon(src)] [timer] seconds until detonation, please clear the area.")
playsound(loc, 'sound/machines/click.ogg', 30, 1)
active = 1
update_icon()
@@ -143,8 +155,8 @@
var/area/A = get_area(bombturf)
if(payload && !istype(payload, /obj/item/weapon/bombcore/training))
msg_admin_attack("[key_name_admin(user)] has primed a [name] ([payload]) for detonation at [A.name] (JMP).")
- log_game("[key_name(user)] has primed a [name] ([payload]) for detonation at [A.name]([bombturf.x],[bombturf.y],[bombturf.z])")
- payload.adminlog = "The [src.name] that [key_name(user)] had primed detonated!"
+ log_game("[key_name(user)] has primed a [name] ([payload]) for detonation at [A.name] ([bombturf.x], [bombturf.y], [bombturf.z])")
+ payload.adminlog = "\The [src] that [key_name(user)] had primed detonated!"
/obj/machinery/syndicatebomb/proc/isWireCut(var/index)
return wires.IsIndexCut(index)
diff --git a/code/game/machinery/telecomms/logbrowser.dm b/code/game/machinery/telecomms/logbrowser.dm
index ae0b2738d1b..48d65eb051b 100644
--- a/code/game/machinery/telecomms/logbrowser.dm
+++ b/code/game/machinery/telecomms/logbrowser.dm
@@ -24,7 +24,8 @@
if(stat & (BROKEN|NOPOWER))
return
user.set_machine(src)
- var/dat = "Telecommunication Server Monitor
Telecommunications Server Monitor
"
+ var/list/dat = list()
+ dat += "Telecommunication Server Monitor
Telecommunications Server Monitor
"
switch(screen)
@@ -63,55 +64,16 @@
var/i = 0
for(var/datum/comm_log_entry/C in SelectedServer.log_entries)
i++
-
-
// If the log is a speech file
if(C.input_type == "Speech File")
-
dat += "
[C.name] \[X\] "
- // -- Determine race of orator --
-
- var/race // The actual race of the mob
- var/language = "Human" // MMIs, pAIs, Cyborgs and humans all speak Human
- var/mobtype = C.parameters["mobtype"]
- var/mob/M = new mobtype
-
- if(ishuman(M) || isbrain(M))
- var/mob/living/carbon/human/H = M
- race = "[H.species.name]"
-
-
- else if(issmall(M))
- race = "Monkey"
- language = race
-
- else if(issilicon(M) || C.parameters["job"] == "AI") // sometimes M gets deleted prematurely for AIs... just check the job
- race = "Artificial Life"
-
- else if(isslime(M)) // NT knows a lot about slimes, but not aliens. Can identify slimes
- race = "Slime"
- language = race
-
- else if(isbot(M))
- race = "Bot"
-
- else if(isanimal(M))
- race = "Domestic Animal"
- language = race
-
- else
- race = "Unidentifiable"
- language = race
-
- qdel(M)
-
// -- If the orator is a human, or universal translate is active, OR mob has universal speech on --
- if(language == "Human" || universal_translate || C.parameters["uspeech"])
+ if(user.say_understands(null, C.parameters["language"]) || universal_translate || C.parameters["uspeech"])
dat += "Data type: [C.input_type] "
dat += "Source: [C.parameters["name"]] (Job: [C.parameters["job"]]) "
- dat += "Class: [race] "
+ dat += "Class: [C.parameters["race"]] "
dat += "Contents: \"[C.parameters["message"]]\" "
@@ -120,7 +82,7 @@
else
dat += "Data type: Audio File "
dat += "Source: Unidentifiable "
- dat += "Class: [race] "
+ dat += "Class: [C.parameters["race"]] "
dat += "Contents: Unintelligble "
dat += "
"
@@ -136,7 +98,7 @@
- user << browse(dat, "window=comm_monitor;size=575x400")
+ user << browse(dat.Join(""), "window=comm_monitor;size=575x400")
onclose(user, "server_control")
temp = ""
@@ -187,7 +149,7 @@
if(href_list["delete"])
if(!src.allowed(usr) && !emagged)
- to_chat(usr, "\red ACCESS DENIED.")
+ to_chat(usr, "ACCESS DENIED.")
return
if(SelectedServer)
@@ -222,10 +184,10 @@
attackby(var/obj/item/weapon/D as obj, var/mob/user as mob, params)
if(istype(D, /obj/item/weapon/screwdriver))
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
- if(do_after(user, 20, target = src))
+ playsound(src.loc, D.usesound, 50, 1)
+ if(do_after(user, 20 * D.toolspeed, target = src))
if(src.stat & BROKEN)
- to_chat(user, "\blue The broken glass falls out.")
+ to_chat(user, "The broken glass falls out.")
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
new /obj/item/weapon/shard(loc)
var/obj/item/weapon/circuitboard/comm_server/M = new /obj/item/weapon/circuitboard/comm_server( A )
@@ -237,7 +199,7 @@
A.anchored = 1
qdel(src)
else
- to_chat(user, "\blue You disconnect the monitor.")
+ to_chat(user, "You disconnect the monitor.")
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
var/obj/item/weapon/circuitboard/comm_server/M = new /obj/item/weapon/circuitboard/comm_server( A )
for(var/obj/C in src)
@@ -254,4 +216,4 @@
if(!emagged)
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
emagged = 1
- to_chat(user, "\blue You you disable the security protocols")
+ to_chat(user, "You you disable the security protocols")
diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm
index c1a10cacd48..db436bfb772 100644
--- a/code/game/machinery/telecomms/machine_interactions.dm
+++ b/code/game/machinery/telecomms/machine_interactions.dm
@@ -24,24 +24,24 @@
if(0)
if(istype(P, /obj/item/weapon/screwdriver))
to_chat(user, "You unfasten the bolts.")
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
+ playsound(src.loc, P.usesound, 50, 1)
construct_op++
if(1)
if(istype(P, /obj/item/weapon/screwdriver))
to_chat(user, "You fasten the bolts.")
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
+ playsound(src.loc,P.usesound, 50, 1)
construct_op--
if(istype(P, /obj/item/weapon/wrench))
to_chat(user, "You dislodge the external plating.")
- playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
+ playsound(src.loc, P.usesound, 75, 1)
construct_op++
if(2)
if(istype(P, /obj/item/weapon/wrench))
to_chat(user, "You secure the external plating.")
- playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
+ playsound(src.loc, P.usesound, 75, 1)
construct_op--
if(istype(P, /obj/item/weapon/wirecutters))
- playsound(src.loc, 'sound/items/Wirecutter.ogg', 50, 1)
+ playsound(src.loc, P.usesound, 50, 1)
to_chat(user, "You remove the cables.")
construct_op++
var/obj/item/stack/cable_coil/A = new /obj/item/stack/cable_coil( user.loc )
@@ -51,6 +51,7 @@
if(istype(P, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/A = P
if(A.amount >= 5)
+ playsound(loc, A.usesound, 50, 1)
to_chat(user, "You insert the cables.")
A.amount -= 5
if(A.amount <= 0)
@@ -60,8 +61,8 @@
stat &= ~BROKEN // the machine's not borked anymore!
if(istype(P, /obj/item/weapon/crowbar))
to_chat(user, "You begin prying out the circuit board other components...")
- playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
- if(do_after(user,60, target = src))
+ playsound(src.loc, P.usesound, 50, 1)
+ if(do_after(user, 60 * P.toolspeed, target = src))
to_chat(user, "You finish prying out the components.")
// Drop all the component stuff
diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm
index a4e481f430b..953fdb68b8b 100644
--- a/code/game/machinery/telecomms/telecomunications.dm
+++ b/code/game/machinery/telecomms/telecomunications.dm
@@ -475,7 +475,9 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
// Copy the signal.data entries we want
log.parameters["mobtype"] = signal.data["mobtype"]
+ log.parameters["race"] = signal.data["race"]
log.parameters["job"] = signal.data["job"]
+ log.parameters["language"] = signal.data["language"]
log.parameters["key"] = signal.data["key"]
log.parameters["vmessage"] = signal.data["message"]
log.parameters["vname"] = signal.data["vname"]
diff --git a/code/game/machinery/telecomms/telemonitor.dm b/code/game/machinery/telecomms/telemonitor.dm
index 9baa2a1a12f..6b5201460e4 100644
--- a/code/game/machinery/telecomms/telemonitor.dm
+++ b/code/game/machinery/telecomms/telemonitor.dm
@@ -128,10 +128,10 @@
attackby(var/obj/item/weapon/D as obj, var/mob/user as mob, params)
if(istype(D, /obj/item/weapon/screwdriver))
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
- if(do_after(user, 20, target = src))
+ playsound(src.loc, D.usesound, 50, 1)
+ if(do_after(user, 20 * D.toolspeed, target = src))
if(src.stat & BROKEN)
- to_chat(user, "\blue The broken glass falls out.")
+ to_chat(user, "The broken glass falls out.")
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
new /obj/item/weapon/shard(loc)
var/obj/item/weapon/circuitboard/comm_monitor/M = new /obj/item/weapon/circuitboard/comm_monitor( A )
@@ -143,7 +143,7 @@
A.anchored = 1
qdel(src)
else
- to_chat(user, "\blue You disconnect the monitor.")
+ to_chat(user, "You disconnect the monitor.")
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
var/obj/item/weapon/circuitboard/comm_monitor/M = new /obj/item/weapon/circuitboard/comm_monitor( A )
for(var/obj/C in src)
@@ -160,4 +160,4 @@
if(!emagged)
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
emagged = 1
- to_chat(user, "\blue You you disable the security protocols")
+ to_chat(user, "You you disable the security protocols")
diff --git a/code/game/machinery/telecomms/traffic_control.dm b/code/game/machinery/telecomms/traffic_control.dm
index 001771b7efa..2aa0c2a5d59 100644
--- a/code/game/machinery/telecomms/traffic_control.dm
+++ b/code/game/machinery/telecomms/traffic_control.dm
@@ -340,10 +340,10 @@
/obj/machinery/computer/telecomms/traffic/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob, params)
if(istype(D, /obj/item/weapon/screwdriver))
- playsound(get_turf(src), 'sound/items/Screwdriver.ogg', 50, 1)
- if(do_after(user, 20, target = src))
+ playsound(get_turf(src), D.usesound, 50, 1)
+ if(do_after(user, 20 * D.toolspeed, target = src))
if(src.stat & BROKEN)
- to_chat(user, "\blue The broken glass falls out.")
+ to_chat(user, "The broken glass falls out.")
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
new /obj/item/weapon/shard(loc)
var/obj/item/weapon/circuitboard/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( A )
@@ -355,7 +355,7 @@
A.anchored = 1
qdel(src)
else
- to_chat(user, "\blue You disconnect the monitor.")
+ to_chat(user, "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)
@@ -372,7 +372,7 @@
if(!emagged)
playsound(get_turf(src), 'sound/effects/sparks4.ogg', 75, 1)
emagged = 1
- to_chat(user, "\blue You you disable the security protocols")
+ to_chat(user, "You you disable the security protocols")
/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 843002a804d..8479e4e051b 100644
--- a/code/game/machinery/teleporter.dm
+++ b/code/game/machinery/teleporter.dm
@@ -55,7 +55,7 @@
/obj/machinery/computer/teleporter/emag_act(user as mob)
if(!emagged)
emagged = 1
- to_chat(user, "\blue The teleporter can now lock on to Syndicate beacons!")
+ to_chat(user, "The teleporter can now lock on to Syndicate beacons!")
else
ui_interact(user)
diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm
index f34e28dcd18..878ea0737aa 100644
--- a/code/game/machinery/transformer.dm
+++ b/code/game/machinery/transformer.dm
@@ -11,6 +11,7 @@
var/cooldown_duration = 600 // 1 minute
var/cooldown = 0
var/robot_cell_charge = 5000
+ var/acceptdir = EAST
/obj/machinery/transformer/New()
// On us
@@ -28,6 +29,12 @@
else
icon_state = initial(icon_state)
+/obj/machinery/transformer/setDir(newdir)
+ . = ..()
+ var/obj/machinery/conveyor/C = locate() in loc
+ C.setDir(newdir)
+ acceptdir = turn(newdir, 180)
+
/obj/machinery/transformer/Bumped(var/atom/movable/AM)
if(cooldown == 1)
@@ -38,7 +45,7 @@
// Only humans can enter from the west side, while lying down.
var/move_dir = get_dir(loc, AM.loc)
var/mob/living/carbon/human/H = AM
- if((transform_standing || H.lying) && move_dir == EAST)// || move_dir == WEST)
+ if((transform_standing || H.lying) && move_dir == acceptdir)// || move_dir == WEST)
AM.loc = src.loc
do_transform(AM)
@@ -255,3 +262,94 @@
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
sleep(30)
+/obj/machinery/transformer/equipper
+ name = "Auto-equipper 9000"
+ desc = "Either in employ of people who cannot dress themselves, or Wallace and Gromit."
+ var/selected_outfit = /datum/outfit/job/assistant
+ var/prestrip = TRUE
+
+/obj/machinery/transformer/equipper/do_transform(mob/living/carbon/human/H)
+ if(!istype(H))
+ return
+ if(!ispath(selected_outfit, /datum/outfit))
+ to_chat(H, "This equipper is not properly configured! 'selected_outfit': '[selected_outfit]'")
+ return
+
+ if(prestrip)
+ for(var/obj/item/I in H)
+ if(istype(I, /obj/item/weapon/implant))
+ continue
+ if(istype(I, /obj/item/organ))
+ continue
+ qdel(I)
+
+ H.equipOutfit(selected_outfit)
+ H.species.after_equip_job(null, H)
+
+/obj/machinery/transformer/transmogrifier
+ name = "species transmogrifier"
+ desc = "As promoted in Calvin & Hobbes!"
+ var/target_species = "Human"
+
+
+/obj/machinery/transformer/transmogrifier/do_transform(mob/living/carbon/human/H)
+ if(!istype(H))
+ return
+ if(!(target_species in all_species))
+ to_chat(H, "'[target_species]' is not a valid species!")
+ return
+ H.set_species(target_species)
+
+
+/obj/machinery/transformer/dnascrambler
+ name = "genetic scrambler"
+ desc = "Step right in and become a new you!"
+
+
+/obj/machinery/transformer/dnascrambler/do_transform(mob/living/carbon/human/H)
+ if(!istype(H))
+ return
+
+ scramble(1, H, 100)
+ H.generate_name()
+ H.sync_organ_dna(assimilate = 1)
+ H.update_body(0)
+ H.reset_hair()
+ H.dna.ResetUIFrom(H)
+
+
+/obj/machinery/transformer/gene_applier
+ name = "genetic blueprint applier"
+ desc = "Here begin the clone wars. Upload a template by using a genetics disk on this machine."
+ var/datum/dna/template
+ var/locked = FALSE // For admins sealing the deal
+
+/obj/machinery/transformer/gene_applier/do_transform(mob/living/carbon/human/H)
+ if(!istype(H))
+ return
+ if(!istype(template))
+ to_chat(H, "No genetic template configured!")
+ return
+ var/prev_ue = H.dna.unique_enzymes
+ H.set_species(template.species)
+ H.dna = template.Clone()
+ H.real_name = template.real_name
+ H.sync_organ_dna(assimilate = 0, old_ue = prev_ue)
+ H.UpdateAppearance()
+ domutcheck(H, null, MUTCHK_FORCED)
+ H.update_mutations()
+
+/obj/machinery/transformer/gene_applier/attackby(obj/item/W, mob/living/user, params)
+ if(istype(W, /obj/item/weapon/disk/data))
+ if(locked)
+ to_chat(user, "Access Denied.")
+ return FALSE
+ var/obj/item/weapon/disk/data/D = W
+ if(!D.buf)
+ to_chat(user, "Error: No data found.")
+ return FALSE
+ template = D.buf.dna.Clone()
+ to_chat(user, "Upload of gene template for '[template.real_name]' complete!")
+ return TRUE
+ else
+ return ..()
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index f45daee2af5..e694ac98817 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -146,11 +146,8 @@
product_records.Add(product)
/obj/machinery/vending/Destroy()
- qdel(wires) // qdel
- wires = null
- if(coin)
- qdel(coin) // qdel
- coin = null
+ QDEL_NULL(wires)
+ QDEL_NULL(coin)
return ..()
/obj/machinery/vending/ex_act(severity)
@@ -221,8 +218,8 @@
if(PDA.id)
paid = pay_with_card(PDA.id)
handled = 1
- else if(istype(I, /obj/item/weapon/spacecash))
- var/obj/item/weapon/spacecash/C = I
+ else if(istype(I, /obj/item/stack/spacecash))
+ var/obj/item/stack/spacecash/C = I
paid = pay_with_cash(C, user)
handled = 1
@@ -237,7 +234,7 @@
return
if(istype(I, /obj/item/weapon/screwdriver) && anchored)
- playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1)
+ playsound(loc, I.usesound, 50, 1)
panel_open = !panel_open
to_chat(user, "You [panel_open ? "open" : "close"] the maintenance panel.")
overlays.Cut()
@@ -264,7 +261,7 @@
I.loc = src
coin = I
categories |= CAT_COIN
- to_chat(user, "\blue You insert the [I] into the [src]")
+ to_chat(user, "You insert the [I] into the [src]")
nanomanager.update_uis(src)
return
else if(istype(I, refill_canister) && refill_canister != null)
@@ -297,8 +294,8 @@
*
* 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.get_total())
+/obj/machinery/vending/proc/pay_with_cash(obj/item/stack/spacecash/cashmoney, mob/user)
+ if(currently_vending.price > cashmoney.amount)
// This is not a status display message, since it's something the character
// themselves is meant to see BEFORE putting the money in
to_chat(usr, "[bicon(cashmoney)] That is not enough money.")
@@ -310,12 +307,7 @@
// 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.get_total() - currently_vending.price
- usr.unEquip(cashmoney)
- qdel(cashmoney)
-
- if(left)
- dispense_cash(left, src.loc, user)
+ cashmoney.use(currently_vending.price)
// Vending machines have no idea who paid with cash
credit_purchase("(cash)")
@@ -391,7 +383,7 @@
/obj/machinery/vending/attack_ai(mob/user)
return attack_hand(user)
-
+
/obj/machinery/vending/attack_ghost(mob/user)
return attack_hand(user)
@@ -582,7 +574,7 @@
/obj/machinery/vending/proc/stock(var/datum/data/vending_product/R, var/mob/user)
if(panel_open)
- to_chat(user, "\blue You stock the [src] with \a [R.product_name]")
+ to_chat(user, "You stock the [src] with \a [R.product_name]")
R.amount++
updateUsrDialog()
@@ -1167,13 +1159,6 @@
/obj/item/weapon/screwdriver = 5,/obj/item/weapon/crowbar = 5)
//everything after the power cell had no amounts, I improvised. -Sayu
-
-/obj/machinery/vending/eva
- name = "\improper Hardsuit Kits"
- desc = "Conversion kits for your alien hardsuit needs."
- products = list(/obj/item/device/modkit = 6,/obj/item/device/modkit/tajaran = 6,/obj/item/device/modkit/unathi = 6,/obj/item/device/modkit/skrell = 6,/obj/item/device/modkit/vox = 6)
-
-
/obj/machinery/vending/sustenance
name = "\improper Sustenance Vendor"
desc = "A vending machine which vends food, as required by section 47-C of the NT's Prisoner Ethical Treatment Agreement."
diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm
index e075457a9e5..e27a97c796c 100644
--- a/code/game/machinery/washing_machine.dm
+++ b/code/game/machinery/washing_machine.dm
@@ -199,7 +199,7 @@
/obj/machinery/washing_machine/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
/*if(istype(W,/obj/item/weapon/screwdriver))
panel = !panel
- to_chat(user, "\blue you [panel ? "open" : "close"] the [src]'s maintenance panel")*/
+ to_chat(user, "you [panel ? "open" : "close"] the [src]'s maintenance panel")*/
if(istype(W,/obj/item/toy/crayon) ||istype(W,/obj/item/weapon/stamp))
if( state in list( 1, 3, 6 ) )
if(!crayon)
@@ -278,9 +278,9 @@
W.loc = src
state = 3
else
- to_chat(user, "\blue You can't put the item in right now.")
+ to_chat(user, "You can't put the item in right now.")
else
- to_chat(user, "\blue The washing machine is full.")
+ to_chat(user, "The washing machine is full.")
else
..()
update_icon()
@@ -302,7 +302,7 @@
crayon = null
state = 1
if(5)
- to_chat(user, "\red The [src] is busy.")
+ to_chat(user, "The [src] is busy.")
if(6)
state = 7
if(7)
diff --git a/code/game/mecha/combat/phazon.dm b/code/game/mecha/combat/phazon.dm
index 205fb4497cd..5f66ad3a85c 100644
--- a/code/game/mecha/combat/phazon.dm
+++ b/code/game/mecha/combat/phazon.dm
@@ -28,18 +28,18 @@
ME = new /obj/item/mecha_parts/mecha_equipment/gravcatapult
ME.attach(src)
-/obj/mecha/combat/phazon/Bump(var/atom/obstacle)
- if(phasing && get_charge() >= phasing_energy_drain)
- spawn()
- if(can_move)
- can_move = 0
- flick("phazon-phase", src)
- forceMove(get_step(src, dir))
- use_power(phasing_energy_drain)
- sleep(step_in * 3)
- can_move = 1
- else
- . = ..()
+/obj/mecha/combat/phazon/mechstep(direction)
+ . = ..()
+ if(!. && phasing && get_charge() >= phasing_energy_drain)
+ if(can_move)
+ can_move = 0
+ flick("phazon-phase", src)
+ forceMove(get_step(src, direction))
+ use_power(phasing_energy_drain)
+ playsound(src,stepsound,40,1)
+ sleep(step_in * 3)
+ can_move = 1
+ return 1
/obj/mecha/combat/phazon/click_action(atom/target,mob/user)
if(phasing)
@@ -62,7 +62,7 @@
if("Torch")
damtype = "fire"
occupant_message("A torch tip extends from your exosuit's hand, glowing red.")
- if("Toxic injector")
+ if("Toxic Injector")
damtype = "tox"
occupant_message("A bone-chillingly thick plasteel needle protracts from the exosuit's palm.")
playsound(src, 'sound/mecha/mechmove01.ogg', 50, 1)
diff --git a/code/game/mecha/combat/recitence.dm b/code/game/mecha/combat/reticence.dm
similarity index 79%
rename from code/game/mecha/combat/recitence.dm
rename to code/game/mecha/combat/reticence.dm
index 04e1e98c063..19eb34fb448 100644
--- a/code/game/mecha/combat/recitence.dm
+++ b/code/game/mecha/combat/reticence.dm
@@ -1,6 +1,6 @@
-/obj/mecha/combat/recitence
+/obj/mecha/combat/reticence
desc = "A silent, fast, and nigh-invisible miming exosuit. Popular among mimes and mime assassins."
- name = "\improper Recitence"
+ name = "\improper Reticence"
icon_state = "mime"
initial_icon = "mime"
step_in = 2
@@ -9,17 +9,18 @@
deflect_chance = 30
damage_absorption = list("brute"=0.75,"fire"=1,"bullet"=0.8,"laser"=0.7,"energy"=0.85,"bomb"=1)
max_temperature = 15000
- wreckage = /obj/effect/decal/mecha_wreckage/recitence
+ wreckage = /obj/effect/decal/mecha_wreckage/reticence
operation_req_access = list(access_mime)
add_req_access = 0
internal_damage_threshold = 60
max_equip = 3
step_energy_drain = 3
stepsound = null
+ turnsound = null
-/obj/mecha/combat/recitence/loaded/New()
+/obj/mecha/combat/reticence/loaded/New()
..()
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine/silenced
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/mimercd //HAHA IT MAKES WALLS GET IT
- ME.attach(src)
\ No newline at end of file
+ ME.attach(src)
diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm
index 9e2a754bd4c..3f60c56a952 100644
--- a/code/game/mecha/equipment/tools/other_tools.dm
+++ b/code/game/mecha/equipment/tools/other_tools.dm
@@ -185,7 +185,7 @@
icon_state = "repair_droid"
origin_tech = "magnets=3;programming=3"
equip_cooldown = 20
- energy_drain = 100
+ energy_drain = 50
range = 0
var/health_boost = 1
var/icon/droid_overlay
diff --git a/code/game/mecha/equipment/tools/work_tools.dm b/code/game/mecha/equipment/tools/work_tools.dm
index 23e18d53a0d..7a0e388b39e 100644
--- a/code/game/mecha/equipment/tools/work_tools.dm
+++ b/code/game/mecha/equipment/tools/work_tools.dm
@@ -194,6 +194,8 @@
range = MELEE|RANGED
var/mode = 0 //0 - deconstruct, 1 - wall or floor, 2 - airlock.
var/canRwall = 0
+ toolspeed = 1
+ usesound = 'sound/items/Deconstruct.ogg'
/obj/item/mecha_parts/mecha_equipment/rcd/New()
rcd_list += src
@@ -224,7 +226,7 @@
if(do_after_cooldown(W))
chassis.spark_system.start()
W.ChangeTurf(/turf/simulated/floor/plating)
- playsound(W, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(W, usesound, 50, 1)
else if(istype(target, /turf/simulated/floor))
var/turf/simulated/floor/F = target
occupant_message("Deconstructing [target]...")
@@ -232,27 +234,27 @@
chassis.spark_system.start()
F.ChangeTurf(/turf/space)
F.air_update_turf()
- playsound(F, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(F, usesound, 50, 1)
else if(istype(target, /obj/machinery/door/airlock))
occupant_message("Deconstructing [target]...")
if(do_after_cooldown(target))
chassis.spark_system.start()
qdel(target)
- playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(target, usesound, 50, 1)
if(1)
if(istype(target, /turf/space))
var/turf/space/S = target
occupant_message("Building Floor...")
if(do_after_cooldown(S))
S.ChangeTurf(/turf/simulated/floor/plating)
- playsound(S, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(S, usesound, 50, 1)
chassis.spark_system.start()
else if(istype(target, /turf/simulated/floor))
var/turf/simulated/floor/F = target
occupant_message("Building Wall...")
if(do_after_cooldown(F))
F.ChangeTurf(/turf/simulated/wall)
- playsound(F, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(F, usesound, 50, 1)
chassis.spark_system.start()
if(2)
if(istype(target, /turf/simulated/floor))
@@ -261,7 +263,7 @@
chassis.spark_system.start()
var/obj/machinery/door/airlock/T = new /obj/machinery/door/airlock(target)
T.autoclose = 1
- playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(target, usesound, 50, 1)
playsound(target, 'sound/effects/sparks2.ogg', 50, 1)
@@ -283,14 +285,14 @@
/obj/item/mecha_parts/mecha_equipment/mimercd
name = "mounted MRCD"
- desc = "An exosuit-mounted Mime Rapid Construction Device. (Can be attached to: Recitence)"
+ desc = "An exosuit-mounted Mime Rapid Construction Device. (Can be attached to: Reticence)"
icon_state = "mecha_rcd"
origin_tech = "materials=4;bluespace=3;magnets=4;powerstorage=4"
equip_cooldown = 10
energy_drain = 250
range = MELEE|RANGED
-/obj/item/mecha_parts/mecha_equipment/mimercd/can_attach(obj/mecha/combat/recitence/M)
+/obj/item/mecha_parts/mecha_equipment/mimercd/can_attach(obj/mecha/combat/reticence/M)
if(..())
if(istype(M))
return 1
diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm
index 0466aa698c6..a4c7b7d2f5d 100644
--- a/code/game/mecha/equipment/weapons/weapons.dm
+++ b/code/game/mecha/equipment/weapons/weapons.dm
@@ -78,7 +78,7 @@
equip_cooldown = 10
name = "CH-LC \"Solaris\" Laser Cannon"
icon_state = "mecha_laser"
- energy_drain = 40
+ energy_drain = 60
projectile = /obj/item/projectile/beam/laser/heavylaser
fire_sound = 'sound/weapons/lasercannonfire.ogg'
@@ -183,7 +183,7 @@
spawn(20)
if(thingy)
walk(thingy,0)
- for(var/obj/mecha/combat/recitence/R in oview(6, chassis))
+ for(var/obj/mecha/combat/reticence/R in oview(6, chassis))
R.occupant_message("\The [R] has protected you from [chassis]'s HONK at the cost of some power.")
R.use_power(R.get_charge() / 4)
@@ -244,7 +244,7 @@
projectiles = 20
projectile_energy_cost = 50
-/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine/silenced/can_attach(obj/mecha/combat/recitence/M as obj)
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine/silenced/can_attach(obj/mecha/combat/reticence/M as obj)
if(..())
if(istype(M))
return 1
@@ -448,7 +448,7 @@
desc = "A device that shoots resonant plasma bursts at extreme velocity. The blasts are capable of crushing rock and demloishing solid obstacles."
icon_state = "mecha_plasmacutter"
item_state = "plasmacutter"
- energy_drain = 60
+ energy_drain = 30
origin_tech = "materials=3;combat=2;powerstorage=3;plasmatech=3"
projectile = /obj/item/projectile/plasma/adv/mech
fire_sound = 'sound/weapons/laser.ogg'
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index 3da5587b2a4..cd20b68f10d 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -39,7 +39,7 @@
"Gygax",
"Durand",
"H.O.N.K",
- "Recitence",
+ "Reticence",
"Phazon",
"Exosuit Equipment",
"Cyborg Upgrade Modules",
@@ -262,13 +262,13 @@
return 1
return interact(user)
-/obj/machinery/mecha_part_fabricator/interact(mob/user as mob)
+/obj/machinery/mecha_part_fabricator/interact(mob/user)
var/dat, left_part
if(..())
return
user.set_machine(src)
var/turf/exit = get_step(src,SOUTH)
- if(exit.density)
+ if(isliving(user) && exit.density)
visible_message("[bicon(src)] \The [src] beeps, \"Error! Part outlet is obstructed.\"")
return
if(temp)
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 4ec4746a198..1ad2bc83d96 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -334,7 +334,7 @@
else if(istype(obstacle, /obj/structure/grille/))
var/obj/structure/grille/G = obstacle
G.health = (0.25*initial(G.health))
- G.destroyed = 1
+ G.broken = 1
G.icon_state = "[initial(G.icon_state)]-b"
G.density = 0
new /obj/item/stack/rods(get_turf(G.loc))
@@ -491,14 +491,14 @@
take_damage(15)
check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
playsound(loc, 'sound/weapons/slash.ogg', 50, 1, -1)
- to_chat(user, "\red You slash at the armored suit!")
- visible_message("\red The [user] slashes at [name]'s armor!")
+ to_chat(user, "You slash at the armored suit!")
+ visible_message("The [user] slashes at [name]'s armor!")
else
log_append_to_last("Armor saved.")
playsound(loc, 'sound/weapons/slash.ogg', 50, 1, -1)
- to_chat(user, "\green Your claws had no effect!")
- occupant_message("\blue The [user]'s claws are stopped by the armor.")
- visible_message("\blue The [user] rebounds off [name]'s armor!")
+ to_chat(user, "Your claws had no effect!")
+ occupant_message("The [user]'s claws are stopped by the armor.")
+ visible_message("The [user] rebounds off [name]'s armor!")
return
@@ -519,8 +519,8 @@
else
log_append_to_last("Armor saved.")
playsound(loc, 'sound/weapons/slash.ogg', 50, 1, -1)
- occupant_message("\blue The [user]'s attack is stopped by the armor.")
- visible_message("\blue The [user] rebounds off [name]'s armor!")
+ occupant_message("The [user]'s attack is stopped by the armor.")
+ visible_message("The [user] rebounds off [name]'s armor!")
user.create_attack_log("attacked [name]")
return
@@ -629,8 +629,7 @@
else
qdel(cabin_air)
cabin_air = null
- qdel(spark_system)
- spark_system = null
+ QDEL_NULL(spark_system)
mechas_list -= src //global mech list
return ..()
@@ -663,7 +662,7 @@
/obj/mecha/emp_act(severity)
if(get_charge())
- use_power((cell.charge / 2) / severity)
+ use_power((cell.charge/3)/(severity*2))
take_damage(50 / severity, "energy")
log_message("EMP detected", 1)
check_for_internal_damage(list(MECHA_INT_FIRE, MECHA_INT_TEMP_CONTROL, MECHA_INT_CONTROL_LOST, MECHA_INT_SHORT_CIRCUIT), 1)
@@ -734,7 +733,7 @@
// Since having maint protocols available is controllable by the MMI, I see this as a consensual way to remove an MMI without destroying the mech
user.visible_message("[user] begins levering out the MMI from the [src].", "You begin to lever out the MMI from the [src].")
to_chat(occupant, "[user] is prying you out of the exosuit!")
- if(do_after(user,80,target=src))
+ if(do_after(user, 80 * W.toolspeed, target=src))
user.visible_message("[user] pries the MMI out of the [src]!", "You finish removing the MMI from the [src]!")
go_out()
return
@@ -858,11 +857,11 @@
/obj/mecha/emag_act(user as mob)
if(istype(src, /obj/mecha/working/ripley) && emagged == 0)
emagged = 1
- to_chat(usr, "\blue You slide the card through the [src]'s ID slot.")
+ to_chat(usr, "You slide the card through the [src]'s ID slot.")
playsound(loc, "sparks", 100, 1)
desc += "The mech's equipment slots spark dangerously!"
else
- to_chat(usr, "\red The [src]'s ID slot rejects the card.")
+ to_chat(usr, "The [src]'s ID slot rejects the card.")
return
@@ -1048,12 +1047,12 @@
var/obj/machinery/atmospherics/unary/portables_connector/possible_port = locate(/obj/machinery/atmospherics/unary/portables_connector/) in loc
if(possible_port)
if(connect(possible_port))
- occupant_message("\blue [name] connects to the port.")
+ occupant_message("[name] connects to the port.")
verbs += /obj/mecha/verb/disconnect_from_port
verbs -= /obj/mecha/verb/connect_to_port
return
else
- occupant_message("\red [name] failed to connect to the port.")
+ occupant_message("[name] failed to connect to the port.")
return
else
occupant_message("Nothing happens")
@@ -1068,11 +1067,11 @@
if(usr!=occupant)
return
if(disconnect())
- occupant_message("\blue [name] disconnects from the port.")
+ occupant_message("[name] disconnects from the port.")
verbs -= /obj/mecha/verb/disconnect_from_port
verbs += /obj/mecha/verb/connect_to_port
else
- occupant_message("\red [name] is not connected to the port at the moment.")
+ occupant_message("[name] is not connected to the port at the moment.")
/obj/mecha/verb/toggle_lights()
set name = "Toggle Lights"
diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm
index f1641c94b64..b570f17ccfe 100644
--- a/code/game/mecha/mecha_construction_paths.dm
+++ b/code/game/mecha/mecha_construction_paths.dm
@@ -6,22 +6,25 @@
if(istype(used_atom, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/W = used_atom
if(W.remove_fuel(0, user))
- playsound(holder, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(holder, W.usesound, 50, 1)
else
return 0
else if(istype(used_atom, /obj/item/weapon/wrench))
- playsound(holder, 'sound/items/Ratchet.ogg', 50, 1)
+ var/obj/item/weapon/wrench/W = used_atom
+ playsound(holder, W.usesound, 50, 1)
else if(istype(used_atom, /obj/item/weapon/screwdriver))
- playsound(holder, 'sound/items/Screwdriver.ogg', 50, 1)
+ var/obj/item/weapon/screwdriver/S = used_atom
+ playsound(holder, S.usesound, 50, 1)
else if(istype(used_atom, /obj/item/weapon/wirecutters))
- playsound(holder, 'sound/items/Wirecutter.ogg', 50, 1)
+ var/obj/item/weapon/wirecutters/W = used_atom
+ playsound(holder, W.usesound, 50, 1)
else if(istype(used_atom, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = used_atom
if(C.use(4))
- playsound(holder, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(holder, C.usesound, 50, 1)
else
to_chat(user, ("There's not enough cable to finish the task."))
return 0
@@ -38,22 +41,25 @@
if(istype(used_atom, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/W = used_atom
if(W.remove_fuel(0, user))
- playsound(holder, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(holder, W.usesound, 50, 1)
else
return 0
else if(istype(used_atom, /obj/item/weapon/wrench))
- playsound(holder, 'sound/items/Ratchet.ogg', 50, 1)
+ var/obj/item/weapon/wrench/W = used_atom
+ playsound(holder, W.usesound, 50, 1)
else if(istype(used_atom, /obj/item/weapon/screwdriver))
- playsound(holder, 'sound/items/Screwdriver.ogg', 50, 1)
+ var/obj/item/weapon/screwdriver/S = used_atom
+ playsound(holder, S.usesound, 50, 1)
else if(istype(used_atom, /obj/item/weapon/wirecutters))
- playsound(holder, 'sound/items/Wirecutter.ogg', 50, 1)
+ var/obj/item/weapon/wirecutters/W = used_atom
+ playsound(holder, W.usesound, 50, 1)
else if(istype(used_atom, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = used_atom
if(C.use(4))
- playsound(holder, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(holder, C.usesound, 50, 1)
else
to_chat(user, ("There's not enough cable to finish the task."))
return 0
@@ -857,48 +863,48 @@
feedback_inc("mecha_honker_created",1)
return
-/datum/construction/mecha/recitence_chassis
- steps = list(list("key"=/obj/item/mecha_parts/part/recitence_torso),//1
- list("key"=/obj/item/mecha_parts/part/recitence_left_arm),//2
- list("key"=/obj/item/mecha_parts/part/recitence_right_arm),//3
- list("key"=/obj/item/mecha_parts/part/recitence_left_leg),//4
- list("key"=/obj/item/mecha_parts/part/recitence_right_leg),//5
- list("key"=/obj/item/mecha_parts/part/recitence_head)
+/datum/construction/mecha/reticence_chassis
+ steps = list(list("key"=/obj/item/mecha_parts/part/reticence_torso),//1
+ list("key"=/obj/item/mecha_parts/part/reticence_left_arm),//2
+ list("key"=/obj/item/mecha_parts/part/reticence_right_arm),//3
+ list("key"=/obj/item/mecha_parts/part/reticence_left_leg),//4
+ list("key"=/obj/item/mecha_parts/part/reticence_right_leg),//5
+ list("key"=/obj/item/mecha_parts/part/reticence_head)
)
-/datum/construction/mecha/recitence_chassis/action(atom/used_atom,mob/user as mob)
+/datum/construction/mecha/reticence_chassis/action(atom/used_atom,mob/user as mob)
return check_all_steps(used_atom,user)
-/datum/construction/mecha/recitence_chassis/custom_action(step, atom/used_atom, mob/user)
+/datum/construction/mecha/reticence_chassis/custom_action(step, atom/used_atom, mob/user)
user.visible_message("[user] has connected [used_atom] to the [holder].", "You connect [used_atom] to the [holder]")
holder.overlays += used_atom.icon_state + "+o"
qdel(used_atom)
return 1
-/datum/construction/mecha/recitence_chassis/spawn_result()
+/datum/construction/mecha/reticence_chassis/spawn_result()
var/obj/item/mecha_parts/chassis/const_holder = holder
- const_holder.construct = new /datum/construction/mecha/recitence(const_holder)
+ const_holder.construct = new /datum/construction/mecha/reticence(const_holder)
const_holder.density = 1
qdel(src)
return
-/datum/construction/mecha/recitence
- result = "/obj/mecha/combat/recitence"
+/datum/construction/mecha/reticence
+ result = "/obj/mecha/combat/reticence"
steps = list(list("key"=/obj/effect/dummy/mecha_emote_step),//1
list("key"=/obj/item/clothing/suit/suspenders),//2
list("key"=/obj/effect/dummy/mecha_emote_step),//3
list("key"=/obj/item/clothing/mask/gas/mime),//4
list("key"=/obj/effect/dummy/mecha_emote_step),//5
list("key"=/obj/item/clothing/head/beret),//6
- list("key"=/obj/item/weapon/circuitboard/mecha/recitence/targeting),//7
- list("key"=/obj/item/weapon/circuitboard/mecha/recitence/peripherals),//8
- list("key"=/obj/item/weapon/circuitboard/mecha/recitence/main),//9
+ list("key"=/obj/item/weapon/circuitboard/mecha/reticence/targeting),//7
+ list("key"=/obj/item/weapon/circuitboard/mecha/reticence/peripherals),//8
+ list("key"=/obj/item/weapon/circuitboard/mecha/reticence/main),//9
)
-/datum/construction/mecha/recitence/action(atom/used_atom,mob/user)
+/datum/construction/mecha/reticence/action(atom/used_atom,mob/user)
return check_step(used_atom,user)
-/datum/construction/mecha/recitence/custom_action(step, atom/used_atom, mob/user)
+/datum/construction/mecha/reticence/custom_action(step, atom/used_atom, mob/user)
if(!..())
return 0
@@ -929,9 +935,9 @@
qdel(used_atom)
return 1
-/datum/construction/mecha/recitence/spawn_result()
+/datum/construction/mecha/reticence/spawn_result()
..()
- feedback_inc("mecha_recitence_created",1)
+ feedback_inc("mecha_reticence_created",1)
return
/datum/construction/mecha/durand_chassis
diff --git a/code/game/mecha/mecha_parts.dm b/code/game/mecha/mecha_parts.dm
index 60c352c20bd..11fed270bab 100644
--- a/code/game/mecha/mecha_parts.dm
+++ b/code/game/mecha/mecha_parts.dm
@@ -223,14 +223,14 @@
icon_state = "honker_r_leg"
-////////// Recitence
+////////// Reticence
-/obj/item/mecha_parts/chassis/recitence
- name = "Recitence Chassis"
+/obj/item/mecha_parts/chassis/reticence
+ name = "Reticence Chassis"
-/obj/item/mecha_parts/chassis/recitence/New()
+/obj/item/mecha_parts/chassis/reticence/New()
..()
- construct = new /datum/construction/mecha/recitence_chassis(src)
+ construct = new /datum/construction/mecha/reticence_chassis(src)
/obj/effect/dummy/mecha_emote_step
var/emote
@@ -238,37 +238,37 @@
/obj/effect/dummy/mecha_emote_step/New(e)
emote = e
-/obj/item/mecha_parts/chassis/recitence/hear_message(mob/living/M, msg)
- if(!istype(M) || !istype(construct, /datum/construction/mecha/recitence))
+/obj/item/mecha_parts/chassis/reticence/hear_message(mob/living/M, msg)
+ if(!istype(M) || !istype(construct, /datum/construction/mecha/reticence))
return
// is the current step the dummy emote object?
var/list/steps = construct.steps
if(steps[steps.len]["key"] == /obj/effect/dummy/mecha_emote_step)
construct.action(new /obj/effect/dummy/mecha_emote_step(msg), M)
-/obj/item/mecha_parts/part/recitence_torso
- name = "Recitence Torso"
- icon_state = "recitence_harness"
+/obj/item/mecha_parts/part/reticence_torso
+ name = "Reticence Torso"
+ icon_state = "reticence_harness"
-/obj/item/mecha_parts/part/recitence_head
- name = "Recitence Head"
- icon_state = "recitence_head"
+/obj/item/mecha_parts/part/reticence_head
+ name = "Reticence Head"
+ icon_state = "reticence_head"
-/obj/item/mecha_parts/part/recitence_left_arm
- name = "Recitence Left Arm"
- icon_state = "recitence_l_arm"
+/obj/item/mecha_parts/part/reticence_left_arm
+ name = "Reticence Left Arm"
+ icon_state = "reticence_l_arm"
-/obj/item/mecha_parts/part/recitence_right_arm
- name = "Recitence Right Arm"
- icon_state = "recitence_r_arm"
+/obj/item/mecha_parts/part/reticence_right_arm
+ name = "Reticence Right Arm"
+ icon_state = "reticence_r_arm"
-/obj/item/mecha_parts/part/recitence_left_leg
- name = "Recitence Left Leg"
- icon_state = "recitence_l_leg"
+/obj/item/mecha_parts/part/reticence_left_leg
+ name = "Reticence Left Leg"
+ icon_state = "reticence_l_leg"
-/obj/item/mecha_parts/part/recitence_right_leg
- name = "Recitence Right Leg"
- icon_state = "recitence_r_leg"
+/obj/item/mecha_parts/part/reticence_right_leg
+ name = "Reticence Right Leg"
+ icon_state = "reticence_r_leg"
////////// Phazon
@@ -455,19 +455,19 @@
name = "Circuit board (H.O.N.K Central Control module)"
icon_state = "mainboard"
-/obj/item/weapon/circuitboard/mecha/recitence
+/obj/item/weapon/circuitboard/mecha/reticence
origin_tech = "programming=4"
-/obj/item/weapon/circuitboard/mecha/recitence/peripherals
- name = "circuit board (Reticience Peripherals Control module)"
+/obj/item/weapon/circuitboard/mecha/reticence/peripherals
+ name = "circuit board (Reticence Peripherals Control module)"
icon_state = "mcontroller"
-/obj/item/weapon/circuitboard/mecha/recitence/targeting
- name = "circuit board (Reticience Weapon Control and Targeting module)"
+/obj/item/weapon/circuitboard/mecha/reticence/targeting
+ name = "circuit board (Reticence Weapon Control and Targeting module)"
icon_state = "mcontroller"
-/obj/item/weapon/circuitboard/mecha/recitence/main
- name = "circuit board (Reticience Central Control module)"
+/obj/item/weapon/circuitboard/mecha/reticence/main
+ name = "circuit board (Reticence Central Control module)"
icon_state = "mainboard"
/obj/item/weapon/circuitboard/mecha/odysseus
diff --git a/code/game/mecha/mecha_wreckage.dm b/code/game/mecha/mecha_wreckage.dm
index 6bd600eaaa7..af6f2f20b3f 100644
--- a/code/game/mecha/mecha_wreckage.dm
+++ b/code/game/mecha/mecha_wreckage.dm
@@ -35,7 +35,7 @@
var/obj/item/weapon/weldingtool/WT = W
if(salvage_num <= 0)
user.visible_message("[user] begins to slice apart the now completely stripped [src].", "You begin to slice apart the [src].", "You hear the sound of a welder nearby.")
- if(WT.remove_fuel(0,user) && do_after(user,80,target=src))
+ if(WT.remove_fuel(0,user) && do_after(user, 80 * WT.toolspeed, target = src))
user.visible_message("The now-dilapidated [src] falls apart in a clatter.", "As you slice apart the final support structures, the [src] falls apart in a heap.", "You hear metal clanking to the floor.")
new /obj/item/stack/sheet/metal(src.loc)
var/obj/item/stack/rods/rods = new /obj/item/stack/rods(src.loc)
@@ -55,7 +55,7 @@
else
to_chat(user, "You failed to salvage anything valuable from [src].")
else
- to_chat(user, "\blue You need more welding fuel to complete this task.")
+ to_chat(user, "You need more welding fuel to complete this task.")
else if(istype(W, /obj/item/weapon/wirecutters))
if(salvage_num <= 0)
to_chat(user, "You don't see anything that can be cut with [W].")
@@ -118,8 +118,8 @@
name = "Seraph wreckage"
icon_state = "seraph-broken"
-/obj/effect/decal/mecha_wreckage/recitence
- name = "\improper Recitence wreckage"
+/obj/effect/decal/mecha_wreckage/reticence
+ name = "\improper Reticence wreckage"
icon_state = "mime-broken"
/obj/effect/decal/mecha_wreckage/ripley
diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm
index bb5e0237c9b..6c563bb22b3 100644
--- a/code/game/mecha/working/ripley.dm
+++ b/code/game/mecha/working/ripley.dm
@@ -129,7 +129,7 @@
if(href_list["drop_from_cargo"])
var/obj/O = locate(href_list["drop_from_cargo"])
if(O && O in cargo)
- occupant_message("\blue You unload [O].")
+ occupant_message("You unload [O].")
O.loc = get_turf(src)
cargo -= O
var/turf/T = get_turf(O)
diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm
index 19cbbd38c5a..122f1741a3c 100644
--- a/code/game/objects/effects/aliens.dm
+++ b/code/game/objects/effects/aliens.dm
@@ -222,7 +222,7 @@
var/obj/item/weapon/weldingtool/WT = I
if(WT.remove_fuel(0, user))
damage = 15
- playsound(loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(loc, WT.usesound, 100, 1)
health -= damage
healthcheck()
@@ -381,7 +381,7 @@
if(WT.remove_fuel(0, user))
damage = 15
- playsound(loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(loc, WT.usesound, 100, 1)
health -= damage
user.changeNext_move(CLICK_CD_MELEE)
diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm
index 434fec620b8..89baf450720 100644
--- a/code/game/objects/effects/anomalies.dm
+++ b/code/game/objects/effects/anomalies.dm
@@ -19,8 +19,9 @@
var/new_frequency = sanitize_frequency(rand(PUBLIC_LOW_FREQ, PUBLIC_HIGH_FREQ))
aSignal.set_frequency(new_frequency)
poi_list |= src
-
+
/obj/effect/anomaly/Destroy()
+ QDEL_NULL(aSignal)
poi_list.Remove(src)
return ..()
diff --git a/code/game/objects/effects/datacore-effect.dm b/code/game/objects/effects/datacore-effect.dm
deleted file mode 100644
index 65d873666d1..00000000000
--- a/code/game/objects/effects/datacore-effect.dm
+++ /dev/null
@@ -1,228 +0,0 @@
-//This item is not completely unused- the central datacore datum uses it.
-/*
- * This item is completely unused, but removing it will break something in R&D and Radio code causing PDA and Ninja code to fail on compile
- */
-
-/obj/effect/datacore
- name = "datacore"
- var/medical[] = list()
- var/general[] = list()
- var/security[] = list()
- //This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character().
- var/locked[] = list()
-
-
-/obj/effect/datacore/proc/get_manifest(monochrome, OOC)
- var/list/heads = new()
- var/list/sec = new()
- var/list/eng = new()
- var/list/med = new()
- var/list/sci = new()
- var/list/ser = new()
- var/list/sup = new()
- var/list/bot = new()
- var/list/misc = new()
- var/list/isactive = new()
- var/dat = {"
-
-
-
Name
Rank
Activity
- "}
- var/even = 0
- // sort mobs
- for(var/datum/data/record/t in data_core.general)
- var/name = t.fields["name"]
- var/rank = t.fields["rank"]
- var/real_rank = t.fields["real_rank"]
- if(OOC)
- var/active = 0
- for(var/mob/M in player_list)
- if(M.real_name == name && M.client && M.client.inactivity <= 10 * 60 * 10)
- active = 1
- break
- isactive[name] = active ? "Active" : "Inactive"
- else
- isactive[name] = t.fields["p_stat"]
-// to_chat(world, "[name]: [rank]")
- //cael - to prevent multiple appearances of a player/job combination, add a continue after each line
- var/department = 0
- if(real_rank in command_positions)
- heads[name] = rank
- department = 1
- if(real_rank in security_positions)
- sec[name] = rank
- department = 1
- if(real_rank in engineering_positions)
- eng[name] = rank
- department = 1
- if(real_rank in medical_positions)
- med[name] = rank
- department = 1
- if(real_rank in science_positions)
- sci[name] = rank
- department = 1
- if(real_rank in service_positions)
- ser[name] = rank
- department = 1
- if(real_rank in supply_positions)
- sup[name] = rank
- department = 1
- if(real_rank in nonhuman_positions)
- bot[name] = rank
- department = 1
- if(!department && !(name in heads))
- misc[name] = rank
- if(heads.len > 0)
- dat += "
Heads
"
- for(name in heads)
- dat += "
[name]
[heads[name]]
[isactive[name]]
"
- even = !even
- if(sec.len > 0)
- dat += "
Security
"
- for(name in sec)
- dat += "
[name]
[sec[name]]
[isactive[name]]
"
- even = !even
- if(eng.len > 0)
- dat += "
Engineering
"
- for(name in eng)
- dat += "
[name]
[eng[name]]
[isactive[name]]
"
- even = !even
- if(med.len > 0)
- dat += "
Medical
"
- for(name in med)
- dat += "
[name]
[med[name]]
[isactive[name]]
"
- even = !even
- if(sci.len > 0)
- dat += "
Science
"
- for(name in sci)
- dat += "
[name]
[sci[name]]
[isactive[name]]
"
- even = !even
- if(ser.len > 0)
- dat += "
Service
"
- for(name in ser)
- dat += "
[name]
[ser[name]]
[isactive[name]]
"
- even = !even
- if(sup.len > 0)
- dat += "
Supply
"
- for(name in sup)
- dat += "
[name]
[sup[name]]
[isactive[name]]
"
- even = !even
- // in case somebody is insane and added them to the manifest, why not
- if(bot.len > 0)
- dat += "
Silicon
"
- for(name in bot)
- dat += "
[name]
[bot[name]]
[isactive[name]]
"
- even = !even
- // misc guys
- if(misc.len > 0)
- dat += "
Miscellaneous
"
- for(name in misc)
- dat += "
[name]
[misc[name]]
[isactive[name]]
"
- even = !even
-
- dat += "
"
- dat = replacetext(dat, "\n", "") // so it can be placed on paper correctly
- dat = replacetext(dat, "\t", "")
- return dat
-
-
-/*
-We can't just insert in HTML into the nanoUI so we need the raw data to play with.
-Instead of creating this list over and over when someone leaves their PDA open to the page
-we'll only update it when it changes. The PDA_Manifest global list is zeroed out upon any change
-using /obj/effect/datacore/proc/manifest_inject( ), or manifest_insert( )
-*/
-
-var/global/list/PDA_Manifest = list()
-
-/obj/effect/datacore/proc/get_manifest_json()
- if(PDA_Manifest.len)
- return
- var/heads[0]
- var/sec[0]
- var/eng[0]
- var/med[0]
- var/sci[0]
- var/ser[0]
- var/sup[0]
- var/bot[0]
- var/misc[0]
- for(var/datum/data/record/t in data_core.general)
- var/name = sanitize(t.fields["name"])
- var/rank = sanitize(t.fields["rank"])
- var/real_rank = t.fields["real_rank"]
-
- var/isactive = t.fields["p_stat"]
- var/department = 0
- var/depthead = 0 // Department Heads will be placed at the top of their lists.
- if(real_rank in command_positions)
- heads[++heads.len] = list("name" = name, "rank" = rank, "active" = isactive)
- department = 1
- depthead = 1
- if(rank == "Captain" && heads.len != 1)
- heads.Swap(1, heads.len)
-
- if(real_rank in security_positions)
- sec[++sec.len] = list("name" = name, "rank" = rank, "active" = isactive)
- department = 1
- if(depthead && sec.len != 1)
- sec.Swap(1, sec.len)
-
- if(real_rank in engineering_positions)
- eng[++eng.len] = list("name" = name, "rank" = rank, "active" = isactive)
- department = 1
- if(depthead && eng.len != 1)
- eng.Swap(1, eng.len)
-
- if(real_rank in medical_positions)
- med[++med.len] = list("name" = name, "rank" = rank, "active" = isactive)
- department = 1
- if(depthead && med.len != 1)
- med.Swap(1, med.len)
-
- if(real_rank in science_positions)
- sci[++sci.len] = list("name" = name, "rank" = rank, "active" = isactive)
- department = 1
- if(depthead && sci.len != 1)
- sci.Swap(1, sci.len)
-
- if(real_rank in service_positions)
- ser[++ser.len] = list("name" = name, "rank" = rank, "active" = isactive)
- department = 1
- if(depthead && ser.len != 1)
- ser.Swap(1, ser.len)
-
- if(real_rank in supply_positions)
- sup[++sup.len] = list("name" = name, "rank" = rank, "active" = isactive)
- department = 1
- if(depthead && sup.len != 1)
- sup.Swap(1, sup.len)
-
- if(real_rank in nonhuman_positions)
- bot[++bot.len] = list("name" = name, "rank" = rank, "active" = isactive)
- department = 1
-
- if(!department && !(name in heads))
- misc[++misc.len] = list("name" = name, "rank" = rank, "active" = isactive)
-
-
- PDA_Manifest = list(\
- "heads" = heads,\
- "sec" = sec,\
- "eng" = eng,\
- "med" = med,\
- "sci" = sci,\
- "ser" = ser,\
- "sup" = sup,\
- "bot" = bot,\
- "misc" = misc\
- )
- return
-
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index 48a85e7e704..cfde9ab55a4 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -1,9 +1,8 @@
/obj/effect/decal/cleanable
var/list/random_icon_states = list()
- var/targeted_by = null // Used so cleanbots can't claim a mess.
var/noscoop = 0 //if it has this, don't let it be scooped up
var/noclear = 0 //if it has this, don't delete it when its' scooped up
-
+
/obj/effect/decal/cleanable/proc/can_bloodcrawl_in()
return FALSE
diff --git a/code/game/objects/effects/decals/contraband.dm b/code/game/objects/effects/decals/contraband.dm
index 9c3dd867c74..62395eb3135 100644
--- a/code/game/objects/effects/decals/contraband.dm
+++ b/code/game/objects/effects/decals/contraband.dm
@@ -309,7 +309,7 @@ obj/structure/sign/poster/New(serial,var/subtypeIn = -1)
obj/structure/sign/poster/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/wirecutters))
- playsound(loc, 'sound/items/Wirecutter.ogg', 100, 1)
+ playsound(loc, I.usesound, 100, 1)
if(ruined)
to_chat(user, "You remove the remnants of the poster.")
qdel(src)
diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm
index 3da7bb372d4..1cd105367ed 100644
--- a/code/game/objects/effects/effect_system.dm
+++ b/code/game/objects/effects/effect_system.dm
@@ -337,8 +337,8 @@ steam.start() -- spawns the effect
return
-/obj/effect/effect/bad_smoke/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if(air_group || (height==0)) return 1
+/obj/effect/effect/bad_smoke/CanPass(atom/movable/mover, turf/target, height=0)
+ if(height==0) return 1
if(istype(mover, /obj/item/projectile/beam))
var/obj/item/projectile/beam/B = mover
B.damage = (B.damage/2)
@@ -877,21 +877,22 @@ steam.start() -- spawns the effect
// Similar to smoke, but spreads out more
// metal foams leave behind a foamed metal wall
-/obj/effect/effect/foam
+/obj/structure/foam
name = "foam"
+ icon = 'icons/effects/effects.dmi'
icon_state = "foam"
opacity = 0
anchored = 1
density = 0
layer = OBJ_LAYER + 0.9
mouse_opacity = 0
+ animate_movement = 0
var/amount = 3
var/expand = 1
- animate_movement = 0
var/metal = 0
-/obj/effect/effect/foam/New(loc, var/ismetal=0)
+/obj/structure/foam/New(loc, var/ismetal=0)
..(loc)
icon_state = "[ismetal ? "m":""]foam"
if(!ismetal && reagents)
@@ -918,11 +919,11 @@ steam.start() -- spawns the effect
flick("[icon_state]-disolve", src)
sleep(5)
- delete()
+ qdel(src)
return
// on delete, transfer any reagents to the floor
-/obj/effect/effect/foam/Destroy()
+/obj/structure/foam/Destroy()
if(!metal && reagents)
reagents.handle_reactions()
for(var/atom/A in oview(1, src))
@@ -933,7 +934,7 @@ steam.start() -- spawns the effect
reagents.reaction(A, TOUCH, fraction)
return ..()
-/obj/effect/effect/foam/process()
+/obj/structure/foam/process()
if(--amount < 0)
return
@@ -948,11 +949,11 @@ steam.start() -- spawns the effect
if(!T.Enter(src))
continue
- var/obj/effect/effect/foam/F = locate() in T
+ var/obj/structure/foam/F = locate() in T
if(F)
continue
- F = new /obj/effect/effect/foam(T, metal)
+ F = new /obj/structure/foam(T, metal)
F.amount = amount
if(!metal)
F.create_reagents(15)
@@ -963,15 +964,15 @@ steam.start() -- spawns the effect
// foam disolves when heated
// except metal foams
-/obj/effect/effect/foam/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/foam/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(!metal && prob(max(0, exposed_temperature - 475)))
flick("[icon_state]-disolve", src)
spawn(5)
- delete()
+ qdel(src)
-/obj/effect/effect/foam/Crossed(var/atom/movable/AM)
+/obj/structure/foam/Crossed(var/atom/movable/AM)
if(metal)
return
@@ -1016,13 +1017,13 @@ steam.start() -- spawns the effect
/datum/effect/system/foam_spread/start()
spawn(0)
- var/obj/effect/effect/foam/F = locate() in location
+ var/obj/structure/foam/F = locate() in location
if(F)
F.amount += amount
F.amount = min(F.amount, 27)
return
- F = new /obj/effect/effect/foam(location, metal)
+ F = new /obj/structure/foam(location, metal)
F.amount = amount
if(!metal) // don't carry other chemicals if a metal foam
@@ -1124,8 +1125,7 @@ steam.start() -- spawns the effect
M.visible_message("[M] tears apart \the [src]!");
qdel(src)
-/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
- if(air_group) return 0
+/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target, height=1.5)
return !density
/obj/structure/foamedmetal/CanAtmosPass()
@@ -1155,10 +1155,10 @@ steam.start() -- spawns the effect
s.start()
for(var/mob/M in viewers(5, location))
- to_chat(M, "\red The solution violently explodes.")
+ to_chat(M, "The solution violently explodes.")
for(var/mob/M in viewers(1, location))
if(prob (50 * amount))
- to_chat(M, "\red The explosion knocks you down.")
+ to_chat(M, "The explosion knocks you down.")
M.Weaken(rand(1,5))
return
else
@@ -1181,7 +1181,7 @@ steam.start() -- spawns the effect
flash += (round(amount/4) * flashing_factor)
for(var/mob/M in viewers(8, location))
- to_chat(M, "\red The solution violently explodes.")
+ to_chat(M, "The solution violently explodes.")
explosion(location, devastation, heavy, light, flash)
diff --git a/code/game/objects/effects/explosion_particles.dm b/code/game/objects/effects/explosion_particles.dm
index bb4fb2e8fd2..3334b27a712 100644
--- a/code/game/objects/effects/explosion_particles.dm
+++ b/code/game/objects/effects/explosion_particles.dm
@@ -48,7 +48,6 @@
..()
spawn (10)
qdel(src)
- return
/datum/effect/system/explosion/set_up(turf/loc)
..(loc=loc)
@@ -58,6 +57,11 @@
var/datum/effect/system/expl_particles/P = new/datum/effect/system/expl_particles()
P.set_up(10,location)
P.start()
+
+/datum/effect/system/explosion/smoke
+
+/datum/effect/system/explosion/smoke/start()
+ ..()
spawn(5)
var/datum/effect/system/harmless_smoke_spread/S = new/datum/effect/system/harmless_smoke_spread()
S.set_up(5,0,location,null)
diff --git a/code/game/objects/effects/gibs.dm b/code/game/objects/effects/gibs.dm
index a9e165666fc..5c5005fb6fd 100644
--- a/code/game/objects/effects/gibs.dm
+++ b/code/game/objects/effects/gibs.dm
@@ -25,7 +25,7 @@
proc/Gib(atom/location, var/list/viruses = list(), var/datum/dna/MobDNA = null)
if(gibtypes.len != gibamounts.len || gibamounts.len != gibdirections.len)
- to_chat(world, "\red Gib list length mismatch!")
+ to_chat(world, "Gib list length mismatch!")
return
var/obj/effect/decal/cleanable/blood/gibs/gib = null
diff --git a/code/game/objects/effects/glowshroom.dm b/code/game/objects/effects/glowshroom.dm
index 21ff80df749..b7967ee02cb 100644
--- a/code/game/objects/effects/glowshroom.dm
+++ b/code/game/objects/effects/glowshroom.dm
@@ -1,6 +1,6 @@
//separate dm since hydro is getting bloated already
-/obj/effect/glowshroom
+/obj/structure/glowshroom
name = "glowshroom"
desc = "Mycena Bregprox, a species of mushroom that glows in the dark."
anchored = 1
@@ -10,30 +10,53 @@
icon_state = "glowshroom" //replaced in New
layer = 2.1
var/endurance = 30
- var/potency = 30
var/delay = 1200
var/floor = 0
- var/yield = 3
var/generation = 1
var/spreadIntoAdjacentChance = 60
- light_color = "#006622"
+ var/obj/item/seeds/myseed = /obj/item/seeds/glowshroom
-obj/effect/glowshroom/glowcap
+/obj/structure/glowshroom/glowcap
name = "glowcap"
+ desc = "Mycena Ruthenia, a species of mushroom that, while it does glow in the dark, is not actually bioluminescent."
icon_state = "glowcap"
- light_color = "#8E0300"
+ myseed = /obj/item/seeds/glowshroom/glowcap
-/obj/effect/glowshroom/single
- yield = 0
+/obj/structure/glowshroom/shadowshroom
+ name = "shadowshroom"
+ desc = "Mycena Umbra, a species of mushroom that emits shadow instead of light."
+ icon_state = "shadowshroom"
+ myseed = /obj/item/seeds/glowshroom/shadowshroom
-/obj/effect/glowshroom/examine(mob/user)
+/obj/structure/glowshroom/single/Spread()
+ return
+
+/obj/structure/glowshroom/examine(mob/user)
. = ..()
to_chat(user, "This is a [generation]\th generation [name]!")
-/obj/effect/glowshroom/New()
+/obj/structure/glowshroom/Destroy()
+ QDEL_NULL(myseed)
+ return ..()
+
+/obj/structure/glowshroom/New(loc, obj/item/seeds/newseed, mutate_stats)
..()
- set_light(round(potency/10))
- dir = CalcDir()
+ if(newseed)
+ myseed = newseed.Copy()
+ myseed.forceMove(src)
+ else
+ myseed = new myseed(src)
+ if(mutate_stats) //baby mushrooms have different stats :3
+ myseed.adjust_potency(rand(-3,6))
+ myseed.adjust_yield(rand(-1,2))
+ myseed.adjust_production(rand(-3,6))
+ myseed.adjust_endurance(rand(-3,6))
+ delay = delay - myseed.production * 100 //So the delay goes DOWN with better stats instead of up. :I
+ endurance = myseed.endurance
+ if(myseed.get_gene(/datum/plant_gene/trait/glow))
+ var/datum/plant_gene/trait/glow/G = myseed.get_gene(/datum/plant_gene/trait/glow)
+ set_light(G.glow_range(myseed), G.glow_power(myseed), G.glow_color)
+ setDir(CalcDir())
var/base_icon_state = initial(icon_state)
if(!floor)
switch(dir) //offset to make it be on the wall rather than on the floor
@@ -49,10 +72,12 @@ obj/effect/glowshroom/glowcap
else //if on the floor, glowshroom on-floor sprite
icon_state = "[base_icon_state]f"
- addtimer(src, "Spread", delay)
+ addtimer(src, "Spread", delay, FALSE)
-/obj/effect/glowshroom/proc/Spread()
- for(var/i = 1 to yield)
+/obj/structure/glowshroom/proc/Spread()
+ var/turf/ownturf = get_turf(src)
+ var/shrooms_planted = 0
+ for(var/i in 1 to myseed.yield)
if(prob(1/(generation * generation) * 100))//This formula gives you diminishing returns based on generation. 100% with 1st gen, decreasing to 25%, 11%, 6, 4, 2...
var/list/possibleLocs = list()
var/spreadsIntoAdjacent = FALSE
@@ -61,7 +86,9 @@ obj/effect/glowshroom/glowcap
spreadsIntoAdjacent = TRUE
for(var/turf/simulated/floor/earth in view(3,src))
- if(spreadsIntoAdjacent || !locate(/obj/effect/glowshroom) in view(1,earth))
+ if(!ownturf.CanAtmosPass(earth))
+ continue
+ if(spreadsIntoAdjacent || !locate(/obj/structure/glowshroom) in view(1,earth))
possibleLocs += earth
CHECK_TICK
@@ -72,7 +99,7 @@ obj/effect/glowshroom/glowcap
var/shroomCount = 0 //hacky
var/placeCount = 1
- for(var/obj/effect/glowshroom/shroom in newLoc)
+ for(var/obj/structure/glowshroom/shroom in newLoc)
shroomCount++
for(var/wallDir in cardinal)
var/turf/isWall = get_step(newLoc,wallDir)
@@ -81,16 +108,18 @@ obj/effect/glowshroom/glowcap
if(shroomCount >= placeCount)
continue
- var/obj/effect/glowshroom/child = new type(newLoc)//The baby mushrooms have different stats :3
- child.potency = max(potency + rand(-3,6), 0)
- child.yield = max(yield + rand(-1,2), 0)
- child.delay = max(delay + rand(-30,60), 0)
- child.endurance = max(endurance + rand(-3,6), 1)
+ var/obj/structure/glowshroom/child = new type(newLoc, myseed, TRUE)
child.generation = generation + 1
+ shrooms_planted++
CHECK_TICK
+ else
+ shrooms_planted++ //if we failed due to generation, don't try to plant one later
+ if(shrooms_planted < myseed.yield) //if we didn't get all possible shrooms planted, try again later
+ myseed.yield -= shrooms_planted
+ addtimer(src, "Spread", delay, FALSE)
-/obj/effect/glowshroom/proc/CalcDir(turf/location = loc)
+/obj/structure/glowshroom/proc/CalcDir(turf/location = loc)
var/direction = 16
for(var/wallDir in cardinal)
@@ -98,7 +127,7 @@ obj/effect/glowshroom/glowcap
if(newTurf.density)
direction |= wallDir
- for(var/obj/effect/glowshroom/shroom in location)
+ for(var/obj/structure/glowshroom/shroom in location)
if(shroom == src)
continue
if(shroom.floor) //special
@@ -122,13 +151,13 @@ obj/effect/glowshroom/glowcap
floor = 1
return 1
-/obj/effect/glowshroom/attackby(obj/item/I, mob/user)
+/obj/structure/glowshroom/attackby(obj/item/I, mob/user)
..()
if(I.damtype != STAMINA)
endurance -= I.force
CheckEndurance()
-/obj/effect/glowshroom/ex_act(severity)
+/obj/structure/glowshroom/ex_act(severity)
switch(severity)
if(1)
qdel(src)
@@ -139,11 +168,11 @@ obj/effect/glowshroom/glowcap
if(prob(5))
qdel(src)
-/obj/effect/glowshroom/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/glowshroom/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300)
endurance -= 5
CheckEndurance()
-/obj/effect/glowshroom/proc/CheckEndurance()
+/obj/structure/glowshroom/proc/CheckEndurance()
if(endurance <= 0)
- qdel(src)
\ No newline at end of file
+ qdel(src)
diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm
index 7ff80f248da..e5b1098e2d0 100644
--- a/code/game/objects/effects/landmarks.dm
+++ b/code/game/objects/effects/landmarks.dm
@@ -20,6 +20,9 @@
wizardstart += loc
qdel(src)
+ if("avatarspawn")
+ avatarspawn += loc
+
if("JoinLate")
latejoin += loc
qdel(src)
@@ -251,7 +254,7 @@
new /obj/item/clothing/mask/gas/sexymime(src.loc)
new /obj/item/clothing/under/sexymime(src.loc)
qdel(src)
-
+
/obj/effect/landmark/ruin
var/datum/map_template/ruin/ruin_template
diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm
index c3facb6ccbe..17029920dd3 100644
--- a/code/game/objects/effects/mines.dm
+++ b/code/game/objects/effects/mines.dm
@@ -6,6 +6,7 @@
icon = 'icons/obj/weapons.dmi'
icon_state = "uglyminearmed"
var/triggered = 0
+ var/faction = "syndicate"
/obj/effect/mine/proc/mineEffect(mob/living/victim)
to_chat(victim, "*click*")
@@ -15,6 +16,8 @@
return
if(isanimal(AM))
var/mob/living/simple_animal/SA = AM
+ if(faction && (faction in SA.faction))
+ return
if(!SA.flying)
triggermine(SA)
else
diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm
index b9804e7d9a5..5972d75f3dd 100644
--- a/code/game/objects/effects/spawners/lootdrop.dm
+++ b/code/game/objects/effects/spawners/lootdrop.dm
@@ -121,6 +121,7 @@
/obj/item/weapon/wirecutters = 10,
/obj/item/weapon/wrench = 40,
/obj/item/weapon/relic = 35,
+ /obj/item/weaponcrafting/receiver = 20,
/obj/item/clothing/shoes/brown = 30,
/obj/item/seeds/ambrosia/deus = 10,
/obj/item/seeds/ambrosia = 20,
@@ -148,7 +149,7 @@
/obj/item/weapon/implanter/storage = 1,
/obj/item/toy/cards/deck/syndicate = 2,
/obj/item/weapon/storage/secure/briefcase/syndie = 2,
- "" = 90
+ "" = 70
)
/obj/effect/spawner/lootdrop/crate_spawner // for ruins
@@ -192,7 +193,7 @@
/obj/item/weapon/stock_parts/matter_bin = 1,
/obj/item/weapon/stock_parts/micro_laser = 1,
/obj/item/weapon/stock_parts/scanning_module = 1,
- /obj/item/weapon/spacecash/c200 = 1,
+ /obj/item/stack/spacecash/c200 = 1,
/obj/item/weapon/airlock_electronics = 1,
/obj/item/weapon/gun/energy/kinetic_accelerator = 1,
/obj/item/pizzabox = 3,
diff --git a/code/game/objects/effects/spawners/random_barrier.dm b/code/game/objects/effects/spawners/random_barrier.dm
new file mode 100644
index 00000000000..3fd81bcf9b0
--- /dev/null
+++ b/code/game/objects/effects/spawners/random_barrier.dm
@@ -0,0 +1,65 @@
+/obj/effect/spawner/random_barrier
+ name = "random tile"
+ var/list/result = list(
+ /turf/simulated/floor/plasteel = 1,
+ /turf/simulated/wall = 1,
+ /obj/structure/falsewall = 1,
+ /obj/effect/spawner/window/reinforced = 1,
+ /obj/machinery/door/airlock = 1,
+ /obj/machinery/door/airlock/welded = 1,
+ /obj/structure/barricade/wooden = 1)
+
+// This needs to come before the initialization wave because
+// the thing it creates might need to be initialized too
+/obj/effect/spawner/random_barrier/New()
+ . = ..()
+ var/turf/T = get_turf(src)
+ if(!T)
+ log_runtime(EXCEPTION("Barrier spawner placed in nullspace!"), src)
+ return
+ var/thing_to_place = pickweight(result)
+ if(ispath(thing_to_place, /turf))
+ T.ChangeTurf(thing_to_place)
+ else
+ new thing_to_place(T)
+ qdel(src)
+
+/obj/effect/spawner/random_barrier/wall_probably
+ name = "probably a wall"
+ result = list(
+ /turf/simulated/wall = 9,
+ /obj/structure/falsewall = 1)
+
+/obj/effect/spawner/random_barrier/floor_probably
+ name = "probably a floor"
+ result = list(
+ /turf/simulated/floor/plasteel = 3,
+ /turf/simulated/wall = 1)
+
+/obj/effect/spawner/random_barrier/obstruction
+ name = "obstruction"
+ result = list(
+ /turf/simulated/wall = 1,
+ /obj/structure/falsewall = 1,
+ /obj/structure/barricade/wooden = 1,
+ /obj/machinery/door/airlock/welded = 1)
+
+/obj/effect/spawner/random_barrier/possibly_welded_airlock // these have no access restrictions, so for internal maintenance only
+ name = "possibly welded airlock"
+ result = list(
+ /obj/machinery/door/airlock = 3,
+ /obj/machinery/door/airlock/welded = 1)
+
+/obj/effect/spawner/random_spawners/grille_often
+ name = "grille often"
+ result = list(
+ /obj/structure/grille = 8,
+ /obj/structure/grille/broken = 4,
+ /turf/simulated/floor/plating = 2)
+
+/obj/effect/spawner/random_spawners/grille_maybe
+ name = "grille maybe"
+ result = list(
+ /obj/structure/grille = 2,
+ /obj/structure/grille/broken = 2,
+ /turf/simulated/floor/plating = 5)
diff --git a/code/game/objects/effects/spawners/random_spawners.dm b/code/game/objects/effects/spawners/random_spawners.dm
new file mode 100644
index 00000000000..621c8799cc2
--- /dev/null
+++ b/code/game/objects/effects/spawners/random_spawners.dm
@@ -0,0 +1,110 @@
+/obj/effect/spawner/random_spawners
+ name = "random spawners"
+ icon = 'icons/mob/screen_gen.dmi'
+ icon_state = "x2"
+ color = "#00FF00"
+ var/list/result = list(
+ /turf/simulated/floor/plasteel = 1,
+ /turf/simulated/floor/plating = 1,
+ /obj/effect/decal/cleanable/blood/splatter = 1,
+ /obj/effect/decal/cleanable/blood/oil = 1,
+ /obj/effect/decal/cleanable/fungus = 1)
+
+// This needs to come before the initialization wave because
+// the thing it creates might need to be initialized too
+/obj/effect/spawner/random_spawners/New()
+ . = ..()
+ var/turf/T = get_turf(src)
+ if(!T)
+ log_runtime(EXCEPTION("Spawner placed in nullspace!"), src)
+ return
+ var/thing_to_place = pickweight(result)
+ if(ispath(thing_to_place, /turf))
+ T.ChangeTurf(thing_to_place)
+ else
+ new thing_to_place(T)
+ qdel(src)
+
+/obj/effect/spawner/random_spawners/blood_maybe
+ name = "blood maybe"
+ result = list(
+ /turf/simulated/floor/plating = 20,
+ /obj/effect/decal/cleanable/blood/splatter = 1)
+
+/obj/effect/spawner/random_spawners/blood_often
+ name = "blood often"
+ result = list(
+ /turf/simulated/floor/plating = 5,
+ /obj/effect/decal/cleanable/blood/splatter = 1)
+
+/obj/effect/spawner/random_spawners/oil_maybe
+ name = "oil maybe"
+ result = list(
+ /turf/simulated/floor/plating = 20,
+ /obj/effect/decal/cleanable/blood/oil = 1)
+
+/obj/effect/spawner/random_spawners/oil_maybe
+ name = "oil often"
+ result = list(
+ /turf/simulated/floor/plating = 5,
+ /obj/effect/decal/cleanable/blood/oil = 1)
+
+/obj/effect/spawner/random_spawners/wall_rusted_probably
+ name = "rusted wall probably"
+ result = list(
+ /turf/simulated/wall = 2,
+ /turf/simulated/wall/rust = 7)
+
+/obj/effect/spawner/random_spawners/wall_rusted_maybe
+ name = "rusted wall maybe"
+ result = list(
+ /turf/simulated/wall = 7,
+ /turf/simulated/wall/rust = 1)
+
+/obj/effect/spawner/random_spawners/cobweb_left_frequent
+ name = "cobweb left frequent"
+ result = list(
+ /turf/simulated/floor/plating = 1,
+ /obj/effect/decal/cleanable/cobweb = 1)
+
+/obj/effect/spawner/random_spawners/cobweb_right_frequent
+ name = "cobweb right frequent"
+ result = list(
+ /turf/simulated/floor/plating = 1,
+ /obj/effect/decal/cleanable/cobweb2 = 1)
+
+/obj/effect/spawner/random_spawners/cobweb_left_rare
+ name = "cobweb left rare"
+ result = list(
+ /turf/simulated/floor/plating = 10,
+ /obj/effect/decal/cleanable/cobweb = 1)
+
+/obj/effect/spawner/random_spawners/cobweb_right_rare
+ name = "cobweb right rare"
+ result = list(
+ /turf/simulated/floor/plating = 10,
+ /obj/effect/decal/cleanable/cobweb2 = 1)
+
+/obj/effect/spawner/random_spawners/dirt_frequent
+ name = "dirt frequent"
+ result = list(
+ /turf/simulated/floor/plating = 1,
+ /obj/effect/decal/cleanable/dirt = 1)
+
+/obj/effect/spawner/random_spawners/dirt_rare
+ name = "dirt rare"
+ result = list(
+ /turf/simulated/floor/plating = 10,
+ /obj/effect/decal/cleanable/dirt = 1)
+
+/obj/effect/spawner/random_spawners/fungus_maybe
+ name = "rusted wall maybe"
+ result = list(
+ /turf/simulated/wall = 7,
+ /obj/effect/decal/cleanable/fungus = 1)
+
+/obj/effect/spawner/random_spawners/fungus_probably
+ name = "rusted wall maybe"
+ result = list(
+ /turf/simulated/wall = 1,
+ /obj/effect/decal/cleanable/fungus = 7)
diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm
index 8443ac90f17..0a9f49cd2d0 100644
--- a/code/game/objects/effects/spiders.dm
+++ b/code/game/objects/effects/spiders.dm
@@ -1,14 +1,19 @@
//generic procs copied from obj/effect/alien
-/obj/effect/spider
+/obj/structure/spider
name = "web"
desc = "it's stringy and sticky"
icon = 'icons/effects/effects.dmi'
anchored = 1
density = 0
var/health = 15
+ var/master_commander = null
+
+/obj/structure/spider/Destroy()
+ master_commander = null
+ return ..()
//similar to weeds, but only barfed out by nurses manually
-/obj/effect/spider/ex_act(severity)
+/obj/structure/spider/ex_act(severity)
switch(severity)
if(1.0)
qdel(src)
@@ -20,7 +25,7 @@
qdel(src)
return
-/obj/effect/spider/attackby(var/obj/item/weapon/W, var/mob/user, params)
+/obj/structure/spider/attackby(var/obj/item/weapon/W, var/mob/user, params)
if(W.attack_verb.len)
visible_message("[user] has [pick(W.attack_verb)] \the [src] with \the [W]!")
else
@@ -33,34 +38,34 @@
if(WT.remove_fuel(0, user))
damage = 15
- playsound(loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(loc, WT.usesound, 100, 1)
health -= damage
healthcheck()
-/obj/effect/spider/bullet_act(var/obj/item/projectile/Proj)
+/obj/structure/spider/bullet_act(var/obj/item/projectile/Proj)
..()
health -= Proj.damage
healthcheck()
-/obj/effect/spider/proc/healthcheck()
+/obj/structure/spider/proc/healthcheck()
if(health <= 0)
qdel(src)
-/obj/effect/spider/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/spider/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300)
health -= 5
healthcheck()
-/obj/effect/spider/stickyweb
+/obj/structure/spider/stickyweb
icon_state = "stickyweb1"
-/obj/effect/spider/stickyweb/New()
+/obj/structure/spider/stickyweb/New()
if(prob(50))
icon_state = "stickyweb2"
-/obj/effect/spider/stickyweb/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if(air_group || (height==0)) return 1
+/obj/structure/spider/stickyweb/CanPass(atom/movable/mover, turf/target, height=0)
+ if(height==0) return 1
if(istype(mover, /mob/living/simple_animal/hostile/poison/giant_spider))
return 1
else if(istype(mover, /mob/living))
@@ -71,33 +76,32 @@
return prob(30)
return 1
-/obj/effect/spider/eggcluster
+/obj/structure/spider/eggcluster
name = "egg cluster"
desc = "They seem to pulse slightly with an inner life"
icon_state = "eggs"
var/amount_grown = 0
var/player_spiders = 0
var/faction = list()
- var/master_commander = null
-/obj/effect/spider/eggcluster/New()
+/obj/structure/spider/eggcluster/New()
pixel_x = rand(3,-3)
pixel_y = rand(3,-3)
processing_objects.Add(src)
-/obj/effect/spider/eggcluster/process()
+/obj/structure/spider/eggcluster/process()
amount_grown += rand(0,2)
if(amount_grown >= 100)
var/num = rand(3,12)
for(var/i=0, i[src] dies!")
new /obj/effect/decal/cleanable/spiderling_remains(src.loc)
qdel(src)
-/obj/effect/spider/spiderling/healthcheck()
+/obj/structure/spider/spiderling/healthcheck()
if(health <= 0)
die()
-/obj/effect/spider/spiderling/process()
+/obj/structure/spider/spiderling/process()
if(travelling_in_vent)
if(istype(src.loc, /turf))
travelling_in_vent = 0
@@ -217,16 +224,16 @@
icon_state = "greenshatter"
anchored = 1
-/obj/effect/spider/cocoon
+/obj/structure/spider/cocoon
name = "cocoon"
desc = "Something wrapped in silky spider web"
icon_state = "cocoon1"
health = 60
-/obj/effect/spider/cocoon/New()
+/obj/structure/spider/cocoon/New()
icon_state = pick("cocoon1","cocoon2","cocoon3")
-/obj/effect/spider/cocoon/Destroy()
+/obj/structure/spider/cocoon/Destroy()
src.visible_message("\The [src] splits open.")
for(var/atom/movable/A in contents)
A.loc = src.loc
diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm
index 9e36faae088..4aea96c167b 100644
--- a/code/game/objects/explosion.dm
+++ b/code/game/objects/explosion.dm
@@ -1,6 +1,6 @@
//TODO: Flash range does nothing currently
-/proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, ignorecap = 0, flame_range = 0 ,silent = 0)
+/proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, ignorecap = 0, flame_range = 0 ,silent = 0, smoke = 1)
src = null //so we don't abort once src is deleted
epicenter = get_turf(epicenter)
@@ -64,9 +64,14 @@
M << 'sound/effects/explosionfar.ogg'
if(heavy_impact_range > 1)
- var/datum/effect/system/explosion/E = new/datum/effect/system/explosion()
- E.set_up(epicenter)
- E.start()
+ if(smoke)
+ var/datum/effect/system/explosion/smoke/E = new/datum/effect/system/explosion/smoke()
+ E.set_up(epicenter)
+ E.start()
+ else
+ var/datum/effect/system/explosion/E = new/datum/effect/system/explosion()
+ E.set_up(epicenter)
+ E.start()
var/x0 = epicenter.x
var/y0 = epicenter.y
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index b34cc09ca89..a2eff8a2aa1 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -19,6 +19,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
var/r_speed = 1.0
var/health = null
var/hitsound = null
+ var/usesound = null
var/w_class = 3
var/slot_flags = 0 //This is used to determine on which slots an item can fit.
pass_flags = PASSTABLE
@@ -54,12 +55,14 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
var/strip_delay = DEFAULT_ITEM_STRIP_DELAY
var/put_on_delay = DEFAULT_ITEM_PUTON_DELAY
var/breakouttime = 0
-
+ var/flags_cover = 0 //for flags such as GLASSESCOVERSEYES
var/flags_size = 0 //flag, primarily used for clothing to determine if a fatty can wear something or not.
var/block_chance = 0
var/hit_reaction_chance = 0 //If you want to have something unrelated to blocking/armour piercing etc. Maybe not needed, but trying to think ahead/allow more freedom
+ var/toolspeed = 1 // If this item is a tool, the speed multiplier
+
/* Species-specific sprites, concept stolen from Paradise//vg/.
ex:
sprite_sheets = list(
@@ -388,22 +391,22 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
if(!usr.canmove || usr.stat || usr.restrained() || !Adjacent(usr))
return
if((!istype(usr, /mob/living/carbon)) || (istype(usr, /mob/living/carbon/brain)))//Is humanoid, and is not a brain
- to_chat(usr, "\red You can't pick things up!")
+ to_chat(usr, "You can't pick things up!")
return
if( usr.stat || usr.restrained() )//Is not asleep/dead and is not restrained
- to_chat(usr, "\red You can't pick things up!")
+ to_chat(usr, "You can't pick things up!")
return
if(src.anchored) //Object isn't anchored
- to_chat(usr, "\red You can't pick that up!")
+ to_chat(usr, "You can't pick that up!")
return
if(!usr.hand && usr.r_hand) //Right hand is not full
- to_chat(usr, "\red Your right hand is full.")
+ to_chat(usr, "Your right hand is full.")
return
if(usr.hand && usr.l_hand) //Left hand is not full
- to_chat(usr, "\red Your left hand is full.")
+ to_chat(usr, "Your left hand is full.")
return
if(!istype(src.loc, /turf)) //Object is on a turf
- to_chat(usr, "\red You can't pick that up!")
+ to_chat(usr, "You can't pick that up!")
return
//All checks are done, time to pick it up!
usr.UnarmedAttack(src)
@@ -429,9 +432,9 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
var/mob/living/carbon/human/H = M
if(istype(H) && ( \
- (H.head && H.head.flags & HEADCOVERSEYES) || \
- (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
- (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
+ (H.head && H.head.flags_cover & HEADCOVERSEYES) || \
+ (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || \
+ (H.glasses && H.glasses.flags_cover & GLASSESCOVERSEYES) \
))
// you can't stab someone in the eyes wearing a mask!
to_chat(user, "You're going to need to remove that mask/helmet/glasses first!")
diff --git a/code/game/objects/items/ashtray.dm b/code/game/objects/items/ashtray.dm
index 8ce5ecc288f..c7d283908d7 100644
--- a/code/game/objects/items/ashtray.dm
+++ b/code/game/objects/items/ashtray.dm
@@ -59,14 +59,14 @@
die()
return
if(contents.len)
- src.visible_message("\red [src] slams into [hit_atom] spilling its contents!")
+ src.visible_message("[src] slams into [hit_atom] spilling its contents!")
for(var/obj/item/clothing/mask/cigarette/O in contents)
O.loc = src.loc
icon_state = icon_empty
return ..()
/obj/item/ashtray/proc/die()
- src.visible_message("\red [src] shatters spilling its contents!")
+ src.visible_message("[src] shatters spilling its contents!")
for(var/obj/item/clothing/mask/cigarette/O in contents)
O.loc = src.loc
icon_state = icon_broken
diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm
index e7443755978..c52aa0e1792 100644
--- a/code/game/objects/items/bodybag.dm
+++ b/code/game/objects/items/bodybag.dm
@@ -126,7 +126,7 @@
MouseDrop(over_object, src_location, over_location)
if((over_object == usr && (in_range(src, usr) || usr.contents.Find(src))))
if(!ishuman(usr)) return
- to_chat(usr, "\red You can't fold that up anymore..")
+ to_chat(usr, "You can't fold that up anymore..")
..()
attackby(W as obj, mob/user as mob, params)
@@ -135,5 +135,5 @@
src.locked = !src.locked
to_chat(user, "The controls are now [src.locked ? "locked." : "unlocked."]")
else
- to_chat(user, "\red Access denied.")
+ to_chat(user, "Access denied.")
return
\ No newline at end of file
diff --git a/code/game/objects/items/control_wand.dm b/code/game/objects/items/control_wand.dm
index 4c2c5420d1a..95cf94a3a1e 100644
--- a/code/game/objects/items/control_wand.dm
+++ b/code/game/objects/items/control_wand.dm
@@ -19,9 +19,7 @@
ID.access = get_region_accesses(region_access)
/obj/item/weapon/door_remote/Destroy()
- if(ID)
- qdel(ID)
- ID = null
+ QDEL_NULL(ID)
return ..()
/obj/item/weapon/door_remote/attack_self(mob/user)
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index 2a2237559fb..3852d67e6ff 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -10,6 +10,7 @@
w_class = 1
slot_flags = SLOT_BELT | SLOT_EARS
attack_verb = list("attacked", "coloured")
+ toolspeed = 1
var/colour = "#FF0000" //RGB
var/drawtype = "rune"
var/list/graffiti = list("body","amyjon","face","matt","revolution","engie","guy","end","dwarf","uboa","up","down","left","right","heart","borgsrogue","voxpox","shitcurity","catbeast","hieroglyphs1","hieroglyphs2","hieroglyphs3","security","syndicate1","syndicate2","nanotrasen","lie","valid","arrowleft","arrowright","arrowup","arrowdown","chicken","hailcrab","brokenheart","peace","scribble","scribble2","scribble3","skrek","squish","tunnelsnake","yip","youaredead")
@@ -86,7 +87,7 @@
else if(graffiti.Find(drawtype))
temp = "graffiti"
to_chat(user, "You start drawing a [temp] on the [target.name].")
- if(instant || do_after(user, 50, target = target))
+ if(instant || do_after(user, 50 * toolspeed, target = target))
var/obj/effect/decal/cleanable/crayon/C = new /obj/effect/decal/cleanable/crayon(target,colour,drawtype,temp)
C.add_hiddenprint(user)
to_chat(user, "You finish drawing [temp].")
diff --git a/code/game/objects/items/dehy_carp.dm b/code/game/objects/items/dehy_carp.dm
index 991d04fbd63..3125c24837a 100644
--- a/code/game/objects/items/dehy_carp.dm
+++ b/code/game/objects/items/dehy_carp.dm
@@ -8,6 +8,11 @@
var/mob/owner = null // Carp doesn't attack owner, set when using in hand
var/owned = 1 // Boolean, no owner to begin with
+
+/obj/item/toy/carpplushie/dehy_carp/Destroy()
+ owner = null
+ return ..()
+
// Attack self
/obj/item/toy/carpplushie/dehy_carp/attack_self(mob/user as mob)
src.add_fingerprint(user) // Anyone can add their fingerprints to it with this
diff --git a/code/game/objects/items/devices/autopsy.dm b/code/game/objects/items/devices/autopsy.dm
index 81e0f05258a..7ebf13e538b 100644
--- a/code/game/objects/items/devices/autopsy.dm
+++ b/code/game/objects/items/devices/autopsy.dm
@@ -1,14 +1,10 @@
-
-//moved these here from code/defines/obj/weapon.dm
-//please preference put stuff where it's easy to find - C
-
/obj/item/weapon/autopsy_scanner
name = "autopsy scanner"
desc = "Extracts information on wounds."
icon = 'icons/obj/autopsy_scanner.dmi'
icon_state = ""
flags = CONDUCT
- w_class = 1
+ w_class = WEIGHT_CLASS_TINY
origin_tech = "materials=1;biotech=1"
var/list/datum/autopsy_data_scanner/wdata = list()
var/list/datum/autopsy_data_scanner/chemtraces = list()
@@ -28,28 +24,23 @@
var/hits = 0
var/time_inflicted = 0
- proc/copy()
- var/datum/autopsy_data/W = new()
- W.weapon = weapon
- W.pretend_weapon = pretend_weapon
- W.damage = damage
- W.hits = hits
- W.time_inflicted = time_inflicted
- return W
+/datum/autopsy_data/proc/copy()
+ var/datum/autopsy_data/W = new()
+ W.weapon = weapon
+ W.pretend_weapon = pretend_weapon
+ W.damage = damage
+ W.hits = hits
+ W.time_inflicted = time_inflicted
+ return W
-/obj/item/weapon/autopsy_scanner/proc/add_data(var/obj/item/organ/external/O)
- if(!O.autopsy_data.len && !O.trace_chemicals.len) return
+/obj/item/weapon/autopsy_scanner/proc/add_data(obj/item/organ/external/O)
+ if(!O.autopsy_data.len && !O.trace_chemicals.len)
+ return
for(var/V in O.autopsy_data)
var/datum/autopsy_data/W = O.autopsy_data[V]
if(!W.pretend_weapon)
- /*
- // the more hits, the more likely it is that we get the right weapon type
- if(prob(50 + W.hits * 10 + W.damage))
- */
-
- // Buffing this stuff up for now!
if(1)
W.pretend_weapon = W.weapon
else
@@ -75,11 +66,8 @@
if(O.trace_chemicals[V] > 0 && !chemtraces.Find(V))
chemtraces += V
-/obj/item/weapon/autopsy_scanner/verb/print_data()
- set src in view(usr, 1)
- set name = "Print Data"
- if(usr.stat || !(istype(usr,/mob/living/carbon/human)))
- to_chat(usr, "No.")
+/obj/item/weapon/autopsy_scanner/attack_self(mob/user)
+ if(!wdata.len && !chemtraces.len)
return
var/scan_data = ""
@@ -101,8 +89,10 @@
var/wname = W.pretend_weapon
- if(wname in weapon_chances) weapon_chances[wname] += W.damage
- else weapon_chances[wname] = max(W.damage, 1)
+ if(wname in weapon_chances)
+ weapon_chances[wname] += W.damage
+ else
+ weapon_chances[wname] = max(W.damage, 1)
total_score+=W.damage
@@ -126,7 +116,8 @@
if(30 to 1000)
damage_desc = "severe"
- if(!total_score) total_score = D.organs_scanned.len
+ if(!total_score)
+ total_score = D.organs_scanned.len
scan_data += "Weapon #[n] "
if(damaging_weapon)
@@ -147,36 +138,19 @@
for(var/chemID in chemtraces)
scan_data += chemID
scan_data += " "
-
- for(var/mob/O in viewers(usr))
- O.show_message("\red \the [src] rattles and prints out a sheet of paper.", 1)
+ user.visible_message("[src] rattles and prints out a sheet of paper.")
playsound(loc, 'sound/goonstation/machines/printer_thermal.ogg', 50, 1)
sleep(10)
- var/obj/item/weapon/paper/P = new(usr.loc)
+ var/obj/item/weapon/paper/P = new(user.loc)
P.name = "Autopsy Data ([target_name])"
P.info = "[scan_data]"
P.overlays += "paper_words"
- if(istype(usr,/mob/living/carbon))
- // place the item in the usr's hand if possible
- if(!usr.r_hand)
- P.loc = usr
- usr.r_hand = P
- P.layer = 20
- P.plane = HUD_PLANE
- else if(!usr.l_hand)
- P.loc = usr
- usr.l_hand = P
- P.layer = 20
- P.plane = HUD_PLANE
+ user.put_in_hands(P)
- if(istype(usr,/mob/living/carbon/human))
- usr:update_inv_l_hand()
- usr:update_inv_r_hand()
-
-/obj/item/weapon/autopsy_scanner/attack(mob/living/carbon/human/M as mob, mob/living/carbon/user as mob)
+/obj/item/weapon/autopsy_scanner/attack(mob/living/carbon/human/M, mob/living/carbon/user)
if(!istype(M))
return
@@ -185,23 +159,18 @@
if(target_name != M.name)
target_name = M.name
- src.wdata = list()
- src.chemtraces = list()
- src.timeofdeath = null
- to_chat(user, "\red A new patient has been registered.. Purging data for previous patient.")
+ wdata.Cut()
+ chemtraces.Cut()
+ timeofdeath = null
+ to_chat(user, "A new patient has been registered. Purging data for previous patient.")
- src.timeofdeath = M.timeofdeath
+ timeofdeath = M.timeofdeath
var/obj/item/organ/external/S = M.get_organ(user.zone_sel.selecting)
if(!S)
- to_chat(usr, "You can't scan this body part.")
+ to_chat(user, "You can't scan this body part.")
return
- if(!S.open)
- to_chat(usr, "You have to cut the limb open first!")
- return
- for(var/mob/O in viewers(M))
- O.show_message("\red [user.name] scans the wounds on [M.name]'s [S.name] with \the [src.name]", 1)
+ M.visible_message("[user] scans the wounds on [M]'s [S] with [src]")
- src.add_data(S)
-
- return 1
+ add_data(S)
+ return 1
\ No newline at end of file
diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm
index 52a9a343e6b..fefb20e90e4 100644
--- a/code/game/objects/items/devices/flash.dm
+++ b/code/game/objects/items/devices/flash.dm
@@ -152,7 +152,7 @@
if(M.stat == CONSCIOUS)
M.mind_initialize() //give them a mind datum if they don't have one.
var/resisted
- if(!isloyal(M))
+ if(!ismindshielded(M))
if(user.mind in ticker.mode.head_revolutionaries)
if(ticker.mode.add_revolutionary(M.mind))
times_used -- //Flashes less likely to burn out for headrevs when used for conversion
diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm
index 216c37e7a51..9ac4897c8f3 100644
--- a/code/game/objects/items/devices/flashlight.dm
+++ b/code/game/objects/items/devices/flashlight.dm
@@ -35,6 +35,7 @@
return 0
on = !on
+ playsound(user, 'sound/weapons/empty.ogg', 100, 1)
update_brightness(user)
for(var/X in actions)
var/datum/action/A = X
@@ -54,8 +55,8 @@
return
var/mob/living/carbon/human/H = M //mob has protective eyewear
- if(istype(H) && ((H.head && H.head.flags & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || (H.glasses && H.glasses.flags & GLASSESCOVERSEYES)))
- to_chat(user, "You're going to need to remove that [(H.head && H.head.flags & HEADCOVERSEYES) ? "helmet" : (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) ? "mask" : "glasses"] first.")
+ if(istype(H) && ((H.head && H.head.flags_cover & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || (H.glasses && H.glasses.flags_cover & GLASSESCOVERSEYES)))
+ to_chat(user, "You're going to need to remove that [(H.head && H.head.flags_cover & HEADCOVERSEYES) ? "helmet" : (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) ? "mask" : "glasses"] first.")
return
if(M == user) //they're using it on themselves
diff --git a/code/game/objects/items/devices/guitar.dm b/code/game/objects/items/devices/guitar.dm
index bb11c5f0a2a..6c0e4645cc9 100644
--- a/code/game/objects/items/devices/guitar.dm
+++ b/code/game/objects/items/devices/guitar.dm
@@ -17,8 +17,7 @@
song.instrumentExt = "ogg"
/obj/item/device/guitar/Destroy()
- qdel(song)
- song = null
+ QDEL_NULL(song)
return ..()
/obj/item/device/guitar/attack_self(mob/user as mob)
diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm
index deb677b23dd..b172ea052f0 100644
--- a/code/game/objects/items/devices/laserpointer.dm
+++ b/code/game/objects/items/devices/laserpointer.dm
@@ -35,9 +35,7 @@
pointer_icon_state = pick("red_laser","green_laser","blue_laser","purple_laser")
/obj/item/device/laser_pointer/Destroy()
- if(diode)
- qdel(diode)
- diode = null
+ QDEL_NULL(diode)
return ..()
/obj/item/device/laser_pointer/upgraded/New()
diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm
index 263f287a823..d38ac3b71ff 100644
--- a/code/game/objects/items/devices/megaphone.dm
+++ b/code/game/objects/items/devices/megaphone.dm
@@ -12,24 +12,22 @@
var/list/insultmsg = list("FUCK EVERYONE!", "I'M A TATER!", "ALL SECURITY TO SHOOT ME ON SIGHT!", "I HAVE A BOMB!", "CAPTAIN IS A COMDOM!", "FOR THE SYNDICATE!")
/obj/item/device/megaphone/attack_self(mob/living/user as mob)
- if(user.client)
- if(user.client.prefs.muted & MUTE_IC)
- to_chat(src, "\red You cannot speak in IC (muted).")
- return
- if(!ishuman(user))
- to_chat(user, "\red You don't know how to use this!")
+ if(user.client && (user.client.prefs.muted & MUTE_IC))
+ to_chat(src, "You cannot speak in IC (muted).")
return
- if(user.silent)
+ if(!ishuman(user))
+ to_chat(user, "You don't know how to use this!")
+ return
+ if(!user.can_speak())
to_chat(user, "You find yourself unable to speak at all.")
return
if(ishuman(user))
var/mob/living/carbon/human/H = user
- if(H && H.mind)
- if(H.mind.miming)
- to_chat(user, "Your vow of silence prevents you from speaking.")
- return
+ if(H && H.mind && H.mind.miming)
+ to_chat(user, "Your vow of silence prevents you from speaking.")
+ return
if(spamcheck)
- to_chat(user, "\red \The [src] needs to recharge!")
+ to_chat(user, "\The [src] needs to recharge!")
return
var/message = input(user, "Shout a message:", "Megaphone") as text|null
@@ -39,28 +37,27 @@
if(!message)
return
message = capitalize(message)
- if((src.loc == user && usr.stat == 0))
+ if((loc == user && !user.incapacitated()))
if(emagged)
if(insults)
saymsg(user, pick(insultmsg))
insults--
else
- to_chat(user, "\red *BZZZZzzzzzt*")
+ to_chat(user, "*BZZZZzzzzzt*")
else
saymsg(user, message)
spamcheck = 1
spawn(20)
spamcheck = 0
- return
/obj/item/device/megaphone/proc/saymsg(mob/living/user as mob, message)
- audible_message("[user] broadcasts, \"[message]\"", hearing_distance = 14)
+ audible_message("[user] broadcasts, \"[message]\"", hearing_distance = 14)
for(var/obj/O in oview(14, get_turf(src)))
- O.hear_talk(user, "[message]")
+ O.hear_talk(user, "[message]")
/obj/item/device/megaphone/emag_act(user as mob)
if(!emagged)
- to_chat(user, "\red You overload \the [src]'s voice synthesizer.")
+ to_chat(user, "You overload \the [src]'s voice synthesizer.")
emagged = 1
insults = rand(1, 3)//to prevent dickflooding
diff --git a/code/game/objects/items/devices/modkit.dm b/code/game/objects/items/devices/modkit.dm
deleted file mode 100644
index 52603b99a0b..00000000000
--- a/code/game/objects/items/devices/modkit.dm
+++ /dev/null
@@ -1,87 +0,0 @@
-#define MODKIT_HELMET 1
-#define MODKIT_SUIT 2
-#define MODKIT_FULL 3
-
-/obj/item/device/modkit
- name = "hardsuit modification kit"
- desc = "A kit containing all the needed tools and parts to modify a hardsuit for another user."
- icon_state = "modkit"
- var/parts = MODKIT_FULL
- var/target_species = "Human"
-
- var/list/permitted_types = list(
- /obj/item/clothing/head/helmet/space/rig,
- /obj/item/clothing/suit/space/rig
- )
-
-/obj/item/device/modkit/afterattack(obj/O, mob/user as mob, proximity)
- if(!proximity)
- return
-
- if(!target_species)
- return //it shouldn't be null, okay?
-
- if(!parts)
- to_chat(user, "This kit has no parts for this modification left.")
- user.unEquip(src)
- qdel(src)
- return
-
- var/allowed = 0
- for(var/permitted_type in permitted_types)
- if(istype(O, permitted_type))
- allowed = 1
-
- var/obj/item/clothing/I = O
- if(!istype(I) || !allowed)
- to_chat(user, "[src] is unable to modify that.")
- return
-
- var/excluding = ("exclude" in I.species_restricted)
- var/in_list = (target_species in I.species_restricted)
- if(excluding ^ in_list)
- to_chat(user, "[I] is already modified.")
- return
-
- if(!isturf(O.loc))
- to_chat(user, "[O] must be safely placed on the ground for modification.")
- return
-
- playsound(user.loc, 'sound/items/Screwdriver.ogg', 100, 1)
-
- user.visible_message("\red [user] opens \the [src] and modifies \the [O].","\red You open \the [src] and modify \the [O].")
-
- I.refit_for_species(target_species)
-
- if(istype(I, /obj/item/clothing/head/helmet))
- parts &= ~MODKIT_HELMET
- if(istype(I, /obj/item/clothing/suit))
- parts &= ~MODKIT_SUIT
-
- if(!parts)
- user.unEquip(src)
- qdel(src)
-
-/obj/item/device/modkit/examine(mob/user)
- ..(user)
- to_chat(user, "It looks as though it modifies hardsuits to fit [target_species] users.")
-
-/obj/item/device/modkit/tajaran
- name = "Tajaran hardsuit modification kit"
- desc = "A kit containing all the needed tools and parts to modify a hardsuit for another user. This one looks like it's meant for Tajaran."
- target_species = "Tajaran"
-
-/obj/item/device/modkit/unathi
- name = "Unathi hardsuit modification kit"
- desc = "A kit containing all the needed tools and parts to modify a hardsuit for another species. This one looks like it's meant for Unathi."
- target_species = "Unathi"
-
-/obj/item/device/modkit/skrell
- name = "Skrell hardsuit modification kit"
- desc = "A kit containing all the needed tools and parts to modify a hardsuit for another species. This one looks like it's meant for Skrell."
- target_species = "Skrell"
-
-/obj/item/device/modkit/vox
- name = "Vox hardsuit modification kit"
- desc = "A kit containing all the needed tools and parts to modify a hardsuit for another species. This one looks like it's meant for Vox."
- target_species = "Vox"
\ No newline at end of file
diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm
index 742afb83c81..4483a920355 100644
--- a/code/game/objects/items/devices/multitool.dm
+++ b/code/game/objects/items/devices/multitool.dm
@@ -1,3 +1,7 @@
+#define PROXIMITY_NONE ""
+#define PROXIMITY_ON_SCREEN "_red"
+#define PROXIMITY_NEAR "_yellow"
+
/**
* Multitool -- A multitool is used for hacking electronic devices.
* TO-DO -- Using it as a power measurement tool for cables etc. Nannek.
@@ -10,13 +14,15 @@
icon_state = "multitool"
flags = CONDUCT
force = 5.0
- w_class = 2
- throwforce = 5.0
- throw_range = 15
+ w_class = WEIGHT_CLASS_SMALL
+ throwforce = 0
+ throw_range = 7
throw_speed = 3
- desc = "You can use this on airlocks or APCs to try to hack them without cutting wires."
materials = list(MAT_METAL=50, MAT_GLASS=20)
- origin_tech = "magnets=1;engineering=1"
+ origin_tech = "magnets=1;engineering=2"
+ toolspeed = 1
+ hitsound = 'sound/weapons/tap.ogg'
+ var/shows_wire_information = FALSE // shows what a wire does if set to TRUE
var/obj/machinery/buffer // simple machine buffer for device linkage
/obj/item/device/multitool/proc/IsBufferA(var/typepath)
@@ -26,40 +32,79 @@
// Syndicate device disguised as a multitool; it will turn red when an AI camera is nearby.
+/obj/item/device/multitool/Destroy()
+ buffer = null
+ return ..()
/obj/item/device/multitool/ai_detect
- var/track_delay = 0
+ var/track_cooldown = 0
+ var/track_delay = 10 //How often it checks for proximity
+ var/detect_state = PROXIMITY_NONE
+ var/rangealert = 8 //Glows red when inside
+ var/rangewarning = 20 //Glows yellow when inside
+ origin_tech = "magnets=1;engineering=2;syndicate=1"
/obj/item/device/multitool/ai_detect/New()
..()
processing_objects += src
-
/obj/item/device/multitool/ai_detect/Destroy()
processing_objects -= src
return ..()
/obj/item/device/multitool/ai_detect/process()
-
- if(track_delay > world.time)
+ if(track_cooldown > world.time)
return
+ detect_state = PROXIMITY_NONE
+ multitool_detect()
+ icon_state = "[initial(icon_state)][detect_state]"
+ track_cooldown = world.time + track_delay
- var/found_eye = 0
-
- for(var/mob/camera/aiEye/A in living_mob_list)
-
- var/turf/our_turf = get_turf(src)
- var/turf/eye_turf = get_turf(A)
-
- if(get_dist(our_turf, eye_turf) < 9)
- found_eye = 1
+/obj/item/device/multitool/ai_detect/proc/multitool_detect()
+ var/turf/our_turf = get_turf(src)
+ for(var/mob/living/silicon/ai/AI in ai_list)
+ if(AI.cameraFollow == src)
+ detect_state = PROXIMITY_ON_SCREEN
break
- if(found_eye)
- icon_state = "[initial(icon_state)]_red"
- else
- icon_state = initial(icon_state)
+ if(!detect_state && cameranet.chunkGenerated(our_turf.x, our_turf.y, our_turf.z))
+ var/datum/camerachunk/chunk = cameranet.getCameraChunk(our_turf.x, our_turf.y, our_turf.z)
+ if(chunk)
+ if(chunk.seenby.len)
+ for(var/mob/camera/aiEye/A in chunk.seenby)
+ var/turf/detect_turf = get_turf(A)
+ if(get_dist(our_turf, detect_turf) < rangealert)
+ detect_state = PROXIMITY_ON_SCREEN
+ break
+ if(get_dist(our_turf, detect_turf) < rangewarning)
+ detect_state = PROXIMITY_NEAR
+ break
- track_delay = world.time + 10 // 1 second
- return
+/obj/item/device/multitool/ai_detect/admin
+ desc = "Used for pulsing wires to test which to cut. Not recommended by doctors. Has a strange tag that says 'Grief in Safety'" //What else should I say for a meme item?
+ track_delay = 5
+ shows_wire_information = TRUE
+/obj/item/device/multitool/ai_detect/admin/multitool_detect()
+ var/turf/our_turf = get_turf(src)
+ for(var/mob/J in urange(rangewarning,our_turf))
+ if(check_rights(R_ADMIN, 0, J))
+ detect_state = PROXIMITY_NEAR
+ var/turf/detect_turf = get_turf(J)
+ if(get_dist(our_turf, detect_turf) < rangealert)
+ detect_state = PROXIMITY_ON_SCREEN
+ break
+
+/obj/item/device/multitool/cyborg
+ name = "multitool"
+ desc = "Optimised and stripped-down version of a regular multitool."
+ toolspeed = 0.5
+
+/obj/item/device/multitool/abductor
+ name = "alien multitool"
+ desc = "An omni-technological interface."
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "multitool"
+ toolspeed = 0.1
+ origin_tech = "magnets=5;engineering=5;abductor=3"
+ shows_wire_information = TRUE
diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm
index ab61008816c..763666f36c7 100644
--- a/code/game/objects/items/devices/paicard.dm
+++ b/code/game/objects/items/devices/paicard.dm
@@ -12,7 +12,7 @@
var/looking_for_personality = 0
var/mob/living/silicon/pai/pai
var/list/faction = list("neutral") // The factions the pAI will inherit from the card
-
+
/obj/item/device/paicard/syndicate
name = "syndicate personal AI device"
faction = list("syndicate")
@@ -33,9 +33,7 @@
pai.ghostize()
qdel(pai)
pai = null
- if(radio)
- qdel(radio)
- radio = null
+ QDEL_NULL(radio)
return ..()
/obj/item/device/paicard/attack_self(mob/user)
@@ -262,7 +260,7 @@
var/delta = (world.time / 10) - last_request
if(request_cooldown > delta)
var/cooldown_time = round(request_cooldown - ((world.time / 10) - last_request), 1)
- to_chat(usr, "\red The request system is currently offline. Please wait another [cooldown_time] seconds.")
+ to_chat(usr, "The request system is currently offline. Please wait another [cooldown_time] seconds.")
return
last_request = world.time / 10
looking_for_personality = 1
@@ -330,7 +328,7 @@
/obj/item/device/paicard/proc/alertUpdate()
var/turf/T = get_turf_or_move(loc)
for(var/mob/M in viewers(T))
- M.show_message("\blue [src] flashes a message across its screen, \"Additional personalities available for download.\"", 3, "\blue [src] bleeps electronically.", 2)
+ M.show_message("[src] flashes a message across its screen, \"Additional personalities available for download.\"", 3, "[src] bleeps electronically.", 2)
/obj/item/device/paicard/emp_act(severity)
for(var/mob/M in src)
diff --git a/code/game/objects/items/devices/pizza_bomb.dm b/code/game/objects/items/devices/pizza_bomb.dm
index 836da188bba..093d7481c51 100644
--- a/code/game/objects/items/devices/pizza_bomb.dm
+++ b/code/game/objects/items/devices/pizza_bomb.dm
@@ -63,7 +63,7 @@
var/chosen_wire = input(user, "OH GOD OH GOD", "WHAT WIRE?!") in wires
if(!in_range(src, usr) || issilicon(usr) || !usr.canmove || usr.restrained())
return
- playsound(src, 'sound/items/Wirecutter.ogg', 50, 1, 1)
+ playsound(src, I.usesound, 50, 1, 1)
user.visible_message("[user] cuts the [chosen_wire] wire!", "You cut the [chosen_wire] wire!")
sleep(5)
if(chosen_wire == correct_wire)
@@ -84,8 +84,8 @@
to_chat(user, "You can't see the box well enough to cut the wires out.")
return
user.visible_message("[user] starts removing the payload and wires from \the [src].")
- if(do_after(user, 40, target = src))
- playsound(src, 'sound/items/Wirecutter.ogg', 50, 1, 1)
+ if(do_after(user, 40 * I.toolspeed, target = src))
+ playsound(src, I.usesound, 50, 1, 1)
user.unEquip(src)
user.visible_message("[user] removes the insides of \the [src]!")
var/obj/item/stack/cable_coil/C = new /obj/item/stack/cable_coil(src.loc)
diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm
index 25e975fa920..65093361197 100644
--- a/code/game/objects/items/devices/powersink.dm
+++ b/code/game/objects/items/devices/powersink.dm
@@ -13,7 +13,7 @@
materials = list(MAT_METAL=750)
origin_tech = "powerstorage=3;syndicate=5"
var/drain_rate = 1600000 // amount of power to drain per tick
- var/apc_drain_rate = 5000 // Max. amount drained from single APC. In Watts.
+ var/apc_drain_rate = 50 // Max. amount drained from single APC. In Watts.
var/dissipation_rate = 20000 // Passive dissipation of drained power. In Watts.
var/power_drained = 0 // Amount of power drained.
var/max_power = 1e10 // Detonation point.
@@ -27,6 +27,8 @@
/obj/item/device/powersink/Destroy()
processing_objects.Remove(src)
processing_power_items.Remove(src)
+ PN = null
+ attached = null
return ..()
/obj/item/device/powersink/attackby(var/obj/item/I, var/mob/user)
@@ -110,10 +112,10 @@
if(istype(T.master, /obj/machinery/power/apc))
var/obj/machinery/power/apc/A = T.master
if(A.operating && A.cell)
- var/cur_charge = A.cell.charge / CELLRATE
- var/drain_val = min(apc_drain_rate, cur_charge)
- A.cell.use(drain_val * CELLRATE)
- drained += drain_val
+ A.cell.charge = max(0, A.cell.charge - apc_drain_rate)
+ drained += apc_drain_rate
+ if(A.charging == 2) // If the cell was full
+ A.charging = 1 // It's no longer full
power_drained += drained
return 1
diff --git a/code/game/objects/items/devices/radio/beacon.dm b/code/game/objects/items/devices/radio/beacon.dm
index 5dc67b15478..55f42587104 100644
--- a/code/game/objects/items/devices/radio/beacon.dm
+++ b/code/game/objects/items/devices/radio/beacon.dm
@@ -21,7 +21,7 @@
if(!emagged)
emagged = 1
syndicate = 1
- to_chat(user, "\blue The This beacon now only be locked on to by emagged teleporters!")
+ to_chat(user, "The This beacon now only be locked on to by emagged teleporters!")
/obj/item/device/radio/beacon/hear_talk()
return
@@ -58,7 +58,7 @@
/obj/item/device/radio/beacon/syndicate/attack_self(mob/user as mob)
if(user)
- to_chat(user, "\blue Locked In")
+ to_chat(user, "Locked In")
new /obj/machinery/power/singularity_beacon/syndicate( user.loc )
playsound(src, 'sound/effects/pop.ogg', 100, 1, 1)
qdel(src)
@@ -71,7 +71,7 @@
/obj/item/device/radio/beacon/syndicate/bomb/attack_self(mob/user as mob)
if(user)
- to_chat(user, "\blue Locked In")
+ to_chat(user, "Locked In")
new /obj/machinery/syndicatebomb( user.loc )
playsound(src, 'sound/effects/pop.ogg', 100, 1, 1)
qdel(src)
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index 30e02824cd1..9fd1e40b4f7 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -32,12 +32,8 @@
recalculateChannels(1)
/obj/item/device/radio/headset/Destroy()
- if(keyslot1)
- qdel(keyslot1)
- if(keyslot2)
- qdel(keyslot2)
- keyslot1 = null
- keyslot2 = null
+ QDEL_NULL(keyslot1)
+ QDEL_NULL(keyslot2)
return ..()
/obj/item/device/radio/headset/list_channels(var/mob/user)
@@ -63,7 +59,7 @@
return RADIO_CONNECTION_FAIL
return ..()
-
+
/obj/item/device/radio/headset/is_listening()
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
@@ -71,7 +67,7 @@
return ..()
else if(isanimal(loc) || isAI(loc))
return ..()
-
+
return FALSE
/obj/item/device/radio/headset/alt
diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm
index 12b12c14406..43289678591 100644
--- a/code/game/objects/items/devices/radio/intercom.dm
+++ b/code/game/objects/items/devices/radio/intercom.dm
@@ -138,8 +138,8 @@
if(3)
if(iswirecutter(W) && b_stat && wires.IsAllCut())
to_chat(user, "You cut out the intercoms wiring and disconnect its electronics.")
- playsound(get_turf(src), 'sound/items/Wirecutter.ogg', 50, 1)
- if(do_after(user, 10, target = src))
+ playsound(get_turf(src), W.usesound, 50, 1)
+ if(do_after(user, 10 * W.toolspeed, target = src))
if(buildstage != 3)
return
new /obj/item/stack/cable_coil(get_turf(src),5)
@@ -152,8 +152,8 @@
else return ..()
if(2)
if(isscrewdriver(W))
- playsound(get_turf(src), 'sound/items/Screwdriver.ogg', 50, 1)
- if(do_after(user, 10, target = src))
+ playsound(get_turf(src), W.usesound, 50, 1)
+ if(do_after(user, 10 * W.toolspeed, target = src))
update_icon()
on = 1
b_stat = 0
@@ -170,15 +170,15 @@
if(coil.amount < 5)
to_chat(user, "You need more cable for this!")
return
- if(do_after(user, 10, target = src))
+ if(do_after(user, 10 * coil.toolspeed, target = src))
coil.use(5)
to_chat(user, "You wire \the [src]!")
buildstage = 2
return 1
if(iscrowbar(W))
to_chat(user, "You begin removing the electronics...")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
- if(do_after(user, 10, target = src))
+ playsound(get_turf(src), W.usesound, 50, 1)
+ if(do_after(user, 10 * W.toolspeed, target = src))
if(buildstage != 1)
return
new /obj/item/weapon/intercom_electronics(get_turf(src))
@@ -187,19 +187,19 @@
return 1
if(0)
if(istype(W,/obj/item/weapon/intercom_electronics))
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
- if(do_after(user, 10, target = src))
+ playsound(get_turf(src), W.usesound, 50, 1)
+ if(do_after(user, 10 * W.toolspeed, target = src))
qdel(W)
to_chat(user, "You insert \the [W] into \the [src]!")
buildstage = 1
return 1
if(iswelder(W))
var/obj/item/weapon/weldingtool/WT=W
- playsound(get_turf(src), 'sound/items/Welder.ogg', 50, 1)
+ playsound(get_turf(src), WT.usesound, 50, 1)
if(!WT.remove_fuel(3, user))
to_chat(user, "You're out of welding fuel.")
return 1
- if(do_after(user, 10, target = src))
+ if(do_after(user, 10 * WT.toolspeed, target = src))
to_chat(user, "You cut the intercom frame from the wall!")
new /obj/item/mounted/frame/intercom(get_turf(src))
qdel(src)
@@ -233,6 +233,8 @@
desc = "Looks like a circuit. Probably is."
w_class = 2
materials = list(MAT_METAL=50, MAT_GLASS=50)
+ toolspeed = 1
+ usesound = 'sound/items/Deconstruct.ogg'
/obj/item/device/radio/intercom/locked
var/locked_frequency
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index e144c5d3c50..b48f21a60cd 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -30,7 +30,6 @@ var/global/list/default_medbay_channels = list(
var/frequency = PUB_FREQ //common chat
var/traitor_frequency = 0 //tune to frequency to unlock traitor supplies
var/canhear_range = 3 // the range which mobs can hear this radio from
- var/obj/item/device/radio/patch_link = null
var/datum/wires/radio/wires = null
var/b_stat = 0
var/broadcasting = 0
@@ -54,14 +53,14 @@ var/global/list/default_medbay_channels = list(
var/list/internal_channels
-/obj/item/device/radio
var/datum/radio_frequency/radio_connection
var/list/datum/radio_frequency/secure_radio_connections = new
- proc/set_frequency(new_frequency)
- radio_controller.remove_object(src, frequency)
- frequency = new_frequency
- radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT)
+
+/obj/item/device/radio/proc/set_frequency(new_frequency)
+ radio_controller.remove_object(src, frequency)
+ frequency = new_frequency
+ radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT)
/obj/item/device/radio/New()
@@ -74,14 +73,13 @@ var/global/list/default_medbay_channels = list(
global_radios |= src
/obj/item/device/radio/Destroy()
- qdel(wires)
- wires = null
+ QDEL_NULL(wires)
if(radio_controller)
radio_controller.remove_object(src, frequency)
for(var/ch_name in channels)
radio_controller.remove_object(src, radiochannels[ch_name])
- patch_link = null
global_radios -= src
+ follow_target = null
return ..()
@@ -94,7 +92,7 @@ var/global/list/default_medbay_channels = list(
secure_radio_connections[ch_name] = radio_controller.add_object(src, radiochannels[ch_name], RADIO_CHAT)
/obj/item/device/radio/attack_ghost(mob/user)
- return ui_interact(user)
+ return interact(user)
/obj/item/device/radio/attack_self(mob/user as mob)
user.set_machine(src)
@@ -180,11 +178,6 @@ var/global/list/default_medbay_channels = list(
/mob/dead/observer/has_internal_radio_channel_access(var/mob/user, var/list/req_one_accesses)
return can_admin_interact()
-/obj/item/device/radio/proc/text_wires()
- if(b_stat)
- return wires.GetInteractWindow()
- return
-
/obj/item/device/radio/proc/ToggleBroadcast()
broadcasting = !broadcasting && !(wires.IsIndexCut(WIRE_TRANSMIT) || wires.IsIndexCut(WIRE_SIGNAL))
@@ -242,7 +235,6 @@ var/global/list/default_medbay_channels = list(
var/datum/radio_frequency/connection = null
if(channel && channels && channels.len > 0)
if(channel == "department")
-// to_chat(world, "DEBUG: channel=\"[channel]\" switching to \"[channels[1]]\"")
channel = channels[1]
connection = secure_radio_connections[channel]
else
@@ -259,9 +251,8 @@ var/global/list/default_medbay_channels = list(
Broadcast_Message(connection, A,
0, "*garbled automated announcement*", src,
message, from, "Automated Announcement", from, "synthesized voice",
- 4, 0, zlevel, connection.frequency, follow_target=follow_target)
+ 4, 0, zlevel, connection.frequency, follow_target = follow_target)
qdel(A)
- return
// Just a dummy mob used for making announcements, so we don't create AIs to do this
// I'm not sure who thought that was a good idea. -- Crazylemon
@@ -278,7 +269,7 @@ var/global/list/default_medbay_channels = list(
/mob/living/automatedannouncer/Destroy()
if(lifetime_timer)
deltimer(lifetime_timer)
- ..()
+ return ..()
/mob/living/automatedannouncer/proc/autocleanup()
log_runtime(EXCEPTION("An announcer somehow managed to outlive the radio! Deleting!"), src, list("Message: '[message]'"))
@@ -322,7 +313,7 @@ var/global/list/default_medbay_channels = list(
actually transmit large mass. Headsets are the only radio devices capable
of sending subspace transmissions to the Communications Satellite.
- A headset sends a signal to a subspace listener/reciever elsewhere in space,
+ A headset sends a signal to a subspace listener/receiver elsewhere in space,
the signal gets processed and logged, and an audible transmission gets sent
to each individual headset.
*/
@@ -403,6 +394,7 @@ var/global/list/default_medbay_channels = list(
// Identity-associated tags:
"mob" = M, // store a reference to the mob
"mobtype" = M.type, // the mob's type
+ "race" = signal.get_race(M),
"realname" = real_name, // the mob's real name
"name" = displayname, // the mob's display name
"job" = jobname, // the mob's job
@@ -464,6 +456,7 @@ var/global/list/default_medbay_channels = list(
"mob" = M, // store a reference to the mob
"mobtype" = M.type, // the mob's type
+ "race" = signal.get_race(M), // text to show next to mob in comms log console
"realname" = real_name, // the mob's real name
"name" = displayname, // the mob's display name
"job" = jobname, // the mob's job
@@ -562,7 +555,7 @@ var/global/list/default_medbay_channels = list(
var/range = receive_range(freq, level)
if(range > -1)
return get_mobs_in_view(canhear_range, src)
-
+
/obj/item/device/radio/proc/is_listening()
var/is_listening = TRUE
if(!on)
@@ -573,20 +566,20 @@ var/global/list/default_medbay_channels = list(
is_listening = FALSE
return is_listening
-
+
/obj/item/device/radio/proc/send_announcement()
if(is_listening())
return get_mobs_in_view(canhear_range, src)
-
+
return null
/obj/item/device/radio/examine(mob/user, var/distance = -1)
. = ..(user, distance)
if((in_range(src, user) || loc == user))
if(b_stat)
- user.show_message("\blue \the [src] can be attached and modified!")
+ user.show_message("\the [src] can be attached and modified!")
else
- user.show_message("\blue \the [src] can not be modified or attached!")
+ user.show_message("\the [src] can not be modified or attached!")
return .
/obj/item/device/radio/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
@@ -597,9 +590,9 @@ var/global/list/default_medbay_channels = list(
b_stat = !( b_stat )
if(!istype(src, /obj/item/device/radio/beacon))
if(b_stat)
- user.show_message("\blue The radio can now be attached and modified!")
+ user.show_message("The radio can now be attached and modified!")
else
- user.show_message("\blue The radio can no longer be modified or attached!")
+ user.show_message("The radio can no longer be modified or attached!")
updateDialog()
//Foreach goto(83)
add_fingerprint(user)
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 9a9edbb62ad..e5bfcb91279 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -128,24 +128,24 @@ REAGENT SCANNER
/obj/item/device/healthanalyzer/attack(mob/living/M as mob, mob/living/user as mob)
if(( (CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50))
- to_chat(user, text("\red You try to analyze the floor's vitals!"))
+ to_chat(user, text("You try to analyze the floor's vitals!"))
for(var/mob/O in viewers(M, null))
- O.show_message(text("\red [user] has analyzed the floor's vitals!"), 1)
- user.show_message(text("\blue Analyzing Results for The floor:\n\t Overall Status: Healthy"), 1)
- user.show_message(text("\blue \t Damage Specifics: [0]-[0]-[0]-[0]"), 1)
- user.show_message("\blue Key: Suffocation/Toxin/Burns/Brute", 1)
- user.show_message("\blue Body Temperature: ???", 1)
+ O.show_message(text("[user] has analyzed the floor's vitals!"), 1)
+ user.show_message(text("Analyzing Results for The floor:\n\t Overall Status: Healthy"), 1)
+ user.show_message(text("\t Damage Specifics: [0]-[0]-[0]-[0]"), 1)
+ user.show_message("Key: Suffocation/Toxin/Burns/Brute", 1)
+ user.show_message("Body Temperature: ???", 1)
return
user.visible_message("[user] has analyzed [M]'s vitals."," You have analyzed [M]'s vitals.")
if(!istype(M,/mob/living/carbon/human) || M.isSynthetic())
//these sensors are designed for organic life
- user.show_message("\blue Analyzing Results for ERROR:\n\t Overall Status: ERROR")
+ user.show_message("Analyzing Results for ERROR:\n\t Overall Status: ERROR")
user.show_message("\t Key: Suffocation/Toxin/Burns/Brute", 1)
user.show_message("\t Damage Specifics: ? - ? - ? - ?")
- user.show_message("\blue Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1)
- user.show_message("\red Warning: Blood Level ERROR: --% --cl.\blue Type: ERROR")
- user.show_message("\blue Subject's pulse: -- bpm.")
+ user.show_message("Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1)
+ user.show_message("Warning: Blood Level ERROR: --% --cl.Type: ERROR")
+ user.show_message("Subject's pulse: -- bpm.")
return
var/fake_oxy = max(rand(1,40), M.getOxyLoss(), (300 - (M.getToxLoss() + M.getFireLoss() + M.getBruteLoss())))
@@ -155,34 +155,34 @@ REAGENT SCANNER
var/BR = M.getBruteLoss() > 50 ? "[M.getBruteLoss()]" : M.getBruteLoss()
if(M.status_flags & FAKEDEATH)
OX = fake_oxy > 50 ? "[fake_oxy]" : fake_oxy
- user.show_message("\blue Analyzing Results for [M]:\n\t Overall Status: dead")
+ user.show_message("Analyzing Results for [M]:\n\t Overall Status: dead")
else
- user.show_message("\blue Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "dead" : "[M.health]% healthy"]")
+ user.show_message("Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "dead" : "[M.health]% healthy"]")
user.show_message("\t Key: Suffocation/Toxin/Burns/Brute", 1)
user.show_message("\t Damage Specifics: [OX] - [TX] - [BU] - [BR]")
- user.show_message("\blue Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1)
+ user.show_message("Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1)
if(M.timeofdeath && (M.stat == DEAD || (M.status_flags & FAKEDEATH)))
- user.show_message("\blue Time of Death: [worldtime2text(M.timeofdeath)]")
+ user.show_message("Time of Death: [worldtime2text(M.timeofdeath)]")
if(istype(M, /mob/living/carbon/human) && mode == 1)
var/mob/living/carbon/human/H = M
var/list/damaged = H.get_damaged_organs(1,1)
- user.show_message("\blue Localized Damage, Brute/Burn:",1)
+ user.show_message("Localized Damage, Brute/Burn:",1)
if(length(damaged)>0)
for(var/obj/item/organ/external/org in damaged)
- user.show_message(text("\blue \t []: [][]\blue - []", \
+ user.show_message(text("\t []: [][] - []", \
capitalize(org.name), \
- (org.brute_dam > 0) ? "\red [org.brute_dam]" :0, \
+ (org.brute_dam > 0) ? "[org.brute_dam]" :0, \
(org.status & ORGAN_BLEEDING)?"\[Bleeding\]":"\t", \
(org.burn_dam > 0) ? "[org.burn_dam]" :0),1)
else
- user.show_message("\blue \t Limbs are OK.",1)
+ user.show_message("\t Limbs are OK.",1)
OX = M.getOxyLoss() > 50 ? "Severe oxygen deprivation detected" : "Subject bloodstream oxygen level normal"
TX = M.getToxLoss() > 50 ? "Dangerous amount of toxins detected" : "Subject bloodstream toxin level minimal"
BU = M.getFireLoss() > 50 ? "Severe burn damage detected" : "Subject burn injury status O.K"
BR = M.getBruteLoss() > 50 ? "Severe anatomical damage detected" : "Subject brute-force injury status O.K"
if(M.status_flags & FAKEDEATH)
- OX = fake_oxy > 50 ? "\red Severe oxygen deprivation detected\blue" : "Subject bloodstream oxygen level normal"
+ OX = fake_oxy > 50 ? "Severe oxygen deprivation detected" : "Subject bloodstream oxygen level normal"
user.show_message("[OX] | [TX] | [BU] | [BR]")
if(istype(M, /mob/living/carbon))
if(upgraded)
@@ -195,13 +195,13 @@ REAGENT SCANNER
if(M.getCloneLoss())
user.show_message("Subject appears to have [M.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage.")
if(M.has_brain_worms())
- user.show_message("\red Subject suffering from aberrant brain activity. Recommend further scanning.")
+ user.show_message("Subject suffering from aberrant brain activity. Recommend further scanning.")
else if(M.getBrainLoss() >= 100 || istype(M, /mob/living/carbon/human) && !M.get_int_organ(/obj/item/organ/internal/brain))
- user.show_message("\red Subject is brain dead.")
+ user.show_message("Subject is brain dead.")
else if(M.getBrainLoss() >= 60)
- user.show_message("\red Severe brain damage detected. Subject likely to have mental retardation.")
+ user.show_message("Severe brain damage detected. Subject likely to have mental retardation.")
else if(M.getBrainLoss() >= 10)
- user.show_message("\red Significant brain damage detected. Subject may have had a concussion.")
+ user.show_message("Significant brain damage detected. Subject may have had a concussion.")
if(ishuman(M))
var/mob/living/carbon/human/H = M
for(var/name in H.organs_by_name)
@@ -211,20 +211,20 @@ REAGENT SCANNER
var/limb = e.name
if(e.status & ORGAN_BROKEN)
if((e.limb_name in list("l_arm", "r_arm", "l_hand", "r_hand", "l_leg", "r_leg", "l_foot", "r_foot")) && !(e.status & ORGAN_SPLINTED))
- user.show_message("\red Unsecured fracture in subject [limb]. Splinting recommended for transport.")
+ user.show_message("Unsecured fracture in subject [limb]. Splinting recommended for transport.")
if(e.has_infected_wound())
- user.show_message("\red Infected wound detected in subject [limb]. Disinfection recommended.")
+ user.show_message("Infected wound detected in subject [limb]. Disinfection recommended.")
for(var/name in H.organs_by_name)
var/obj/item/organ/external/e = H.organs_by_name[name]
if(!e)
continue
if(e.status & ORGAN_BROKEN)
- user.show_message(text("\red Bone fractures detected. Advanced scanner required for location."), 1)
+ user.show_message(text("Bone fractures detected. Advanced scanner required for location."), 1)
break
for(var/obj/item/organ/external/e in H.organs)
for(var/datum/wound/W in e.wounds) if(W.internal)
- user.show_message(text("\red Internal bleeding detected. Advanced scanner required for location."), 1)
+ user.show_message(text("Internal bleeding detected. Advanced scanner required for location."), 1)
break
if(H.vessel)
var/blood_type = H.get_blood_name()
@@ -232,17 +232,17 @@ REAGENT SCANNER
var/blood_percent = blood_volume / BLOOD_VOLUME_NORMAL
blood_percent *= 100
if(blood_volume <= 500)
- user.show_message("\red Warning: Blood Level LOW: [blood_percent]% [blood_volume]cl")
+ user.show_message("Warning: Blood Level LOW: [blood_percent]% [blood_volume]cl")
else if(blood_volume <= 336)
- user.show_message("\red Warning: Blood Level CRITICAL: [blood_percent]% [blood_volume]cl")
+ user.show_message("Warning: Blood Level CRITICAL: [blood_percent]% [blood_volume]cl")
else
- user.show_message("\blue Blood Level Normal: [blood_percent]% [blood_volume]cl")
+ user.show_message("Blood Level Normal: [blood_percent]% [blood_volume]cl")
if(H.species.exotic_blood)
user.show_message("Subject possesses exotic blood.")
user.show_message("Exotic blood type: [blood_type].")
if(H.heart_attack && H.stat != DEAD)
user.show_message("Subject suffering from heart attack: Apply defibrillator immediately.")
- user.show_message("\blue Subject's pulse: [H.get_pulse(GETPULSE_TOOL)] bpm.")
+ user.show_message("Subject's pulse: [H.get_pulse(GETPULSE_TOOL)] bpm.")
var/implant_detect
for(var/obj/item/organ/internal/cyberimp/CI in H.internal_organs)
if(CI.status == ORGAN_ROBOT)
@@ -253,7 +253,7 @@ REAGENT SCANNER
if(H.gene_stability < 40)
user.show_message("Subject's genes are quickly breaking down!")
else if(H.gene_stability < 70)
- user.show_message("Subject's genes are showing signs of spontenous breakdown.")
+ user.show_message("Subject's genes are showing signs of spontaneous breakdown.")
else if(H.gene_stability < 85)
user.show_message("Subject's genes are showing minor signs of instability.")
else
@@ -279,7 +279,7 @@ REAGENT SCANNER
else
to_chat(user, "You install the upgrade in the [src].")
overlays += "advanced"
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(loc, W.usesound, 50, 1)
upgraded = 1
qdel(W)
@@ -296,6 +296,7 @@ REAGENT SCANNER
desc = "An upgrade unit that can be installed on a health analyzer for expanded functionality."
w_class = 1
origin_tech = "magnets=2;biotech=2"
+ usesound = 'sound/items/Deconstruct.ogg'
/obj/item/device/analyzer
desc = "A hand-held environmental scanner which reports current gas levels."
@@ -530,5 +531,5 @@ REAGENT SCANNER
user.show_message("Possible mutations: [T.slime_mutation[1]], [T.slime_mutation[2]], [T.slime_mutation[3]], [T.slime_mutation[4]]", 1)
user.show_message("Genetic destability: [T.mutation_chance]% chance of mutation on splitting", 1)
if(T.cores > 1)
- user.show_message("Anomalious slime core amount detected", 1)
+ user.show_message("Anomalous slime core amount detected", 1)
user.show_message("Growth progress: [T.amount_grown]/10", 1)
diff --git a/code/game/objects/items/devices/sensor_device.dm b/code/game/objects/items/devices/sensor_device.dm
index e1dd31b79be..79fc2f92457 100644
--- a/code/game/objects/items/devices/sensor_device.dm
+++ b/code/game/objects/items/devices/sensor_device.dm
@@ -12,8 +12,7 @@
crew_monitor = new(src)
/obj/item/device/sensor_device/Destroy()
- qdel(crew_monitor)
- crew_monitor = null
+ QDEL_NULL(crew_monitor)
return ..()
/obj/item/device/sensor_device/attack_self(mob/user as mob)
diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm
index c573e4ff975..6ec1a36504b 100644
--- a/code/game/objects/items/devices/taperecorder.dm
+++ b/code/game/objects/items/devices/taperecorder.dm
@@ -21,9 +21,7 @@
update_icon()
/obj/item/device/taperecorder/Destroy()
- if(mytape)
- qdel(mytape)
- mytape = null
+ QDEL_NULL(mytape)
return ..()
/obj/item/device/taperecorder/examine(mob/user)
@@ -303,7 +301,7 @@
/obj/item/device/tape/attackby(obj/item/I, mob/user)
if(ruined && istype(I, /obj/item/weapon/screwdriver))
to_chat(user, "You start winding the tape back in.")
- if(do_after(user, 120, target = src))
+ if(do_after(user, 120 * I.toolspeed, target = src))
to_chat(user, "You wound the tape back in!")
fix()
else if(istype(I, /obj/item/weapon/pen))
diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm
index ba62169b886..877cb1a5fc9 100644
--- a/code/game/objects/items/devices/transfer_valve.dm
+++ b/code/game/objects/items/devices/transfer_valve.dm
@@ -13,15 +13,9 @@
origin_tech = "materials=1;engineering=1"
/obj/item/device/transfer_valve/Destroy()
- if(tank_one)
- qdel(tank_one)
- tank_one = null
- if(tank_two)
- qdel(tank_two)
- tank_two = null
- if(attached_device)
- qdel(attached_device)
- attached_device = null
+ QDEL_NULL(tank_one)
+ QDEL_NULL(tank_two)
+ QDEL_NULL(attached_device)
attacher = null
return ..()
diff --git a/code/game/objects/items/devices/violin.dm b/code/game/objects/items/devices/violin.dm
index 3ad1e98d6a6..3ef6b2bef85 100644
--- a/code/game/objects/items/devices/violin.dm
+++ b/code/game/objects/items/devices/violin.dm
@@ -18,8 +18,7 @@
song.instrumentExt = "ogg"
/obj/item/device/violin/Destroy()
- qdel(song)
- song = null
+ QDEL_NULL(song)
return ..()
/obj/item/device/violin/initialize()
diff --git a/code/game/objects/items/devices/whistle.dm b/code/game/objects/items/devices/whistle.dm
index c65f0a94355..359dfd82efa 100644
--- a/code/game/objects/items/devices/whistle.dm
+++ b/code/game/objects/items/devices/whistle.dm
@@ -26,6 +26,6 @@
/obj/item/device/hailer/emag_act(user as mob)
if(!emagged)
- to_chat(user, "\red You overload \the [src]'s voice synthesizer.")
+ to_chat(user, "You overload \the [src]'s voice synthesizer.")
emagged = 1
diff --git a/code/game/objects/items/latexballoon.dm b/code/game/objects/items/latexballoon.dm
index 855c97d9b12..a7a45de8cb8 100644
--- a/code/game/objects/items/latexballoon.dm
+++ b/code/game/objects/items/latexballoon.dm
@@ -12,9 +12,7 @@
var/datum/gas_mixture/air_contents = null
/obj/item/latexballon/Destroy()
- if(air_contents)
- qdel(air_contents)
- air_contents = null
+ QDEL_NULL(air_contents)
return ..()
/obj/item/latexballon/proc/blow(obj/item/weapon/tank/tank, mob/user)
diff --git a/code/game/objects/items/mountable_frames/frames.dm b/code/game/objects/items/mountable_frames/frames.dm
index e377cac4015..b8ef9216053 100644
--- a/code/game/objects/items/mountable_frames/frames.dm
+++ b/code/game/objects/items/mountable_frames/frames.dm
@@ -3,6 +3,8 @@
desc = "Place it on a wall."
var/sheets_refunded = 2
var/list/mount_reqs = list() //can contain simfloor, nospace. Used in try_build to see if conditions are needed, then met
+ toolspeed = 1
+ usesound = 'sound/items/Deconstruct.ogg'
/obj/item/mounted/frame/attackby(obj/item/weapon/W, mob/user)
..()
diff --git a/code/game/objects/items/policetape.dm b/code/game/objects/items/policetape.dm
index 907be15d850..f171e984f36 100644
--- a/code/game/objects/items/policetape.dm
+++ b/code/game/objects/items/policetape.dm
@@ -66,13 +66,13 @@ var/list/tape_roll_applications = list()
/obj/item/taperoll/attack_self(mob/user as mob)
if(icon_state == "[icon_base]_start")
start = get_turf(src)
- to_chat(usr, "\blue You place the first end of the [src].")
+ to_chat(usr, "You place the first end of the [src].")
icon_state = "[icon_base]_stop"
else
icon_state = "[icon_base]_start"
end = get_turf(src)
if(start.y != end.y && start.x != end.x || start.z != end.z)
- to_chat(usr, "\blue [src] can only be laid horizontally or vertically.")
+ to_chat(usr, "[src] can only be laid horizontally or vertically.")
return
var/turf/cur = start
@@ -101,7 +101,7 @@ var/list/tape_roll_applications = list()
break
cur = get_step_towards(cur,end)
if(!can_place)
- to_chat(usr, "\blue You can't run \the [src] through that!")
+ to_chat(usr, "You can't run \the [src] through that!")
return
cur = start
@@ -115,7 +115,7 @@ var/list/tape_roll_applications = list()
P.icon_state = "[P.icon_base]_[dir]"
cur = get_step_towards(cur,end)
//is_blocked_turf(var/turf/T)
- to_chat(usr, "\blue You finish placing the [src].")//Git Test
+ to_chat(usr, "You finish placing the [src].")//Git Test
/obj/item/taperoll/afterattack(var/atom/A, mob/user as mob, proximity)
@@ -128,7 +128,7 @@ var/list/tape_roll_applications = list()
P.loc = locate(T.x,T.y,T.z)
P.icon_state = "[src.icon_base]_door"
P.layer = 3.2
- to_chat(user, "\blue You finish placing the [src].")
+ to_chat(user, "You finish placing the [src].")
if(istype(A, /turf/simulated/floor) ||istype(A, /turf/unsimulated/floor))
var/turf/F = A
@@ -147,9 +147,9 @@ var/list/tape_roll_applications = list()
tape_roll_applications[F] |= direction
return
-/obj/item/tape/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+/obj/item/tape/CanPass(atom/movable/mover, turf/target, height=0)
if(!density) return 1
- if(air_group || (height==0)) return 1
+ if(height==0) return 1
if((mover.pass_flags & PASSTABLE || istype(mover, /obj/effect/meteor) || mover.throwing == 1) )
return 1
diff --git a/code/game/objects/items/random_items.dm b/code/game/objects/items/random_items.dm
index 7e15df8676c..5cc0ab739c0 100644
--- a/code/game/objects/items/random_items.dm
+++ b/code/game/objects/items/random_items.dm
@@ -263,7 +263,7 @@
/mob/living/simple_animal/hostile/creature,/mob/living/simple_animal/hostile/pirate/ranged,
/mob/living/simple_animal/hostile/hivebot,/mob/living/simple_animal/hostile/viscerator,/mob/living/simple_animal/hostile/pirate)
- visible_message("\red Something falls out of the [src]!")
+ visible_message("Something falls out of the [src]!")
var/obj/item/weapon/grenade/clusterbuster/C = new(src.loc)
C.prime()
spawn(10)
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index f8ca693bf9c..d99ed06bb6c 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -160,9 +160,9 @@
src.chest = W
src.updateicon()
else if(!W:wires)
- to_chat(user, "\blue You need to attach wires to it first!")
+ to_chat(user, "You need to attach wires to it first!")
else
- to_chat(user, "\blue You need to attach a cell to it first!")
+ to_chat(user, "You need to attach a cell to it first!")
if(istype(W, /obj/item/robot_parts/head))
if(src.head) return
@@ -172,7 +172,7 @@
src.head = W
src.updateicon()
else
- to_chat(user, "\blue You need to attach a flash to it first!")
+ to_chat(user, "You need to attach a flash to it first!")
if(istype(W, /obj/item/device/multitool))
if(check_completion())
@@ -184,10 +184,10 @@
var/obj/item/device/mmi/M = W
if(check_completion())
if(!istype(loc,/turf))
- to_chat(user, "\red You can't put \the [W] in, the frame has to be standing on the ground to be perfectly precise.")
+ to_chat(user, "You can't put \the [W] in, the frame has to be standing on the ground to be perfectly precise.")
return
if(!M.brainmob)
- to_chat(user, "\red Sticking an empty [W] into the frame would sort of defeat the purpose.")
+ to_chat(user, "Sticking an empty [W] into the frame would sort of defeat the purpose.")
return
if(!M.brainmob.key)
@@ -206,15 +206,15 @@
return
if(M.brainmob.stat == DEAD)
- to_chat(user, "\red Sticking a dead [W] into the frame would sort of defeat the purpose.")
+ to_chat(user, "Sticking a dead [W] into the frame would sort of defeat the purpose.")
return
if(M.brainmob.mind in ticker.mode.head_revolutionaries)
- to_chat(user, "\red The frame's firmware lets out a shrill sound, and flashes 'Abnormal Memory Engram'. It refuses to accept the [W].")
+ to_chat(user, "The frame's firmware lets out a shrill sound, and flashes 'Abnormal Memory Engram'. It refuses to accept the [W].")
return
if(jobban_isbanned(M.brainmob, "Cyborg") || jobban_isbanned(M.brainmob,"nonhumandept"))
- to_chat(user, "\red This [W] does not seem to fit.")
+ to_chat(user, "This [W] does not seem to fit.")
return
var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(get_turf(loc), unfinished = 1)
@@ -338,45 +338,45 @@
..()
if(istype(W, /obj/item/weapon/stock_parts/cell))
if(src.cell)
- to_chat(user, "\blue You have already inserted a cell!")
+ to_chat(user, "You have already inserted a cell!")
return
else
user.drop_item()
W.loc = src
src.cell = W
- to_chat(user, "\blue You insert the cell!")
+ to_chat(user, "You insert the cell!")
if(istype(W, /obj/item/stack/cable_coil))
if(src.wires)
- to_chat(user, "\blue You have already inserted wire!")
+ to_chat(user, "You have already inserted wire!")
return
else
var/obj/item/stack/cable_coil/coil = W
coil.use(1)
src.wires = 1.0
- to_chat(user, "\blue You insert the wire!")
+ to_chat(user, "You insert the wire!")
return
/obj/item/robot_parts/head/attackby(obj/item/W as obj, mob/user as mob, params)
..()
if(istype(W, /obj/item/device/flash))
if(istype(user,/mob/living/silicon/robot))
- to_chat(user, "\red How do you propose to do that?")
+ to_chat(user, "How do you propose to do that?")
return
else if(src.flash1 && src.flash2)
- to_chat(user, "\blue You have already inserted the eyes!")
+ to_chat(user, "You have already inserted the eyes!")
return
else if(src.flash1)
user.drop_item()
W.loc = src
src.flash2 = W
- to_chat(user, "\blue You insert the flash into the eye socket!")
+ to_chat(user, "You insert the flash into the eye socket!")
else
user.drop_item()
W.loc = src
src.flash1 = W
- to_chat(user, "\blue You insert the flash into the eye socket!")
+ to_chat(user, "You insert the flash into the eye socket!")
else if(istype(W, /obj/item/weapon/stock_parts/manipulator))
- to_chat(user, "\blue You install some manipulators and modify the head, creating a functional spider-bot!")
+ to_chat(user, "You install some manipulators and modify the head, creating a functional spider-bot!")
new /mob/living/simple_animal/spiderbot(get_turf(loc))
user.drop_item()
qdel(W)
@@ -387,9 +387,9 @@
/obj/item/robot_parts/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W,/obj/item/weapon/card/emag))
if(sabotaged)
- to_chat(user, "\red [src] is already sabotaged!")
+ to_chat(user, "[src] is already sabotaged!")
else
- to_chat(user, "\red You slide [W] into the dataport on [src] and short out the safeties.")
+ to_chat(user, "You slide [W] into the dataport on [src] and short out the safeties.")
sabotaged = 1
return
..()
diff --git a/code/game/objects/items/shooting_range.dm b/code/game/objects/items/shooting_range.dm
index 611a5a3e37e..a46e84d1573 100644
--- a/code/game/objects/items/shooting_range.dm
+++ b/code/game/objects/items/shooting_range.dm
@@ -96,7 +96,7 @@
if(hp <= 0)
for(var/mob/O in oviewers())
if((O.client && !( O.blinded )))
- to_chat(O, "\red [src] breaks into tiny pieces and collapses!")
+ to_chat(O, "[src] breaks into tiny pieces and collapses!")
qdel(src)
// Create a temporary object to represent the damage
diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm
index 1555e9a697f..4c2bbfa3bcd 100644
--- a/code/game/objects/items/stacks/medical.dm
+++ b/code/game/objects/items/stacks/medical.dm
@@ -175,7 +175,7 @@
heal_burn = 12
-//Splits//
+//Splints//
/obj/item/stack/medical/splint
@@ -203,14 +203,14 @@
to_chat(user, "You remove the splint from [H]'s [limb].")
return
if(M == user)
- user.visible_message("[user] starts to apply [src] to [H]'s [limb].", \
- "You start to apply [src] to [H]'s [limb].", \
+ user.visible_message("[user] starts to apply [src] to their [limb].", \
+ "You start to apply [src] to your [limb].", \
"You hear something being wrapped.")
if(!do_mob(user, H, self_delay))
return
else
- user.visible_message("[user] applies [src] to their [limb].", \
- "You apply [src] to your [limb].", \
+ user.visible_message("[user] applies [src] to [H]'s [limb].", \
+ "You apply [src] to [H]'s [limb].", \
"You hear something being wrapped.")
affecting.status |= ORGAN_SPLINTED
diff --git a/code/game/objects/items/stacks/nanopaste.dm b/code/game/objects/items/stacks/nanopaste.dm
index 55e1cc4a722..a21bb504fdc 100644
--- a/code/game/objects/items/stacks/nanopaste.dm
+++ b/code/game/objects/items/stacks/nanopaste.dm
@@ -6,7 +6,7 @@
icon_state = "tube"
origin_tech = "materials=3;engineering=2"
amount = 10
-
+ toolspeed = 1
/obj/item/stack/nanopaste/attack(mob/living/M as mob, mob/user as mob)
if(!istype(M) || !istype(user))
diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm
index e4866856e97..1b63eaae7f0 100644
--- a/code/game/objects/items/stacks/rods.dm
+++ b/code/game/objects/items/stacks/rods.dm
@@ -1,3 +1,7 @@
+var/global/list/datum/stack_recipe/rod_recipes = list ( \
+ new/datum/stack_recipe("grille", /obj/structure/grille, 2, time = 10, one_per_turf = 1, on_floor = 1), \
+ )
+
/obj/item/stack/rods
name = "metal rod"
desc = "Some rods. Can be used for building, or something."
@@ -11,16 +15,18 @@
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL=1000)
- max_amount = 60
+ max_amount = 50
attack_verb = list("hit", "bludgeoned", "whacked")
hitsound = 'sound/weapons/grenadelaunch.ogg'
+ toolspeed = 1
+ usesound = 'sound/items/Deconstruct.ogg'
/obj/item/stack/rods/cyborg
materials = list()
-/obj/item/stack/rods/New(var/loc, var/amount=null)
+/obj/item/stack/rods/New(loc, amount=null)
..()
-
+ recipes = rod_recipes
update_icon()
/obj/item/stack/rods/update_icon()
@@ -30,12 +36,12 @@
else
icon_state = "rods"
-/obj/item/stack/rods/attackby(obj/item/W as obj, mob/user as mob, params)
+/obj/item/stack/rods/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if(get_amount() < 2)
- to_chat(user, "You need at least two rods to do this.")
+ to_chat(user, "You need at least two rods to do this!")
return
if(WT.remove_fuel(0,user))
@@ -45,9 +51,9 @@
// stack was moved into another one on the pile
new_item = locate() in user.loc
- user.visible_message("[user.name] shaped [src] into metal with the weldingtool.", \
- "You shaped [src] into metal with the weldingtool.", \
- "You hear welding.")
+ user.visible_message("[user.name] shape [src] into metal with the welding tool.", \
+ "You shape [src] into metal with the welding tool.", \
+ "You hear welding.")
var/replace = user.get_inactive_hand() == src
use(2)
@@ -57,34 +63,3 @@
user.put_in_hands(new_item)
return
..()
-
-
-/obj/item/stack/rods/attack_self(mob/user as mob)
- src.add_fingerprint(user)
-
- if(!istype(user.loc,/turf)) return 0
-
- if(locate(/obj/structure/grille, usr.loc))
- for(var/obj/structure/grille/G in usr.loc)
- if(G.destroyed)
- G.health = 10
- G.density = 1
- G.destroyed = 0
- G.icon_state = "grille"
- use(1)
- else
- return 1
- else
- if(amount < 2)
- to_chat(user, "\blue You need at least two rods to do this.")
- return
- to_chat(usr, "\blue Assembling grille...")
-
- if(!do_after(usr, 10, target = user))
- return
-
- var /obj/structure/grille/F = new /obj/structure/grille/ ( usr.loc )
- to_chat(usr, "\blue You assemble a grille")
- F.add_fingerprint(usr)
- use(2)
- return
diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm
index 0a52ea4c552..deea1ecc24e 100644
--- a/code/game/objects/items/stacks/sheets/glass.dm
+++ b/code/game/objects/items/stacks/sheets/glass.dm
@@ -22,6 +22,10 @@
origin_tech = "materials=1"
var/created_window = /obj/structure/window/basic
var/full_window = /obj/structure/window/full/basic
+ merge_type = /obj/item/stack/sheet/glass
+
+/obj/item/stack/sheet/glass/fifty
+ amount = 50
/obj/item/stack/sheet/glass/cyborg
materials = list()
@@ -34,7 +38,7 @@
if(istype(W,/obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/CC = W
if(CC.amount < 5)
- to_chat(user, "\b There is not enough wire in this coil. You need 5 lengths.")
+ to_chat(user, "There is not enough wire in this coil. You need 5 lengths.")
return
CC.use(5)
to_chat(user, "You attach wire to the [name].")
@@ -152,6 +156,7 @@
origin_tech = "materials=2"
var/created_window = /obj/structure/window/reinforced
var/full_window = /obj/structure/window/full/reinforced
+ merge_type = /obj/item/stack/sheet/rglass
/obj/item/stack/sheet/rglass/cyborg
materials = list()
diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm
index 46f7b3fb469..3a2d07aa2f6 100644
--- a/code/game/objects/items/stacks/sheets/leather.dm
+++ b/code/game/objects/items/stacks/sheets/leather.dm
@@ -143,7 +143,7 @@ var/global/list/datum/stack_recipe/sinew_recipes = list ( \
/obj/item/stack/sheet/animalhide/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(W.sharp)
user.visible_message("[user] starts cutting hair off \the [src].", "You start cutting the hair off \the [src]...", "You hear the sound of a knife rubbing against flesh.")
- if(do_after(user,50, target = src))
+ if(do_after(user, 50 * W.toolspeed, target = src))
to_chat(user, "You cut the hair from this [src.singular_name].")
//Try locating an exisitng stack on the tile and add to there if possible
for(var/obj/item/stack/sheet/hairlesshide/HS in usr.loc)
diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm
index 7612d3a88ad..ef9781f9a0d 100644
--- a/code/game/objects/items/stacks/sheets/mineral.dm
+++ b/code/game/objects/items/stacks/sheets/mineral.dm
@@ -5,7 +5,6 @@ Mineral Sheets
- Diamond
- Uranium
- Plasma
- - Plastic
- Gold
- Silver
- Bananium
@@ -17,24 +16,41 @@ Mineral Sheets
var/global/list/datum/stack_recipe/sandstone_recipes = list ( \
new/datum/stack_recipe("pile of dirt", /obj/machinery/hydroponics/soil, 3, time = 10, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("sandstone door", /obj/structure/mineral_door/sandstone, 10, one_per_turf = 1, on_floor = 1), \
+ null, \
+ new/datum/stack_recipe("Assistant Statue", /obj/structure/statue/sandstone/assistant, 5, one_per_turf = 1, on_floor = 1), \
+ null, \
+ new/datum/stack_recipe("Breakdown into sand", /obj/item/weapon/ore/glass, 1, one_per_turf = 0, on_floor = 1), \
)
var/global/list/datum/stack_recipe/silver_recipes = list ( \
new/datum/stack_recipe("silver door", /obj/structure/mineral_door/silver, 10, one_per_turf = 1, on_floor = 1), \
null, \
new/datum/stack_recipe("silver tile", /obj/item/stack/tile/mineral/silver, 1, 4, 20), \
+ null, \
+ new/datum/stack_recipe("Janitor Statue", /obj/structure/statue/silver/janitor, 5, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("Sec Officer Statue", /obj/structure/statue/silver/sec, 5, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("Sec Borg Statue", /obj/structure/statue/silver/secborg, 5, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("Med Doctor Statue", /obj/structure/statue/silver/md, 5, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("Med Borg Statue", /obj/structure/statue/silver/medborg, 5, one_per_turf = 1, on_floor = 1), \
)
var/global/list/datum/stack_recipe/diamond_recipes = list ( \
new/datum/stack_recipe("diamond door", /obj/structure/mineral_door/transparent/diamond, 10, one_per_turf = 1, on_floor = 1), \
null, \
new/datum/stack_recipe("diamond tile", /obj/item/stack/tile/mineral/diamond, 1, 4, 20), \
+ null, \
+ new/datum/stack_recipe("Captain Statue", /obj/structure/statue/diamond/captain, 5, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("AI Hologram Statue", /obj/structure/statue/diamond/ai1, 5, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("AI Core Statue", /obj/structure/statue/diamond/ai2, 5, one_per_turf = 1, on_floor = 1), \
)
var/global/list/datum/stack_recipe/uranium_recipes = list ( \
new/datum/stack_recipe("uranium door", /obj/structure/mineral_door/uranium, 10, one_per_turf = 1, on_floor = 1), \
null, \
new/datum/stack_recipe("uranium tile", /obj/item/stack/tile/mineral/uranium, 1, 4, 20), \
+ null, \
+ new/datum/stack_recipe("Nuke Statue", /obj/structure/statue/uranium/nuke, 5, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("Engineer Statue", /obj/structure/statue/uranium/eng, 5, one_per_turf = 1, on_floor = 1), \
)
var/global/list/datum/stack_recipe/gold_recipes = list ( \
@@ -42,6 +58,12 @@ var/global/list/datum/stack_recipe/gold_recipes = list ( \
null, \
new/datum/stack_recipe("gold tile", /obj/item/stack/tile/mineral/gold, 1, 4, 20), \
null, \
+ new/datum/stack_recipe("HoS Statue", /obj/structure/statue/gold/hos, 5, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("HoP Statue", /obj/structure/statue/gold/hop, 5, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("CE Statue", /obj/structure/statue/gold/ce, 5, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("RD Statue", /obj/structure/statue/gold/rd, 5, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("CMO Statue", /obj/structure/statue/gold/cmo, 5, one_per_turf = 1, on_floor = 1), \
+ null, \
new/datum/stack_recipe("Simple Crown", /obj/item/clothing/head/crown, 5), \
)
@@ -49,28 +71,16 @@ var/global/list/datum/stack_recipe/plasma_recipes = list ( \
new/datum/stack_recipe("plasma door", /obj/structure/mineral_door/transparent/plasma, 10, one_per_turf = 1, on_floor = 1), \
null, \
new/datum/stack_recipe("plasma tile", /obj/item/stack/tile/mineral/plasma, 1, 4, 20), \
- )
-
-var/global/list/datum/stack_recipe/plastic_recipes = list ( \
- new/datum/stack_recipe("plastic crate", /obj/structure/closet/crate/plastic, 10, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("plastic ashtray", /obj/item/ashtray/plastic, 2, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("plastic fork", /obj/item/weapon/kitchen/utensil/pfork, 1, on_floor = 1), \
- new/datum/stack_recipe("plastic spoon", /obj/item/weapon/kitchen/utensil/pspoon, 1, on_floor = 1), \
- new/datum/stack_recipe("plastic knife", /obj/item/weapon/kitchen/knife/plastic, 1, on_floor = 1), \
- new/datum/stack_recipe("plastic bag", /obj/item/weapon/storage/bag/plasticbag, 3, on_floor = 1), \
- new/datum/stack_recipe("bear mould", /obj/item/weapon/kitchen/mould/bear, 1, on_floor = 1), \
- new/datum/stack_recipe("worm mould", /obj/item/weapon/kitchen/mould/worm, 1, on_floor = 1), \
- new/datum/stack_recipe("bean mould", /obj/item/weapon/kitchen/mould/bean, 1, on_floor = 1), \
- new/datum/stack_recipe("ball mould", /obj/item/weapon/kitchen/mould/ball, 1, on_floor = 1), \
- new/datum/stack_recipe("cane mould", /obj/item/weapon/kitchen/mould/cane, 1, on_floor = 1), \
- new/datum/stack_recipe("cash mould", /obj/item/weapon/kitchen/mould/cash, 1, on_floor = 1), \
- new/datum/stack_recipe("coin mould", /obj/item/weapon/kitchen/mould/coin, 1, on_floor = 1), \
- new/datum/stack_recipe("sucker mould", /obj/item/weapon/kitchen/mould/loli, 1, on_floor = 1), \
+ null, \
+ new/datum/stack_recipe("Scientist Statue", /obj/structure/statue/plasma/scientist, 5, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("Xenomorph Statue", /obj/structure/statue/plasma/xeno, 5, one_per_turf = 1, on_floor = 1), \
)
var/global/list/datum/stack_recipe/bananium_recipes = list ( \
new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \
null, \
+ new/datum/stack_recipe("Clown Statue", /obj/structure/statue/bananium/clown, 5, one_per_turf = 1, on_floor = 1), \
+ null, \
new/datum/stack_recipe("bananium computer frame", /obj/structure/computerframe/HONKputer, 50, time = 25, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("bananium grenade casing", /obj/item/weapon/grenade/bananade/casing, 4, on_floor = 1), \
)
@@ -79,6 +89,8 @@ var/global/list/datum/stack_recipe/tranquillite_recipes = list ( \
new/datum/stack_recipe("invisible wall", /obj/structure/barricade/mime, 5, one_per_turf = 1, on_floor = 1, time = 50), \
null, \
new/datum/stack_recipe("silent tile", /obj/item/stack/tile/mineral/tranquillite, 1, 4, 20), \
+ null, \
+ new/datum/stack_recipe("Mime Statue", /obj/structure/statue/tranquillite/mime, 5, one_per_turf = 1, on_floor = 1), \
)
var/global/list/datum/stack_recipe/abductor_recipes = list ( \
@@ -166,19 +178,6 @@ var/global/list/datum/stack_recipe/abductor_recipes = list ( \
atmos_spawn_air(SPAWN_HEAT | SPAWN_TOXINS, amount*10)
qdel(src)
-/obj/item/stack/sheet/mineral/plastic
- name = "Plastic"
- icon_state = "sheet-plastic"
- origin_tech = "materials=3"
-
-/obj/item/stack/sheet/mineral/plastic/New()
- ..()
- recipes = plastic_recipes
-
-/obj/item/stack/sheet/mineral/plastic/cyborg
- name = "plastic sheets"
- icon_state = "sheet-plastic"
-
/obj/item/stack/sheet/mineral/gold
name = "gold"
icon_state = "sheet-gold"
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index 4e822d3ce12..fd7d10c6612 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -4,7 +4,9 @@
* Plasteel
* Wood
* Cloth
+ * Plastic
* Cardboard
+ * Runed Metal (cult)
*/
/*
@@ -20,6 +22,7 @@ var/global/list/datum/stack_recipe/metal_recipes = list(
new /datum/stack_recipe("barber chair", /obj/structure/stool/bed/chair/barber, one_per_turf = 1, on_floor = 1),
new /datum/stack_recipe("wheelchair", /obj/structure/stool/bed/chair/wheelchair, 15, one_per_turf = 1, on_floor = 1),
new /datum/stack_recipe("bed", /obj/structure/stool/bed, 2, one_per_turf = 1, on_floor = 1),
+ new /datum/stack_recipe("psychiatrist bed", /obj/structure/stool/psychbed, 5, one_per_turf = 1, on_floor = 1),
null,
new /datum/stack_recipe_list("office chairs",list(
new /datum/stack_recipe("dark office chair", /obj/structure/stool/bed/chair/office/dark, 5, one_per_turf = 1, on_floor = 1),
@@ -47,9 +50,10 @@ var/global/list/datum/stack_recipe/metal_recipes = list(
new /datum/stack_recipe("canister", /obj/machinery/portable_atmospherics/canister, 10, time = 15, one_per_turf = 1, on_floor = 1),
null,
new /datum/stack_recipe("floor tile", /obj/item/stack/tile/plasteel, 1, 4, 20),
- new /datum/stack_recipe/rods("metal rod", /obj/item/stack/rods, 1, 2, 60),
+ new /datum/stack_recipe/rods("metal rod", /obj/item/stack/rods, 1, 2, 50),
null,
new /datum/stack_recipe("computer frame", /obj/structure/computerframe, 5, time = 25, one_per_turf = 1, on_floor = 1),
+ new /datum/stack_recipe("modular console", /obj/machinery/modular_computer/console/buildable/, 10, time = 25, one_per_turf = 1, on_floor = 1),
new /datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 50, one_per_turf = 1, on_floor = 1),
new /datum/stack_recipe("machine frame", /obj/machinery/constructable_frame/machine_frame, 5, time = 25, one_per_turf = 1, on_floor = 1),
new /datum/stack_recipe("turret frame", /obj/machinery/porta_turret_construct, 5, time = 25, one_per_turf = 1, on_floor = 1),
@@ -97,15 +101,19 @@ var/global/list/datum/stack_recipe/metal_recipes = list(
throwforce = 10.0
flags = CONDUCT
origin_tech = "materials=1"
+ merge_type = /obj/item/stack/sheet/metal
+
+/obj/item/stack/sheet/metal/cyborg
+ materials = list()
+
+/obj/item/stack/sheet/metal/fifty
+ amount = 50
/obj/item/stack/sheet/metal/narsie_act()
if(prob(20))
new /obj/item/stack/sheet/runed_metal(loc, amount)
qdel(src)
-/obj/item/stack/sheet/metal/cyborg
- materials = list()
-
/obj/item/stack/sheet/metal/New(var/loc, var/amount=null)
recipes = metal_recipes
return ..()
@@ -130,6 +138,7 @@ var/global/list/datum/stack_recipe/plasteel_recipes = list(
throwforce = 10.0
flags = CONDUCT
origin_tech = "materials=2"
+ merge_type = /obj/item/stack/sheet/plasteel
/obj/item/stack/sheet/plasteel/New(var/loc, var/amount=null)
recipes = plasteel_recipes
@@ -146,13 +155,15 @@ var/global/list/datum/stack_recipe/wood_recipes = list(
new /datum/stack_recipe("wooden barricade", /obj/structure/barricade/wooden, 5, time = 50, one_per_turf = 1, on_floor = 1),
new /datum/stack_recipe("bookcase", /obj/structure/bookcase, 5, time = 50, one_per_turf = 1, on_floor = 1),
new /datum/stack_recipe("drying rack", /obj/machinery/smartfridge/drying_rack, 10, time = 15, one_per_turf = 1, on_floor = 1),
+ new /datum/stack_recipe("dog bed", /obj/structure/stool/bed/dogbed, 10, time = 10, one_per_turf = 1, on_floor = 1), \
new /datum/stack_recipe("rifle stock", /obj/item/weaponcrafting/stock, 10, time = 40),
new /datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 20, one_per_turf = 1, on_floor = 1),
new /datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1),
new /datum/stack_recipe("easel", /obj/structure/easel, 3, one_per_turf = 1, on_floor = 1),
new /datum/stack_recipe("wooden buckler", /obj/item/weapon/shield/riot/buckler, 20, time = 40),
new /datum/stack_recipe("apiary", /obj/structure/beebox, 40, time = 50),
- new /datum/stack_recipe("honey frame", /obj/item/honey_frame, 5, time = 10)
+ new /datum/stack_recipe("honey frame", /obj/item/honey_frame, 5, time = 10),
+ new /datum/stack_recipe("baseball bat", /obj/item/weapon/melee/baseball_bat, 5, time = 15)
)
/obj/item/stack/sheet/wood
@@ -163,6 +174,7 @@ var/global/list/datum/stack_recipe/wood_recipes = list(
icon_state = "sheet-wood"
origin_tech = "materials=1;biotech=1"
burn_state = FLAMMABLE
+ merge_type = /obj/item/stack/sheet/wood
/obj/item/stack/sheet/wood/New(var/loc, var/amount=null)
recipes = wood_recipes
@@ -200,6 +212,7 @@ var/global/list/datum/stack_recipe/cloth_recipes = list ( \
burn_state = FLAMMABLE
force = 0
throwforce = 0
+ merge_type = /obj/item/stack/sheet/cloth
/obj/item/stack/sheet/cloth/New(loc, amount=null)
recipes = cloth_recipes
@@ -232,6 +245,7 @@ var/global/list/datum/stack_recipe/cardboard_recipes = list (
icon_state = "sheet-card"
origin_tech = "materials=1"
burn_state = FLAMMABLE
+ merge_type = /obj/item/stack/sheet/cardboard
/obj/item/stack/sheet/cardboard/New(var/loc, var/amt = null)
recipes = cardboard_recipes
@@ -257,6 +271,7 @@ var/global/list/datum/stack_recipe/runed_metal_recipes = list ( \
icon_state = "sheet-runed"
icon = 'icons/obj/items.dmi'
sheettype = "runed"
+ merge_type = /obj/item/stack/sheet/runed_metal
/obj/item/stack/sheet/runed_metal/attack_self(mob/living/user)
if(!iscultist(user))
@@ -285,4 +300,41 @@ var/global/list/datum/stack_recipe/runed_metal_recipes = list ( \
w_class = 3
throw_speed = 1
throw_range = 3
- origin_tech = "materials=2;biotech=2"
\ No newline at end of file
+ origin_tech = "materials=2;biotech=2"
+
+var/global/list/datum/stack_recipe/plastic_recipes = list ( \
+ new/datum/stack_recipe("plastic flaps", /obj/structure/plasticflaps, 5, one_per_turf = 1, on_floor = 1, time = 40), \
+ new/datum/stack_recipe("plastic crate", /obj/structure/closet/crate/plastic, 10, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("plastic ashtray", /obj/item/ashtray/plastic, 2, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("plastic fork", /obj/item/weapon/kitchen/utensil/pfork, 1, on_floor = 1), \
+ new/datum/stack_recipe("plastic spoon", /obj/item/weapon/kitchen/utensil/pspoon, 1, on_floor = 1), \
+ new/datum/stack_recipe("plastic knife", /obj/item/weapon/kitchen/knife/plastic, 1, on_floor = 1), \
+ new/datum/stack_recipe("plastic bag", /obj/item/weapon/storage/bag/plasticbag, 3, on_floor = 1), \
+ new/datum/stack_recipe("bear mould", /obj/item/weapon/kitchen/mould/bear, 1, on_floor = 1), \
+ new/datum/stack_recipe("worm mould", /obj/item/weapon/kitchen/mould/worm, 1, on_floor = 1), \
+ new/datum/stack_recipe("bean mould", /obj/item/weapon/kitchen/mould/bean, 1, on_floor = 1), \
+ new/datum/stack_recipe("ball mould", /obj/item/weapon/kitchen/mould/ball, 1, on_floor = 1), \
+ new/datum/stack_recipe("cane mould", /obj/item/weapon/kitchen/mould/cane, 1, on_floor = 1), \
+ new/datum/stack_recipe("cash mould", /obj/item/weapon/kitchen/mould/cash, 1, on_floor = 1), \
+ new/datum/stack_recipe("coin mould", /obj/item/weapon/kitchen/mould/coin, 1, on_floor = 1), \
+ new/datum/stack_recipe("sucker mould", /obj/item/weapon/kitchen/mould/loli, 1, on_floor = 1), \
+ )
+
+/obj/item/stack/sheet/plastic
+ name = "plastic"
+ desc = "Compress dinosaur over millions of years, then refine, split and mold, and voila! You have plastic."
+ singular_name = "plastic sheet"
+ icon_state = "sheet-plastic"
+ throwforce = 7
+ origin_tech = "materials=1;biotech=1"
+ merge_type = /obj/item/stack/sheet/plastic
+
+/obj/item/stack/sheet/plastic/New()
+ recipes = plastic_recipes
+ . = ..()
+
+/obj/item/stack/sheet/plastic/fifty
+ amount = 50
+
+/obj/item/stack/sheet/plastic/five
+ amount = 5
diff --git a/code/game/objects/items/stacks/sheets/sheets.dm b/code/game/objects/items/stacks/sheets/sheets.dm
index 2a8b2130be6..4e5a0e9fdc8 100644
--- a/code/game/objects/items/stacks/sheets/sheets.dm
+++ b/code/game/objects/items/stacks/sheets/sheets.dm
@@ -9,6 +9,8 @@
attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed")
var/perunit = MINERAL_MATERIAL_AMOUNT
var/sheettype = null //this is used for girders in the creation of walls/false walls
+ usesound = 'sound/items/Deconstruct.ogg'
+ toolspeed = 1
// Since the sheetsnatcher was consolidated into weapon/storage/bag we now use
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index 852be314b1c..d4d4ae7f48c 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -14,11 +14,14 @@
var/singular_name
var/amount = 1
var/max_amount //also see stack recipes initialisation, param "max_res_amount" must be equal to this max_amount
+ var/merge_type = null // This path and its children should merge with this stack, defaults to src.type
/obj/item/stack/New(var/loc, var/amt = null)
..()
if(amt != null) //Allow for stacks with the amount=0
amount = amt
+ if(!merge_type)
+ merge_type = type
/obj/item/stack/Destroy()
if(usr && usr.machine == src)
@@ -232,7 +235,7 @@
/obj/item/stack/attackby(obj/item/W, mob/user, params)
..()
- if(istype(W, type))
+ if(istype(W, merge_type))
var/obj/item/stack/S = W
if(S.amount >= max_amount)
return 1
diff --git a/code/game/objects/items/stacks/tiles/tile_mineral.dm b/code/game/objects/items/stacks/tiles/tile_mineral.dm
index 7f9c6b6535b..8e830f27407 100644
--- a/code/game/objects/items/stacks/tiles/tile_mineral.dm
+++ b/code/game/objects/items/stacks/tiles/tile_mineral.dm
@@ -17,6 +17,10 @@
mineralType = "uranium"
materials = list(MAT_URANIUM=500)
+var/global/list/datum/stack_recipe/gold_tile_recipes = list ( \
+ new/datum/stack_recipe("fancy gold tile", /obj/item/stack/tile/mineral/gold/fancy, max_res_amount = 20), \
+ )
+
/obj/item/stack/tile/mineral/gold
name = "gold tile"
singular_name = "gold floor tile"
@@ -26,6 +30,26 @@
mineralType = "gold"
materials = list(MAT_GOLD=500)
+/obj/item/stack/tile/mineral/gold/New(loc, amount=null)
+ ..()
+ recipes = gold_tile_recipes
+
+var/global/list/datum/stack_recipe/goldfancy_tile_recipes = list ( \
+ new/datum/stack_recipe("regular gold tile", /obj/item/stack/tile/mineral/gold, max_res_amount = 20), \
+ )
+
+/obj/item/stack/tile/mineral/gold/fancy
+ icon_state = "tile_goldfancy"
+ turf_type = /turf/simulated/floor/mineral/gold/fancy
+
+/obj/item/stack/tile/mineral/gold/fancy/New(loc, amount=null)
+ ..()
+ recipes = goldfancy_tile_recipes
+
+var/global/list/datum/stack_recipe/silver_tile_recipes = list ( \
+ new/datum/stack_recipe("fancy silver tile", /obj/item/stack/tile/mineral/silver/fancy, max_res_amount = 20), \
+ )
+
/obj/item/stack/tile/mineral/silver
name = "silver tile"
singular_name = "silver floor tile"
@@ -35,6 +59,22 @@
mineralType = "silver"
materials = list(MAT_SILVER=500)
+/obj/item/stack/tile/mineral/silver/New(loc, amount=null)
+ ..()
+ recipes = silver_tile_recipes
+
+var/global/list/datum/stack_recipe/silverfancy_tile_recipes = list ( \
+ new/datum/stack_recipe("regular silver tile", /obj/item/stack/tile/mineral/silver, max_res_amount = 20), \
+ )
+
+/obj/item/stack/tile/mineral/silver/fancy
+ icon_state = "tile_silverfancy"
+ turf_type = /turf/simulated/floor/mineral/silver/fancy
+
+/obj/item/stack/tile/mineral/silver/fancy/New(loc, amount=null)
+ ..()
+ recipes = silverfancy_tile_recipes
+
/obj/item/stack/tile/mineral/diamond
name = "diamond tile"
singular_name = "diamond floor tile"
diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm
index afa38da7721..b8078bfebcb 100644
--- a/code/game/objects/items/stacks/tiles/tile_types.dm
+++ b/code/game/objects/items/stacks/tiles/tile_types.dm
@@ -136,6 +136,7 @@
icon_state = "tile_space"
turf_type = /turf/simulated/floor/fakespace
burn_state = FLAMMABLE
+ merge_type = /obj/item/stack/tile/fakespace
/obj/item/stack/tile/fakespace/loaded
amount = 30
@@ -148,6 +149,7 @@
icon_state = "tile_noslip"
turf_type = /turf/simulated/floor/noslip
origin_tech = "materials=3"
+ merge_type = /obj/item/stack/tile/noslip
/obj/item/stack/tile/noslip/loaded
amount = 20
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index feb681e47c2..87da0987487 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -1301,7 +1301,7 @@ obj/item/toy/cards/deck/syndicate/black
/obj/item/toy/minigibber/attackby(var/obj/O, var/mob/user, params)
if(istype(O,/obj/item/toy/character) && O.loc == user)
to_chat(user, "You start feeding \the [O] [bicon(O)] into \the [src]'s mini-input.")
- if(do_after(user,10, target = src))
+ if(do_after(user, 10, target = src))
if(O.loc != user)
to_chat(user, "\The [O] is too far away to feed into \the [src]!")
else
diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm
index 50306ac7e02..cca1464d6e7 100755
--- a/code/game/objects/items/weapons/AI_modules.dm
+++ b/code/game/objects/items/weapons/AI_modules.dm
@@ -367,7 +367,7 @@ AI MODULES
log_law_changes(target, sender)
lawchanges.Add("The law is '[newFreeFormLaw]'")
- to_chat(target, "\red BZZZZT")
+ to_chat(target, "BZZZZT")
var/law = "[newFreeFormLaw]"
target.add_ion_law(law)
target.show_laws()
diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm
index bb57a4a2cc2..5598a42cc8f 100644
--- a/code/game/objects/items/weapons/RCD.dm
+++ b/code/game/objects/items/weapons/RCD.dm
@@ -20,6 +20,8 @@ RCD
w_class = 3
materials = list(MAT_METAL = 30000)
origin_tech = "engineering=4;materials=2"
+ toolspeed = 1
+ usesound = 'sound/items/Deconstruct.ogg'
var/datum/effect/system/spark_spread/spark_system
var/max_matter = 100
var/matter = 0
@@ -57,8 +59,7 @@ RCD
return
/obj/item/weapon/rcd/Destroy()
- qdel(spark_system)
- spark_system = null
+ QDEL_NULL(spark_system)
rcd_list -= src
return ..()
@@ -172,7 +173,7 @@ RCD
door_name = temp_t
/obj/item/weapon/rcd/proc/activate()
- playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(loc, usesound, 50, 1)
/obj/item/weapon/rcd/afterattack(atom/A, mob/user, proximity)
@@ -197,7 +198,7 @@ RCD
if(checkResource(3, user))
to_chat(user, "Building Wall ...")
playsound(loc, 'sound/machines/click.ogg', 50, 1)
- if(do_after(user, 20, target = A))
+ if(do_after(user, 20 * toolspeed, target = A))
if(!useResource(3, user)) return 0
activate()
var/turf/AT = A
@@ -210,7 +211,7 @@ RCD
if(checkResource(10, user))
to_chat(user, "Building Airlock...")
playsound(loc, 'sound/machines/click.ogg', 50, 1)
- if(do_after(user, 50, target = A))
+ if(do_after(user, 50 * toolspeed, target = A))
if(!useResource(10, user)) return 0
activate()
var/obj/machinery/door/airlock/T = new door_type(A)
@@ -231,7 +232,7 @@ RCD
if(checkResource(5, user))
to_chat(user, "Deconstructing Wall...")
playsound(loc, 'sound/machines/click.ogg', 50, 1)
- if(do_after(user, 40, target = A))
+ if(do_after(user, 40 * toolspeed, target = A))
if(!useResource(5, user)) return 0
activate()
var/turf/AT = A
@@ -243,7 +244,7 @@ RCD
if(checkResource(5, user))
to_chat(user, "Deconstructing Floor...")
playsound(loc, 'sound/machines/click.ogg', 50, 1)
- if(do_after(user, 50, target = A))
+ if(do_after(user, 50 * toolspeed, target = A))
if(!useResource(5, user)) return 0
activate()
var/turf/AT = A
@@ -255,7 +256,7 @@ RCD
if(checkResource(20, user))
to_chat(user, "Deconstructing Airlock...")
playsound(loc, 'sound/machines/click.ogg', 50, 1)
- if(do_after(user, 50, target = A))
+ if(do_after(user, 50 * toolspeed, target = A))
if(!useResource(20, user)) return 0
activate()
qdel(A)
@@ -270,7 +271,7 @@ RCD
return 0
to_chat(user, "Deconstructing window...")
playsound(loc, 'sound/machines/click.ogg', 50, 1)
- if(!do_after(user, 20, target = A))
+ if(!do_after(user, 20 * toolspeed, target = A))
return 0
if(locate(/obj/structure/window/full/shuttle) in A.contents)
return 0 // Let's not give shuttle-griefers an easy time.
@@ -307,7 +308,7 @@ RCD
return 0
to_chat(user, "Constructing window...")
playsound(loc, 'sound/machines/click.ogg', 50, 1)
- if(!do_after(user, 20, target = A))
+ if(!do_after(user, 20 * toolspeed, target = A))
return 0
if(locate(/obj/structure/grille) in A.contents)
return 0 // We already have window
@@ -376,6 +377,9 @@ RCD
explosion(src, 0, 0, 3, 1, flame_range = 1)
qdel(src)
+/obj/item/weapon/rcd/preloaded
+ matter = 100
+
/obj/item/weapon/rcd/combat
name = "combat RCD"
max_matter = 500
diff --git a/code/game/objects/items/weapons/RCL.dm b/code/game/objects/items/weapons/RCL.dm
new file mode 100644
index 00000000000..8e0357ecd13
--- /dev/null
+++ b/code/game/objects/items/weapons/RCL.dm
@@ -0,0 +1,149 @@
+/obj/item/weapon/twohanded/rcl
+ name = "rapid cable layer (RCL)"
+ desc = "A device used to rapidly deploy cables. It has screws on the side which can be removed to slide off the cables."
+ icon = 'icons/obj/tools.dmi'
+ icon_state = "rcl-0"
+ item_state = "rcl-0"
+ opacity = 0
+ force = 5 //Plastic is soft
+ throwforce = 5
+ throw_speed = 1
+ throw_range = 7
+ w_class = WEIGHT_CLASS_NORMAL
+ origin_tech = "engineering=4;materials=4"
+ var/max_amount = 90
+ var/active = 0
+ var/obj/structure/cable/last = null
+ var/obj/item/stack/cable_coil/loaded = null
+
+/obj/item/weapon/twohanded/rcl/attackby(obj/item/weapon/W, mob/user)
+ if(istype(W, /obj/item/stack/cable_coil))
+ var/obj/item/stack/cable_coil/C = W
+ if(!loaded)
+ if(user.drop_item())
+ loaded = W
+ loaded.forceMove(src)
+ loaded.max_amount = max_amount //We store a lot.
+ else
+ to_chat(user, "[user.get_active_hand()] is stuck to your hand!")
+ return
+ else
+ if(loaded.amount < max_amount)
+ var/amount = min(loaded.amount + C.amount, max_amount)
+ C.use(amount - loaded.amount)
+ loaded.amount = amount
+ else
+ return
+ update_icon()
+ to_chat(user, "You add the cables to the [src]. It now contains [loaded.amount].")
+ else if(isscrewdriver(W))
+ if(!loaded)
+ return
+ to_chat(user, "You loosen the securing screws on the side, allowing you to lower the guiding edge and retrieve the wires.")
+ while(loaded.amount > 30) //There are only two kinds of situations: "nodiff" (60,90), or "diff" (31-59, 61-89)
+ var/diff = loaded.amount % 30
+ if(diff)
+ loaded.use(diff)
+ new /obj/item/stack/cable_coil(user.loc, diff)
+ else
+ loaded.use(30)
+ new /obj/item/stack/cable_coil(user.loc, 30)
+ loaded.max_amount = initial(loaded.max_amount)
+ loaded.forceMove(user.loc)
+ user.put_in_hands(loaded)
+ loaded = null
+ update_icon()
+ else
+ ..()
+
+/obj/item/weapon/twohanded/rcl/examine(mob/user)
+ ..()
+ if(loaded)
+ to_chat(user, "It contains [loaded.amount]/[max_amount] cables.")
+
+/obj/item/weapon/twohanded/rcl/Destroy()
+ QDEL_NULL(loaded)
+ last = null
+ active = 0
+ return ..()
+
+/obj/item/weapon/twohanded/rcl/update_icon()
+ if(!loaded)
+ icon_state = "rcl-0"
+ item_state = "rcl-0"
+ return
+ switch(loaded.amount)
+ if(61 to INFINITY)
+ icon_state = "rcl-30"
+ item_state = "rcl"
+ if(31 to 60)
+ icon_state = "rcl-20"
+ item_state = "rcl"
+ if(1 to 30)
+ icon_state = "rcl-10"
+ item_state = "rcl"
+ else
+ icon_state = "rcl-0"
+ item_state = "rcl-0"
+
+/obj/item/weapon/twohanded/rcl/proc/is_empty(mob/user, loud = 1)
+ update_icon()
+ if(!loaded || !loaded.amount)
+ if(loud)
+ to_chat(user, "The last of the cables unreel from [src].")
+ if(loaded)
+ qdel(loaded)
+ loaded = null
+ unwield(user)
+ active = wielded
+ return 1
+ return 0
+
+/obj/item/weapon/twohanded/rcl/dropped(mob/wearer)
+ ..()
+ active = 0
+ last = null
+
+/obj/item/weapon/twohanded/rcl/attack_self(mob/user)
+ ..()
+ active = wielded
+ if(!active)
+ last = null
+ else if(!last)
+ for(var/obj/structure/cable/C in get_turf(user))
+ if(C.d1 == 0 || C.d2 == 0)
+ last = C
+ break
+
+/obj/item/weapon/twohanded/rcl/moved(mob/user, turf/old_loc, direct)
+ if(active)
+ trigger(user)
+
+/obj/item/weapon/twohanded/rcl/proc/trigger(mob/user)
+ if(is_empty(user, 0))
+ to_chat(user, "\The [src] is empty!")
+ return
+ if(last)
+ if(get_dist(last, user) == 1) //hacky, but it works
+ var/turf/T = get_turf(user)
+ if(!isturf(T) || T.intact || !T.can_have_cabling())
+ last = null
+ return
+ if(get_dir(last, user) == last.d2)
+ //Did we just walk backwards? Well, that's the one direction we CAN'T complete a stub.
+ last = null
+ return
+ loaded.cable_join(last, user)
+ if(is_empty(user))
+ return //If we've run out, display message and exit
+ else
+ last = null
+ last = loaded.place_turf(get_turf(loc), user, turn(user.dir, 180))
+ is_empty(user) //If we've run out, display message
+
+/obj/item/weapon/twohanded/rcl/pre_loaded/New() //Comes preloaded with cable, for testing stuff
+ ..()
+ loaded = new()
+ loaded.max_amount = max_amount
+ loaded.amount = max_amount
+ update_icon()
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/RSF.dm b/code/game/objects/items/weapons/RSF.dm
index 47cf88f9bbc..07a489490e1 100644
--- a/code/game/objects/items/weapons/RSF.dm
+++ b/code/game/objects/items/weapons/RSF.dm
@@ -69,7 +69,7 @@ RSF
if(istype(A, /obj/structure/table) && matter >= 1)
to_chat(user, "Dispensing Dosh...")
playsound(src.loc, 'sound/machines/click.ogg', 10, 1)
- new /obj/item/weapon/spacecash/c10( A.loc )
+ new /obj/item/stack/spacecash/c10( A.loc )
if(isrobot(user))
var/mob/living/silicon/robot/engy = user
engy.cell.charge -= 200 //once money becomes useful, I guess changing this to a high ammount, like 500 units a kick, till then, enjoy dosh!
@@ -83,7 +83,7 @@ RSF
if(istype(A, /turf/simulated/floor) && matter >= 1)
to_chat(user, "Dispensing Dosh...")
playsound(src.loc, 'sound/machines/click.ogg', 10, 1)
- new /obj/item/weapon/spacecash/c10( A )
+ new /obj/item/stack/spacecash/c10( A )
if(isrobot(user))
var/mob/living/silicon/robot/engy = user
engy.cell.charge -= 200 //once money becomes useful, I guess changing this to a high ammount, like 500 units a kick, till then, enjoy dosh!
diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm
index 4a600fe188f..fe6a35cda66 100644
--- a/code/game/objects/items/weapons/cards_ids.dm
+++ b/code/game/objects/items/weapons/cards_ids.dm
@@ -715,6 +715,18 @@
desc = "A modified ID card given only to those people who have devoted their lives to the better interests of Nanotrasen. It sparkles blue."
icon_state = "lifetimeid"
+/obj/item/weapon/card/id/ert
+ name = "ERT ID"
+ icon_state = "ERT_empty"
+
+/obj/item/weapon/card/id/ert/commander
+ icon_state = "ERT_leader"
+/obj/item/weapon/card/id/ert/security
+ icon_state = "ERT_security"
+/obj/item/weapon/card/id/ert/engineering
+ icon_state = "ERT_engineering"
+/obj/item/weapon/card/id/ert/medic
+ icon_state = "ERT_medical"
// Decals
/obj/item/weapon/id_decal
name = "identification card decal"
diff --git a/code/game/objects/items/weapons/cash.dm b/code/game/objects/items/weapons/cash.dm
index 3608d7861f3..507b19d9f7a 100644
--- a/code/game/objects/items/weapons/cash.dm
+++ b/code/game/objects/items/weapons/cash.dm
@@ -1,125 +1,59 @@
-var/global/list/moneytypes=list(
- /obj/item/weapon/spacecash/c1000 = 1000,
- /obj/item/weapon/spacecash/c500 = 500,
- /obj/item/weapon/spacecash/c200 = 200,
- /obj/item/weapon/spacecash/c100 = 100,
- /obj/item/weapon/spacecash/c50 = 50,
- /obj/item/weapon/spacecash/c20 = 20,
- /obj/item/weapon/spacecash/c10 = 10,
- /obj/item/weapon/spacecash = 1,
-)
-
-/obj/item/weapon/spacecash
- name = "credit chip"
+/obj/item/stack/spacecash
+ name = "1 Credit"
desc = "Money money money."
- gender = PLURAL
- icon = 'icons/obj/money.dmi'
- icon_state = "cash1"
- opacity = 0
- density = 0
- anchored = 0.0
- force = 1.0
- throwforce = 1.0
+ icon = 'icons/goonstation/objects/money.dmi'
+ icon_state = "cashgreen"
+ hitsound = "swing_hit"
+ force = 1
+ throwforce = 1
throw_speed = 1
- throw_range = 2
- w_class = 1
+ throw_range = 7
+ w_class = WEIGHT_CLASS_TINY
burn_state = FLAMMABLE
- var/access = list()
- access = access_crate_cash
- var/worth = 1 // Per chip
- var/amount = 1 // number of chips
- var/stack_color = "#4E054F"
+ singular_name = "credit"
+ max_amount = 1000000
+ merge_type = /obj/item/stack/spacecash
-/obj/item/weapon/spacecash/New(var/new_loc,var/new_amount=1)
- loc = new_loc
- name = "[worth] credit chip"
- amount = new_amount
+/obj/item/stack/spacecash/New(loc, amt = null)
+ ..()
update_icon()
-/obj/item/weapon/spacecash/examine(mob/user)
- if(amount>1)
- to_chat(user, "[bicon(src)] This is a stack of [amount] [src]s.")
+/obj/item/stack/spacecash/update_icon()
+ ..()
+ name = "[amount == max_amount ? "1000000" : amount] Credit[amount > 1 ? "s" : ""]"
+ if(amount >= 1 && amount < 10)
+ icon_state = "cashgreen"
+ else if(amount >= 10 && amount < 50)
+ icon_state = "spacecash"
+ else if(amount >= 50 && amount < 500)
+ icon_state = "cashblue"
+ else if(amount >= 500 && amount < 1000)
+ icon_state = "cashindi"
+ else if(amount >= 1000 && amount < 1000000)
+ icon_state = "cashpurp"
else
- to_chat(user, "[bicon(src)] This is \a [src]s.")
- to_chat(user, "It's worth [worth*amount] credits.")
+ icon_state = "cashrbow"
-/obj/item/weapon/spacecash/update_icon()
- icon_state = "cash[worth]"
- // Up to 100 items per stack.
- pixel_x=rand(-7,7)
- pixel_y=rand(-14,14)
+/obj/item/stack/spacecash/c10
+ amount = 10
-/obj/item/weapon/spacecash/proc/collect_from(var/obj/item/weapon/spacecash/cash)
- if(cash.worth == src.worth)
- var/taking = min(100-src.amount,cash.amount)
- cash.amount -= taking
- src.amount += taking
- if(cash.amount <= 0)
- qdel(cash)
- return taking
- return 0
+/obj/item/stack/spacecash/c20
+ amount = 20
-/obj/item/weapon/spacecash/afterattack(atom/A as mob|obj, mob/user as mob)
- if(istype(A, /turf) || istype(A, /obj/structure/table) || istype(A, /obj/structure/rack))
- var/turf/T = get_turf(A)
- var/collected = 0
- for(var/obj/item/weapon/spacecash/cash in T)
- if(cash.worth == src.worth)
- collected += collect_from(cash)
- if(collected)
- update_icon()
- to_chat(user, "You add [collected] credit [amount > 1 ? "chips":"chip"] to your stack of cash.")
- else if(istype(A,/obj/item/weapon/spacecash))
- var/obj/item/weapon/spacecash/cash = A
- var/collected = src.collect_from(cash)
- if(collected)
- update_icon()
- to_chat(user, "You add [collected] credit [amount > 1 ? "chips":"chip"] to your stack of cash.")
+/obj/item/stack/spacecash/c50
+ amount = 50
+/obj/item/stack/spacecash/c100
+ amount = 100
-/obj/item/weapon/spacecash/proc/get_total()
- return worth * amount
+/obj/item/stack/spacecash/c200
+ amount = 200
-/obj/item/weapon/spacecash/c10
- icon_state = "cash10"
- worth = 10
+/obj/item/stack/spacecash/c500
+ amount = 500
-/obj/item/weapon/spacecash/c20
- icon_state = "cash10"
- worth = 20
+/obj/item/stack/spacecash/c1000
+ amount = 1000
-/obj/item/weapon/spacecash/c50
- icon_state = "cash10"
- worth = 50
-
-/obj/item/weapon/spacecash/c100
- icon_state = "cash100"
- worth = 100
-
-/obj/item/weapon/spacecash/c200
- icon_state = "cash200"
- worth = 200
-
-/obj/item/weapon/spacecash/c500
- icon_state = "cash500"
- worth = 500
-
-/obj/item/weapon/spacecash/c1000
- icon_state = "cash1000"
- worth = 1000
-
-/proc/dispense_cash(var/amount, var/loc)
- for(var/cashtype in moneytypes)
- var/slice = moneytypes[cashtype]
- var/dispense_count = Floor(amount/slice)
- amount = amount % slice
- while(dispense_count>0)
- var/dispense_this_time = min(dispense_count,100)
- if(dispense_this_time > 0)
- new cashtype(loc,dispense_this_time)
- dispense_count -= dispense_this_time
-
-/proc/count_cash(var/list/cash)
- . = 0
- for(var/obj/item/weapon/spacecash/C in cash)
- . += C.get_total()
\ No newline at end of file
+/obj/item/stack/spacecash/c1000000
+ amount = 1000000
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/caution.dm b/code/game/objects/items/weapons/caution.dm
index 6e57028472e..44a357a6d92 100644
--- a/code/game/objects/items/weapons/caution.dm
+++ b/code/game/objects/items/weapons/caution.dm
@@ -22,7 +22,7 @@
return
if(armed)
armed = 0
- to_chat(user, "\blue You disarm \the [src].")
+ to_chat(user, "You disarm \the [src].")
return
timing = !timing
if(timing)
@@ -30,7 +30,7 @@
else
armed = 0
timepassed = 0
- to_chat(H, "\blue You [timing ? "activate \the [src]'s timer, you have 15 seconds." : "de-activate \the [src]'s timer."]")
+ to_chat(H, "You [timing ? "activate \the [src]'s timer, you have 15 seconds." : "de-activate \the [src]'s timer."]")
process()
if(!timing)
diff --git a/code/game/objects/items/weapons/cigs.dm b/code/game/objects/items/weapons/cigs.dm
index f0c4f1e60d6..2b46e8de101 100644
--- a/code/game/objects/items/weapons/cigs.dm
+++ b/code/game/objects/items/weapons/cigs.dm
@@ -46,8 +46,7 @@ LIGHTERS ARE IN LIGHTERS.DM
reagents.set_reacting(FALSE) // so it doesn't react until you light it
/obj/item/clothing/mask/cigarette/Destroy()
- if(reagents)
- qdel(reagents)
+ QDEL_NULL(reagents)
processing_objects -= src
return ..()
@@ -94,6 +93,17 @@ LIGHTERS ARE IN LIGHTERS.DM
else if(istype(W, /obj/item/device/assembly/igniter))
light("[user] fiddles with [W], and manages to light their [name].")
+ else if(istype(W, /obj/item/weapon/gun/magic/wand/fireball))
+ var/obj/item/weapon/gun/magic/wand/fireball/F = W
+ if(F.charges)
+ if(prob(50) || user.mind.assigned_role == "Wizard")
+ light("Holy shit, did [user] just manage to light their [name] with [W], with only moderate eyebrow singing?")
+ else
+ to_chat(user, "Unsure which end of the wand is which, [user] fails to light [name] with [W].")
+ explosion(user.loc, -1, 0, 2, 3, 0, flame_range = 2)
+ F.charges--
+
+
//can't think of any other way to update the overlays :<
user.update_inv_wear_mask()
user.update_inv_l_hand()
diff --git a/code/game/objects/items/weapons/clown_items.dm b/code/game/objects/items/weapons/clown_items.dm
index db6035bddbe..3312c6555d4 100644
--- a/code/game/objects/items/weapons/clown_items.dm
+++ b/code/game/objects/items/weapons/clown_items.dm
@@ -13,7 +13,7 @@
var/mob/living/carbon/M = AM
M.slip("soap", 4, 2)
-/obj/item/weapon/soap/afterattack(atom/target, mob/user as mob, proximity)
+/obj/item/weapon/soap/afterattack(atom/target, mob/user, proximity)
if(!proximity) return
//I couldn't feasibly fix the overlay bugs caused by cleaning items we are wearing.
//So this is a workaround. This also makes more sense from an IC standpoint. ~Carn
@@ -37,11 +37,14 @@
var/obj/effect/decal/cleanable/C = locate() in target
qdel(C)
target.clean_blood()
+ if(istype(target, /turf/simulated))
+ var/turf/simulated/T = target
+ T.dirt = 0
return
/obj/item/weapon/soap/attack(mob/target as mob, mob/user as mob)
if(target && user && ishuman(target) && ishuman(user) && !target.stat && !user.stat && user.zone_sel &&user.zone_sel.selecting == "mouth" )
- user.visible_message("\red \the [user] washes \the [target]'s mouth out with [src.name]!")
+ user.visible_message("\the [user] washes \the [target]'s mouth out with [src.name]!")
return
..()
diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm
index e60a68f42d6..f311d56d1ba 100644
--- a/code/game/objects/items/weapons/cosmetics.dm
+++ b/code/game/objects/items/weapons/cosmetics.dm
@@ -87,6 +87,8 @@
icon_state = "razor"
flags = CONDUCT
w_class = 1
+ usesound = 'sound/items/Welder2.ogg'
+ toolspeed = 1
/obj/item/weapon/razor/attack(mob/living/carbon/M as mob, mob/user as mob)
if(ishuman(M))
@@ -106,24 +108,24 @@
if(H == user) //shaving yourself
user.visible_message("[user] starts to shave their facial hair with \the [src].", \
"You take a moment shave your facial hair with \the [src].")
- if(do_after(user, 50, target = H))
+ if(do_after(user, 50 * toolspeed, target = H))
user.visible_message("[user] shaves his facial hair clean with the [src].", \
"You finish shaving with the [src]. Fast and clean!")
C.f_style = "Shaved"
H.update_fhair()
- playsound(src.loc, 'sound/items/Welder2.ogg', 20, 1)
+ playsound(src.loc, usesound, 20, 1)
else
var/turf/user_loc = user.loc
var/turf/H_loc = H.loc
user.visible_message("[user] tries to shave [H]'s facial hair with \the [src].", \
"You start shaving [H]'s facial hair.")
- if(do_after(user, 50, target = H))
+ if(do_after(user, 50 * toolspeed, target = H))
if(user_loc == user.loc && H_loc == H.loc)
user.visible_message("[user] shaves off [H]'s facial hair with \the [src].", \
"You shave [H]'s facial hair clean off.")
C.f_style = "Shaved"
H.update_fhair()
- playsound(src.loc, 'sound/items/Welder2.ogg', 20, 1)
+ playsound(src.loc, usesound, 20, 1)
if(user.zone_sel.selecting == "head")
if(!get_location_accessible(H, "head"))
to_chat(user, "The headgear is in the way.")
@@ -137,24 +139,24 @@
if(H == user) //shaving yourself
user.visible_message("[user] starts to shave their head with \the [src].", \
"You start to shave your head with \the [src].")
- if(do_after(user, 50, target = H))
+ if(do_after(user, 50 * toolspeed, target = H))
user.visible_message("[user] shaves his head with the [src].", \
"You finish shaving with the [src].")
C.h_style = "Skinhead"
H.update_hair()
- playsound(src.loc, 'sound/items/Welder2.ogg', 40, 1)
+ playsound(src.loc, usesound, 40, 1)
else
var/turf/user_loc = user.loc
var/turf/H_loc = H.loc
user.visible_message("[user] tries to shave [H]'s head with \the [src]!", \
"You start shaving [H]'s head.")
- if(do_after(user, 50, target = H))
+ if(do_after(user, 50 * toolspeed, target = H))
if(user_loc == user.loc && H_loc == H.loc)
user.visible_message("[user] shaves [H]'s head bald with \the [src]!", \
"You shave [H]'s head bald.")
C.h_style = "Skinhead"
H.update_hair()
- playsound(src.loc, 'sound/items/Welder2.ogg', 40, 1)
+ playsound(src.loc, usesound, 40, 1)
else
..()
else
diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm
index 924b5e3d590..329ea2f9ce3 100644
--- a/code/game/objects/items/weapons/defib.dm
+++ b/code/game/objects/items/weapons/defib.dm
@@ -172,12 +172,8 @@
if(on)
var/M = get(paddles, /mob)
remove_paddles(M)
- if(paddles)
- qdel(paddles)
- paddles = null
- if(bcell)
- qdel(bcell)
- bcell = null
+ QDEL_NULL(paddles)
+ QDEL_NULL(bcell)
return ..()
/obj/item/weapon/defibrillator/proc/deductcharge(var/chrgdeductamt)
@@ -256,6 +252,7 @@
force = 0
throwforce = 6
w_class = 4
+ toolspeed = 1
var/revivecost = 1000
var/cooldown = 0
@@ -346,7 +343,7 @@
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, target = M)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process
+ if(do_after(user, 30 * toolspeed, target = M)) //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/machines/defib_charge.ogg', 50, 0)
var/mob/dead/observer/ghost = H.get_ghost()
@@ -362,7 +359,7 @@
var/tloss = 600 //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, target = M)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total
+ if(do_after(user, 20 * toolspeed, target = M)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total
for(var/obj/item/carried_item in H.contents)
if(istype(carried_item, /obj/item/clothing/suit/space))
if(!defib.combat)
@@ -455,6 +452,7 @@
var/busy = 0
var/safety = 1
flags = NODROP
+ toolspeed = 1
/obj/item/weapon/borg_defib/attack(mob/M, mob/user)
var/tobehealed
@@ -495,7 +493,7 @@
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, target = M)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process
+ if(do_after(user, 30 * toolspeed, target = M)) //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/machines/defib_charge.ogg', 50, 0)
var/mob/dead/observer/ghost = H.get_ghost()
@@ -511,7 +509,7 @@
var/tloss = 600 //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, target = M)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total
+ if(do_after(user, 20 * toolspeed, target = M)) //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.")
diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm
index edf3c737787..b4d0e0b5eaa 100644
--- a/code/game/objects/items/weapons/dna_injector.dm
+++ b/code/game/objects/items/weapons/dna_injector.dm
@@ -5,7 +5,7 @@
icon_state = "dnainjector"
item_state = "dnainjector"
var/block = 0
- var/datum/dna2/record/buf=null
+ var/datum/dna2/record/buf = null
throw_speed = 3
throw_range = 5
w_class = 1
@@ -26,6 +26,10 @@
buf.dna.ResetSE()
SetValue(value)
+/obj/item/weapon/dnainjector/Destroy()
+ QDEL_NULL(buf)
+ return ..()
+
/obj/item/weapon/dnainjector/proc/GetRealBlock(var/selblock)
if(selblock==0)
return block
@@ -128,17 +132,17 @@
if(block)
if(GetState() && block == MONKEYBLOCK && ishuman(M))
- message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the Isolated [name] \red(MONKEY)")
+ message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the Isolated [name] (MONKEY)")
log_attack("[key_name(user)] injected [key_name(M)] with the Isolated [name] (MONKEY)")
- log_game("[key_name_admin(user)] injected [key_name_admin(M)] with the Isolated [name] \red(MONKEY)")
+ log_game("[key_name_admin(user)] injected [key_name_admin(M)] with the Isolated [name] (MONKEY)")
else
log_attack("[key_name(user)] injected [key_name(M)] with the Isolated [name]")
else
if(GetState(MONKEYBLOCK) && ishuman(M))
- message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the Isolated [name] \red(MONKEY)")
+ message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the Isolated [name] (MONKEY)")
log_attack("[key_name(user)] injected [key_name(M)] with the Isolated [name] (MONKEY)")
- log_game("[key_name_admin(user)] injected [key_name_admin(M)] with the Isolated [name] \red(MONKEY)")
+ log_game("[key_name_admin(user)] injected [key_name_admin(M)] with the Isolated [name] (MONKEY)")
else
log_attack("[key_name(user)] injected [key_name(M)] with the Isolated [name]")
diff --git a/code/game/objects/items/weapons/dnascrambler.dm b/code/game/objects/items/weapons/dnascrambler.dm
index 24c977ddb2d..e691fce0961 100644
--- a/code/game/objects/items/weapons/dnascrambler.dm
+++ b/code/game/objects/items/weapons/dnascrambler.dm
@@ -22,16 +22,22 @@
if(src.used)
return
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ if(H.species.flags & NO_DNA)
+ to_chat(user, "You failed to inject [M], as they have no DNA to scramble, nor flesh to inject.")
+ return
+
if(M == user)
- user.visible_message("[user.name] injects \himself with [src]!")
+ user.visible_message("[user] injects \himself with [src]!")
src.injected(user,user)
else
- user.visible_message("[user.name] is trying to inject [M.name] with [src]!")
+ user.visible_message("[user] is trying to inject [M] with [src]!")
if(do_mob(user,M,30))
- user.visible_message("[user.name] injects [M.name] with [src].")
+ user.visible_message("[user] injects [M] with [src].")
src.injected(M, user)
else
- to_chat(user, "\red You failed to inject [M.name].")
+ to_chat(user, "You failed to inject [M].")
proc/injected(var/mob/living/carbon/target, var/mob/living/carbon/user)
scramble(1, target, 100)
diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm
index 3269aefde0e..13a9186058e 100644
--- a/code/game/objects/items/weapons/explosives.dm
+++ b/code/game/objects/items/weapons/explosives.dm
@@ -7,6 +7,7 @@
det_time = 10
display_timer = 0
origin_tech = "syndicate=2"
+ toolspeed = 1
var/atom/target = null
var/image_overlay = null
var/obj/item/device/assembly_holder/nadeassembly = null
@@ -17,10 +18,9 @@
..()
/obj/item/weapon/grenade/plastic/Destroy()
- qdel(nadeassembly)
- nadeassembly = null
+ QDEL_NULL(nadeassembly)
target = null
- ..()
+ return ..()
/obj/item/weapon/grenade/plastic/attackby(obj/item/I, mob/user, params)
if(!nadeassembly && istype(I, /obj/item/device/assembly_holder))
@@ -36,7 +36,7 @@
update_icon()
return
if(nadeassembly && istype(I, /obj/item/weapon/wirecutters))
- playsound(src, 'sound/items/Wirecutter.ogg', 20, 1)
+ playsound(src, I.usesound, 20, 1)
nadeassembly.loc = get_turf(src)
nadeassembly.master = null
nadeassembly = null
@@ -73,7 +73,7 @@
return
to_chat(user, "You start planting the [src]. The timer is set to [det_time]...")
- if(do_after(user, 50, target = AM))
+ if(do_after(user, 50 * toolspeed, target = AM))
if(!user.unEquip(src))
return
src.target = AM
diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm
index 5fc704b7618..0767e26fbdb 100644
--- a/code/game/objects/items/weapons/extinguisher.dm
+++ b/code/game/objects/items/weapons/extinguisher.dm
@@ -40,7 +40,7 @@
to_chat(usr, "[bicon(src)] [src.name] contains:")
if(reagents && reagents.reagent_list.len)
for(var/datum/reagent/R in reagents.reagent_list)
- to_chat(user, "\blue [R.volume] units of [R.name]")
+ to_chat(user, "[R.volume] units of [R.name]")
/obj/item/weapon/extinguisher/New()
@@ -80,8 +80,7 @@
//TODO; Add support for reagents in water.
if(target.loc == user)//No more spraying yourself when putting your extinguisher away
return
- var/Refill = AttemptRefill(target, user)
- if(Refill)
+ if(AttemptRefill(target, user))
return
if(!safety)
if(src.reagents.total_volume < 1)
@@ -164,4 +163,4 @@
if(W.loc == my_target) break
sleep(2)
else
- return ..()
\ No newline at end of file
+ return ..()
diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm
index 71dafff99ff..70fbde22224 100644
--- a/code/game/objects/items/weapons/flamethrower.dm
+++ b/code/game/objects/items/weapons/flamethrower.dm
@@ -25,15 +25,10 @@
/obj/item/weapon/flamethrower/Destroy()
- if(weldtool)
- qdel(weldtool)
- weldtool = null
- if(igniter)
- qdel(igniter)
- igniter = null
- if(ptank)
- qdel(ptank)
- ptank = null
+ QDEL_NULL(weldtool)
+ QDEL_NULL(igniter)
+ QDEL_NULL(ptank)
+ previousturf = null
return ..()
diff --git a/code/game/objects/items/weapons/garrote.dm b/code/game/objects/items/weapons/garrote.dm
index a48bc19d512..196b0d269a0 100644
--- a/code/game/objects/items/weapons/garrote.dm
+++ b/code/game/objects/items/weapons/garrote.dm
@@ -13,6 +13,10 @@
var/improvised = 0
var/garrote_time
+/obj/item/weapon/twohanded/garrote/Destroy()
+ strangling = null
+ return ..()
+
/obj/item/weapon/twohanded/garrote/update_icon()
if(strangling) // If we're strangling someone we want our icon to stay wielded
icon_state = "garrot_unwrap"
@@ -70,7 +74,7 @@
to_chat(user, "You cannot use [src] on [M] from that angle!")
return
- if(improvised && ((M.head && (M.head.flags & HEADCOVERSMOUTH)) || (M.wear_mask && (M.wear_mask.flags & MASKCOVERSMOUTH)))) // Improvised garrotes are blocked by mouth-covering items.
+ if(improvised && ((M.head && (M.head.flags_cover & HEADCOVERSMOUTH)) || (M.wear_mask && (M.wear_mask.flags_cover & MASKCOVERSMOUTH)))) // Improvised garrotes are blocked by mouth-covering items.
to_chat(user, "[M]'s neck is blocked by something they're wearing!")
if(strangling)
diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm
index 4f9830890d4..4e558f7b64e 100644
--- a/code/game/objects/items/weapons/gift_wrappaper.dm
+++ b/code/game/objects/items/weapons/gift_wrappaper.dm
@@ -31,7 +31,7 @@
user.put_in_active_hand(gift)
src.gift.add_fingerprint(user)
else
- to_chat(user, "\blue The gift was empty!")
+ to_chat(user, "The gift was empty!")
qdel(src)
return
@@ -42,16 +42,16 @@
/obj/effect/spresent/relaymove(mob/user as mob)
if(user.stat)
return
- to_chat(user, "\blue You cant move.")
+ to_chat(user, "You cant move.")
/obj/effect/spresent/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
..()
if(!istype(W, /obj/item/weapon/wirecutters))
- to_chat(user, "\blue I need wirecutters for that.")
+ to_chat(user, "I need wirecutters for that.")
return
- to_chat(user, "\blue You cut open the present.")
+ to_chat(user, "You cut open the present.")
for(var/mob/M in src) //Should only be one but whatever.
M.loc = src.loc
diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm
index c49b2341f29..cf649bae421 100644
--- a/code/game/objects/items/weapons/grenades/chem_grenade.dm
+++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm
@@ -11,6 +11,7 @@
var/payload_name = null // used for spawned grenades
w_class = 2
force = 2
+ var/prime_sound = 'sound/items/Screwdriver2.ogg'
var/stage = EMPTY
var/list/beakers = list()
var/list/allowed_containers = list(/obj/item/weapon/reagent_containers/glass/beaker, /obj/item/weapon/reagent_containers/glass/bottle)
@@ -25,6 +26,12 @@
payload_name += " " // formatting, ignore me
update_icon()
+/obj/item/weapon/grenade/chem_grenade/Destroy()
+ QDEL_NULL(nadeassembly)
+ for(var/thing in beakers)
+ qdel(thing)
+ beakers.Cut()
+ return ..()
/obj/item/weapon/grenade/chem_grenade/examine(mob/user)
..(user)
@@ -124,7 +131,7 @@
if(stage == WIRED)
if(beakers.len)
to_chat(user, "You lock the assembly.")
- playsound(loc, 'sound/items/Screwdriver.ogg', 25, -3)
+ playsound(loc, prime_sound, 25, -3)
stage = READY
update_icon()
var/contained = ""
@@ -265,7 +272,7 @@
has_reagents = 1
if(!has_reagents)
- playsound(loc, 'sound/items/Screwdriver2.ogg', 50, 1)
+ playsound(loc, usesound, 50, 1)
return
if(nadeassembly)
@@ -347,7 +354,7 @@
if(E.reagents.total_volume) has_reagents = 1
if(!has_reagents)
- playsound(loc, 'sound/items/Screwdriver2.ogg', 50, 1)
+ playsound(loc, prime_sound, 50, 1)
return
playsound(loc, 'sound/effects/bamf.ogg', 50, 1)
diff --git a/code/game/objects/items/weapons/grenades/clowngrenade.dm b/code/game/objects/items/weapons/grenades/clowngrenade.dm
index a77bd6301b6..0fcdceff9ac 100644
--- a/code/game/objects/items/weapons/grenades/clowngrenade.dm
+++ b/code/game/objects/items/weapons/grenades/clowngrenade.dm
@@ -61,7 +61,7 @@
if((M:shoes.flags&NOSLIP) || (M:species.bodyflags & FEET_NOSLIP))
return
else
- to_chat(M, "\red Your feet feel like they're on fire!")
+ to_chat(M, "Your feet feel like they're on fire!")
M.take_overall_damage(0, max(0, (burned - 2)))
if(!istype(M, /mob/living/carbon/slime) && !isrobot(M))
diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm
index 4241c9c5c0c..3b82b972663 100644
--- a/code/game/objects/items/weapons/grenades/flashbang.dm
+++ b/code/game/objects/items/weapons/grenades/flashbang.dm
@@ -12,7 +12,7 @@
for(var/mob/living/M in hearers(7, flashbang_turf))
bang(get_turf(M), M)
- for(var/obj/effect/blob/B in hear(8,flashbang_turf)) //Blob damage here
+ for(var/obj/structure/blob/B in hear(8,flashbang_turf)) //Blob damage here
var/damage = round(30/(get_dist(B,get_turf(src))+1))
B.health -= damage
B.update_icon()
diff --git a/code/game/objects/items/weapons/grenades/smokebomb.dm b/code/game/objects/items/weapons/grenades/smokebomb.dm
index b5838839cba..798565e63fd 100644
--- a/code/game/objects/items/weapons/grenades/smokebomb.dm
+++ b/code/game/objects/items/weapons/grenades/smokebomb.dm
@@ -30,7 +30,7 @@
sleep(10)
src.smoke.start()
- for(var/obj/effect/blob/B in view(8,src))
+ for(var/obj/structure/blob/B in view(8,src))
var/damage = round(30/(get_dist(B,src)+1))
B.health -= damage
B.update_icon()
diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm
index 7b1187bcc50..723920e7a5c 100644
--- a/code/game/objects/items/weapons/handcuffs.dm
+++ b/code/game/objects/items/weapons/handcuffs.dm
@@ -130,7 +130,7 @@
to_chat(user, "You need at least six metal sheets to make good enough weights!")
return
to_chat(user, "You begin to apply [I] to [src]...")
- if(do_after(user, 35, target = src))
+ if(do_after(user, 35 * M.toolspeed, target = src))
var/obj/item/weapon/restraints/legcuffs/bola/S = new /obj/item/weapon/restraints/legcuffs/bola
M.use(6)
user.put_in_hands(S)
diff --git a/code/game/objects/items/weapons/holosign.dm b/code/game/objects/items/weapons/holosign.dm
index dac93f9cb04..1a5542b5ef5 100644
--- a/code/game/objects/items/weapons/holosign.dm
+++ b/code/game/objects/items/weapons/holosign.dm
@@ -13,6 +13,12 @@
var/list/signs = list()
var/max_signs = 20
+/obj/item/weapon/holosign_creator/Destroy()
+ for(var/sign in signs)
+ qdel(sign)
+ signs.Cut()
+ return ..()
+
/obj/item/weapon/holosign_creator/afterattack(atom/target, mob/user, flag)
if(flag)
var/turf/T = get_turf(target)
diff --git a/code/game/objects/items/weapons/holy_weapons.dm b/code/game/objects/items/weapons/holy_weapons.dm
index d82ec9fdf00..cda1145d90c 100644
--- a/code/game/objects/items/weapons/holy_weapons.dm
+++ b/code/game/objects/items/weapons/holy_weapons.dm
@@ -3,7 +3,7 @@
desc = "A rod of pure obsidian, its very presence disrupts and dampens the powers of Nar-Sie's followers."
icon_state = "nullrod"
item_state = "nullrod"
- force = 18
+ force = 15
throw_speed = 3
throw_range = 4
throwforce = 10
@@ -197,7 +197,7 @@
item_state = "hfrequency1"
desc = "Bad references are the DNA of the soul."
attack_verb = list("chopped", "sliced", "cut", "zandatsu'd")
-
+
/obj/item/weapon/nullrod/scythe/spellblade
icon_state = "spellblade"
item_state = "spellblade"
@@ -328,7 +328,7 @@
icon = 'icons/obj/toy.dmi'
icon_state = "carpplushie"
item_state = "carp_plushie"
- force = 15
+ force = 13
attack_verb = list("bitten", "eaten", "fin slapped")
hitsound = 'sound/weapons/bite.ogg'
var/used_blessing = FALSE
@@ -346,7 +346,7 @@
name = "monk's staff"
desc = "A long, tall staff made of polished wood. Traditionally used in ancient old-Earth martial arts, now used to harass the clown."
w_class = 4
- force = 15
+ force = 13
block_chance = 40
slot_flags = SLOT_BACK
sharp = 0
@@ -592,7 +592,7 @@
to_chat(missionary, "Your faith is strong, but their mind is already slaved to someone else's ideals. Perhaps an inquisition would reveal more...")
faith -= 25 //same faith cost as losing sight of them mid-conversion, but did you just find someone who can lead you to a fellow traitor?
return
- if(isloyal(target))
+ if(ismindshielded(target))
if(prob(20)) //loyalty implants typically overpower this, but you CAN get lucky and convert still (20% chance of success)
faith -= 125 //yes, this puts it negative. it's gonna take longer to recharge if you manage to convert a one of these people to balance the new power you gained through them
to_chat(missionary, "Through sheer willpower, you overcome their closed mind and rally [target] to your cause! You may need a bit longer than usual before your faith is fully recharged, and they won't remain loyal to you for long ...")
diff --git a/code/game/objects/items/weapons/implants/implant_abductor.dm b/code/game/objects/items/weapons/implants/implant_abductor.dm
new file mode 100644
index 00000000000..4985576e66c
--- /dev/null
+++ b/code/game/objects/items/weapons/implants/implant_abductor.dm
@@ -0,0 +1,46 @@
+/obj/item/weapon/implant/abductor
+ name = "recall implant"
+ desc = "Returns you to the mothership."
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "implant"
+ activated = 1
+ origin_tech = "materials=2;biotech=7;magnets=4;bluespace=4;abductor=5"
+ var/obj/machinery/abductor/pad/home
+ var/cooldown = 30
+ var/total_cooldown = 30
+
+/obj/item/weapon/implant/abductor/activate()
+ if(cooldown == total_cooldown)
+ home.Retrieve(imp_in,1)
+ cooldown = 0
+ processing_objects.Add(src)
+ else
+ to_chat(imp_in, "You must wait [(total_cooldown - cooldown)*2] seconds to use [src] again!")
+
+/obj/item/weapon/implant/abductor/process()
+ if(cooldown < total_cooldown)
+ cooldown++
+ if(cooldown == total_cooldown)
+ processing_objects.Remove(src)
+
+/obj/item/weapon/implant/abductor/implant(mob/source, mob/user)
+ if(..())
+ var/obj/machinery/abductor/console/console
+ if(ishuman(source))
+ var/mob/living/carbon/human/H = source
+ if(H.get_species() == "Abductor")
+ console = get_team_console(H.mind.abductor.team)
+ home = console.pad
+
+ if(!home)
+ console = get_team_console(pick(1, 2, 3, 4))
+ home = console.pad
+ return 1
+
+/obj/item/weapon/implant/abductor/proc/get_team_console(var/team)
+ var/obj/machinery/abductor/console/console
+ for(var/obj/machinery/abductor/console/c in abductor_equipment)
+ if(c.team == team)
+ console = c
+ break
+ return console
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/implants/implant_death_alarm.dm b/code/game/objects/items/weapons/implants/implant_death_alarm.dm
index db4f25e1be2..da9560122ad 100644
--- a/code/game/objects/items/weapons/implants/implant_death_alarm.dm
+++ b/code/game/objects/items/weapons/implants/implant_death_alarm.dm
@@ -3,6 +3,7 @@
desc = "An alarm which monitors host vital signs and transmits a radio message upon death."
var/mobname = "Will Robinson"
activated = 0
+ var/static/list/stealth_areas = typecacheof(list(/area/syndicate_station, /area/syndicate_mothership, /area/shuttle/syndicate_elite))
/obj/item/weapon/implant/death_alarm/get_data()
var/dat = {"Implant Specifications:
@@ -33,26 +34,26 @@
/obj/item/weapon/implant/death_alarm/activate(var/cause)
var/mob/M = imp_in
var/area/t = get_area(M)
+
+ var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null)
+ a.follow_target = M
+
switch(cause)
if("death")
- var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null)
- if(istype(t, /area/syndicate_station) || istype(t, /area/syndicate_mothership) || istype(t, /area/shuttle/syndicate_elite) )
+ if(is_type_in_typecache(t, stealth_areas))
//give the syndies a bit of stealth
a.autosay("[mobname] has died in Space!", "[mobname]'s Death Alarm")
else
a.autosay("[mobname] has died in [t.name]!", "[mobname]'s Death Alarm")
- qdel(a)
qdel(src)
if("emp")
- var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null)
var/name = prob(50) ? t.name : pick(teleportlocs)
a.autosay("[mobname] has died in [name]!", "[mobname]'s Death Alarm")
- qdel(a)
else
- var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null)
a.autosay("[mobname] has died-zzzzt in-in-in...", "[mobname]'s Death Alarm")
- qdel(a)
qdel(src)
+
+ qdel(a)
/obj/item/weapon/implant/death_alarm/emp_act(severity) //for some reason alarms stop going off in case they are emp'd, even without this
activate("emp") //let's shout that this dude is dead
diff --git a/code/game/objects/items/weapons/implants/implant_mindshield.dm b/code/game/objects/items/weapons/implants/implant_mindshield.dm
index a6efb21661f..a76b373e6b7 100644
--- a/code/game/objects/items/weapons/implants/implant_mindshield.dm
+++ b/code/game/objects/items/weapons/implants/implant_mindshield.dm
@@ -1,10 +1,10 @@
-/obj/item/weapon/implant/loyalty
+/obj/item/weapon/implant/mindshield
name = "mindshield implant"
desc = "Stops people messing with your mind."
origin_tech = "materials=2;biotech=4;programming=4"
activated = 0
-/obj/item/weapon/implant/loyalty/get_data()
+/obj/item/weapon/implant/mindshield/get_data()
var/dat = {"Implant Specifications: Name: Nanotrasen Employee Management Implant Life: Ten years.
@@ -17,7 +17,7 @@
return dat
-/obj/item/weapon/implant/loyalty/implant(mob/target)
+/obj/item/weapon/implant/mindshield/implant(mob/target)
if(..())
if(target.mind in ticker.mode.head_revolutionaries || is_shadow_or_thrall(target))
target.visible_message("[target] seems to resist the implant!", "You feel the corporate tendrils of Nanotrasen try to invade your mind!")
@@ -33,7 +33,7 @@
return 1
return 0
-/obj/item/weapon/implant/loyalty/removed(mob/target, var/silent = 0)
+/obj/item/weapon/implant/mindshield/removed(mob/target, var/silent = 0)
if(..())
if(target.stat != DEAD && !silent)
to_chat(target, "You feel a sense of liberation as Nanotrasen's grip on your mind fades away.")
@@ -41,19 +41,19 @@
return 0
-/obj/item/weapon/implanter/loyalty
+/obj/item/weapon/implanter/mindshield
name = "implanter (mindshield)"
-/obj/item/weapon/implanter/loyalty/New()
- imp = new /obj/item/weapon/implant/loyalty(src)
+/obj/item/weapon/implanter/mindshield/New()
+ imp = new /obj/item/weapon/implant/mindshield(src)
..()
update_icon()
-/obj/item/weapon/implantcase/loyalty
+/obj/item/weapon/implantcase/mindshield
name = "implant case - 'mindshield'"
desc = "A glass case containing a mindshield implant."
-/obj/item/weapon/implantcase/loyalty/New()
- imp = new /obj/item/weapon/implant/loyalty(src)
+/obj/item/weapon/implantcase/mindshield/New()
+ imp = new /obj/item/weapon/implant/mindshield(src)
..()
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/implants/implant_traitor.dm b/code/game/objects/items/weapons/implants/implant_traitor.dm
index bb80d50845d..47b993b6007 100644
--- a/code/game/objects/items/weapons/implants/implant_traitor.dm
+++ b/code/game/objects/items/weapons/implants/implant_traitor.dm
@@ -38,7 +38,7 @@
removed(M)
qdel(src)
return -1
- if(isloyal(H))
+ if(ismindshielded(H))
H.visible_message("[H] seems to resist the implant!", "You feel a strange sensation in your head that quickly dissipates.")
removed(M)
qdel(src)
diff --git a/code/game/objects/items/weapons/implants/implantchair.dm b/code/game/objects/items/weapons/implants/implantchair.dm
index 141f9b14f89..53183e21d63 100644
--- a/code/game/objects/items/weapons/implants/implantchair.dm
+++ b/code/game/objects/items/weapons/implants/implantchair.dm
@@ -11,7 +11,7 @@
var/ready = 1
var/malfunction = 0
- var/list/obj/item/weapon/implant/loyalty/implant_list = list()
+ var/list/obj/item/weapon/implant/mindshield/implant_list = list()
var/max_implants = 5
var/injection_cooldown = 600
var/replenish_cooldown = 6000
@@ -122,9 +122,9 @@
if(!istype(M, /mob/living/carbon))
return
if(!implant_list.len) return
- for(var/obj/item/weapon/implant/loyalty/imp in implant_list)
+ for(var/obj/item/weapon/implant/mindshield/imp in implant_list)
if(!imp) continue
- if(istype(imp, /obj/item/weapon/implant/loyalty))
+ if(istype(imp, /obj/item/weapon/implant/mindshield))
M.visible_message("[M] has been implanted by the [src.name].")
if(imp.implant(M))
@@ -135,7 +135,7 @@
/obj/machinery/implantchair/add_implants()
for(var/i=0, i[user] is attemping to implant [M].")
var/turf/T = get_turf(M)
- if(T && (M == user || do_after(user, 50, target = M)))
+ if(T && (M == user || do_after(user, 50 * toolspeed, target = M)))
if(user && M && (get_turf(M) == T) && src && imp)
if(imp.implant(M, user))
if(M == user)
diff --git a/code/game/objects/items/weapons/legcuffs.dm b/code/game/objects/items/weapons/legcuffs.dm
index 7e62a14250b..3bec7f32f9e 100644
--- a/code/game/objects/items/weapons/legcuffs.dm
+++ b/code/game/objects/items/weapons/legcuffs.dm
@@ -27,12 +27,8 @@
icon_state = "[initial(icon_state)][armed]"
/obj/item/weapon/restraints/legcuffs/beartrap/Destroy()
- if(IED)
- qdel(IED)
- IED = null
- if(sig)
- qdel(sig)
- sig = null
+ QDEL_NULL(IED)
+ QDEL_NULL(sig)
return ..()
/obj/item/weapon/restraints/legcuffs/beartrap/suicide_act(mob/user)
diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm
index 5e262ce4afa..afc5dbd93ad 100644
--- a/code/game/objects/items/weapons/melee/energy.dm
+++ b/code/game/objects/items/weapons/melee/energy.dm
@@ -8,6 +8,8 @@
var/list/attack_verb_on = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
no_embed = 1 // Physically impossible for energy weapons to embed themselves into people, this should fix that. -- Dave
hitsound = 'sound/weapons/blade1.ogg' // Probably more appropriate than the previous hitsound. -- Dave
+ usesound = 'sound/weapons/blade1.ogg'
+ toolspeed = 1
/obj/item/weapon/melee/energy/suicide_act(mob/user)
user.visible_message(pick("[user] is slitting \his stomach open with the [src.name]! It looks like \he's trying to commit seppuku.", \
@@ -107,7 +109,7 @@
if(R.cell)
var/obj/item/weapon/stock_parts/cell/C = R.cell
if(active && !(C.use(hitcost)))
- attack_self()
+ attack_self(R)
to_chat(R, "It's out of charge!")
return
..()
diff --git a/code/game/objects/items/weapons/mop.dm b/code/game/objects/items/weapons/mop.dm
index 06bb11dd59e..4495f637e56 100644
--- a/code/game/objects/items/weapons/mop.dm
+++ b/code/game/objects/items/weapons/mop.dm
@@ -18,6 +18,7 @@
var/mopspeed = 30
/obj/item/weapon/mop/New()
+ ..()
create_reagents(mopcap)
janitorial_equipment += src
@@ -28,6 +29,7 @@
/obj/item/weapon/mop/proc/clean(turf/simulated/A)
if(reagents.has_reagent("water", 1) || reagents.has_reagent("cleaner", 1) || reagents.has_reagent("holywater", 1))
A.clean_blood()
+ A.dirt = 0
for(var/obj/effect/O in A)
if(is_cleanable(O))
qdel(O)
diff --git a/code/game/objects/items/weapons/pneumaticCannon.dm b/code/game/objects/items/weapons/pneumaticCannon.dm
index 78a974240de..c54a31fad05 100644
--- a/code/game/objects/items/weapons/pneumaticCannon.dm
+++ b/code/game/objects/items/weapons/pneumaticCannon.dm
@@ -17,9 +17,7 @@
var/pressureSetting = 1 //How powerful the cannon is - higher pressure = more gas but more powerful throws
/obj/item/weapon/pneumatic_cannon/Destroy()
- if(tank)
- qdel(tank)
- tank = null
+ QDEL_NULL(tank)
for(var/obj/item/I in loadedItems)
qdel(I)
loadedItems.Cut()
diff --git a/code/game/objects/items/weapons/power_cells.dm b/code/game/objects/items/weapons/power_cells.dm
index 005ef313a4f..de5d788a9f3 100644
--- a/code/game/objects/items/weapons/power_cells.dm
+++ b/code/game/objects/items/weapons/power_cells.dm
@@ -5,18 +5,17 @@
icon_state = "cell"
item_state = "cell"
origin_tech = "powerstorage=1"
- force = 5.0
- throwforce = 5.0
- throw_speed = 3
+ force = 5
+ throwforce = 5
+ throw_speed = 2
throw_range = 5
- w_class = 2
+ w_class = WEIGHT_CLASS_SMALL
var/charge = 0 // note %age conveted to actual charge in New
- var/maxcharge = 10000
- rating = 1
+ var/maxcharge = 1000
materials = list(MAT_METAL=700, MAT_GLASS=50)
var/rigged = 0 // true if rigged to explode
+ var/chargerate = 100 //how much power is given every tick in a recharger
var/minor_fault = 0 //If not 100% reliable, it will build up faults.
- var/chargerate = 1000 //how much power is given every tick in a recharger
var/self_recharge = 0 //does it self recharge, over time, or not?
var/grown_battery = FALSE // If it's a grown that acts as a battery, add a wire overlay to it.
@@ -62,10 +61,9 @@
/obj/item/weapon/stock_parts/cell/crap
name = "\improper Nanotrasen brand rechargable AA battery"
desc = "You can't top the plasma top." //TOTALLY TRADEMARK INFRINGEMENT
- origin_tech = null
- maxcharge = 5000
- rating = 2
+ maxcharge = 500
materials = list(MAT_GLASS=40)
+ rating = 2
/obj/item/weapon/stock_parts/cell/crap/empty/New()
..()
@@ -74,9 +72,9 @@
/obj/item/weapon/stock_parts/cell/secborg
name = "\improper Security borg rechargable D battery"
origin_tech = null
- maxcharge = 6000 //6000 max charge / 1000 charge per shot = six shots
- rating = 2.5
+ maxcharge = 600 //600 max charge / 100 charge per shot = six shots
materials = list(MAT_GLASS=40)
+ rating = 2.5
/obj/item/weapon/stock_parts/cell/secborg/empty/New()
..()
@@ -86,11 +84,18 @@
name = "high-capacity power cell"
origin_tech = "powerstorage=2"
icon_state = "hcell"
- maxcharge = 15000
- rating = 3
+ maxcharge = 10000
materials = list(MAT_GLASS=60)
+ rating = 3
chargerate = 1500
+/obj/item/weapon/stock_parts/cell/high/plus
+ name = "high-capacity power cell+"
+ desc = "Where did these come from?"
+ icon_state = "h+cell"
+ maxcharge = 15000
+ chargerate = 2250
+
/obj/item/weapon/stock_parts/cell/high/empty/New()
..()
charge = 0
@@ -100,7 +105,7 @@
origin_tech = "powerstorage=5"
icon_state = "scell"
maxcharge = 20000
- materials = list(MAT_GLASS=70)
+ materials = list(MAT_GLASS=300)
rating = 4
chargerate = 2000
@@ -113,8 +118,8 @@
origin_tech = "powerstorage=6"
icon_state = "hpcell"
maxcharge = 30000
+ materials = list(MAT_GLASS=400)
rating = 5
- materials = list(MAT_GLASS=80)
chargerate = 3000
/obj/item/weapon/stock_parts/cell/hyper/empty/New()
@@ -126,7 +131,7 @@
origin_tech = "powerstorage=7"
icon_state = "bscell"
maxcharge = 40000
- materials = list(MAT_GLASS=80)
+ materials = list(MAT_GLASS=600)
rating = 6
chargerate = 4000
@@ -139,8 +144,8 @@
icon_state = "icell"
origin_tech = null
maxcharge = 30000
+ materials = list(MAT_GLASS=1000)
rating = 6
- materials = list(MAT_GLASS=80)
chargerate = 30000
/obj/item/weapon/stock_parts/cell/infinite/use()
@@ -153,7 +158,7 @@
icon_state = "potato"
origin_tech = "powerstorage=1;biotech=1"
charge = 100
- maxcharge = 3000
+ maxcharge = 300
materials = list()
rating = 1
minor_fault = 1
@@ -170,17 +175,17 @@
/obj/item/weapon/stock_parts/cell/pulse //200 pulse shots
name = "pulse rifle power cell"
- maxcharge = 400000
+ maxcharge = 40000
rating = 3
chargerate = 1500
-/obj/item/weapon/stock_parts/cell/pulse/carbine
+/obj/item/weapon/stock_parts/cell/pulse/carbine //25 pulse shots
name = "pulse carbine power cell"
- maxcharge = 40000
+ maxcharge = 5000
-/obj/item/weapon/stock_parts/cell/pulse/pistol
+/obj/item/weapon/stock_parts/cell/pulse/pistol //10 pulse shots
name = "pulse pistol power cell"
- maxcharge = 16000
+ maxcharge = 2000
/obj/item/weapon/stock_parts/cell/ninja
name = "spider-clan power cell"
@@ -192,7 +197,7 @@
/obj/item/weapon/stock_parts/cell/emproof
name = "\improper EMP-proof cell"
desc = "An EMP-proof cell."
- maxcharge = 5000
+ maxcharge = 500
rating = 2
/obj/item/weapon/stock_parts/cell/emproof/empty/New()
diff --git a/code/game/objects/items/weapons/powerfist.dm b/code/game/objects/items/weapons/powerfist.dm
index 0167ab589be..9ee2c46728e 100644
--- a/code/game/objects/items/weapons/powerfist.dm
+++ b/code/game/objects/items/weapons/powerfist.dm
@@ -17,9 +17,7 @@
/obj/item/weapon/melee/powerfist/Destroy()
- if(tank)
- qdel(tank)
- tank = null
+ QDEL_NULL(tank)
return ..()
/obj/item/weapon/melee/powerfist/examine(mob/user)
@@ -46,7 +44,7 @@
fisto_setting = 3
if(3)
fisto_setting = 1
- playsound(loc, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(loc, W.usesound, 50, 1)
to_chat(user, "You tweak \the [src]'s piston valve to [fisto_setting].")
else if(istype(W, /obj/item/weapon/screwdriver))
if(tank)
diff --git a/code/game/objects/items/weapons/scissors.dm b/code/game/objects/items/weapons/scissors.dm
index 00b85d8ebe1..6cfb677bd21 100644
--- a/code/game/objects/items/weapons/scissors.dm
+++ b/code/game/objects/items/weapons/scissors.dm
@@ -9,6 +9,7 @@
w_class = 2
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("slices", "cuts", "stabs", "jabs")
+ toolspeed = 1
/obj/item/weapon/scissors/barber
name = "Barber's Scissors"
@@ -16,6 +17,7 @@
icon_state = "bscissor"
item_state = "scissor"
attack_verb = list("beautifully sliced", "artistically cut", "smoothly stabbed", "quickly jabbed")
+ toolspeed = 0.75
/obj/item/weapon/scissors/attack(mob/living/carbon/M as mob, mob/user as mob)
if(user.a_intent != "help")
@@ -79,7 +81,7 @@
var/h_new_style = input(user, "Select a hair style", "Grooming") as null|anything in species_hair
user.visible_message("[user] starts cutting [M]'s hair!", "You start cutting [M]'s hair!") //arguments for this are: 1. what others see 2. what the user sees. --Fixed grammar, (TGameCo)
playsound(loc, 'sound/goonstation/misc/Scissor.ogg', 100, 1)
- if(do_after(user, 50, target = H)) //this is the part that adds a delay. delay is in deciseconds. --Made it 5 seconds, because hair isn't cut in one second in real life, and I want at least a little bit longer time, (TGameCo)
+ if(do_after(user, 50 * toolspeed, target = H)) //this is the part that adds a delay. delay is in deciseconds. --Made it 5 seconds, because hair isn't cut in one second in real life, and I want at least a little bit longer time, (TGameCo)
if(!(M in view(1))) //Adjacency test
user.visible_message("[user] stops cutting [M]'s hair.", "You stop cutting [M]'s hair.")
return
@@ -112,7 +114,7 @@
is_cutting = 1
user.visible_message("[user] starts cutting [M]'s hair!", "You start cutting [M]'s hair!")
playsound(loc, 'sound/goonstation/misc/Scissor.ogg', 100, 1)
- if(do_after(user, 50, target = H))
+ if(do_after(user, 50 * toolspeed, target = H))
playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
user.visible_message("[user] abruptly stops cutting [M]'s hair and slices their throat!", "You stop cutting [M]'s hair and slice their throat!") //Just a little off the top.
H.AdjustLoseBreath(10) //30 Oxy damage over time
diff --git a/code/game/objects/items/weapons/shards.dm b/code/game/objects/items/weapons/shards.dm
index 4e5de260926..0ba245af4e6 100644
--- a/code/game/objects/items/weapons/shards.dm
+++ b/code/game/objects/items/weapons/shards.dm
@@ -35,6 +35,24 @@
else
..()
+/obj/item/weapon/shard/afterattack(atom/movable/AM, mob/user, proximity)
+ if(!proximity || !(src in user))
+ return
+ if(isturf(AM))
+ return
+ if(istype(AM, /obj/item/weapon/storage))
+ return
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ if(!H.gloves)
+ var/obj/item/organ/external/affecting = H.get_organ("[user.hand ? "l" : "r" ]_hand")
+ if(affecting.status & ORGAN_ROBOT)
+ return
+ to_chat(H, "[src] cuts into your hand!")
+ if(affecting.take_damage(force*0.5))
+ H.UpdateDamageIcon()
+ H.updatehealth()
+
/obj/item/weapon/shard/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = I
diff --git a/code/game/objects/items/weapons/stock_parts.dm b/code/game/objects/items/weapons/stock_parts.dm
index e6e58196108..74fc3a5be6c 100644
--- a/code/game/objects/items/weapons/stock_parts.dm
+++ b/code/game/objects/items/weapons/stock_parts.dm
@@ -6,7 +6,7 @@
icon_state = "RPED"
item_state = "RPED"
w_class = 5
- can_hold = list("/obj/item/weapon/stock_parts")
+ can_hold = list(/obj/item/weapon/stock_parts)
storage_slots = 50
use_to_pickup = 1
allow_quick_gather = 1
@@ -18,6 +18,8 @@
var/works_from_distance = 0
var/primary_sound = 'sound/items/rped.ogg'
var/alt_sound = null
+ toolspeed = 1
+ usesound = 'sound/items/rped.ogg'
/obj/item/weapon/storage/part_replacer/afterattack(obj/machinery/T as obj, mob/living/carbon/human/user as mob, flag, params)
if(flag)
@@ -41,6 +43,8 @@
works_from_distance = 1
primary_sound = 'sound/items/PSHOOM.ogg'
alt_sound = 'sound/items/PSHOOM_2.ogg'
+ usesound = 'sound/items/PSHOOM.ogg'
+ toolspeed = 0.5
/obj/item/weapon/storage/part_replacer/proc/play_rped_sound()
//Plays the sound for RPED exchanging or installing parts.
@@ -61,9 +65,12 @@
icon = 'icons/obj/stock_parts.dmi'
w_class = 2
var/rating = 1
- New()
- src.pixel_x = rand(-5.0, 5)
- src.pixel_y = rand(-5.0, 5)
+ toolspeed = 1
+ usesound = 'sound/items/Deconstruct.ogg'
+
+/obj/item/weapon/stock_parts/New()
+ src.pixel_x = rand(-5.0, 5)
+ src.pixel_y = rand(-5.0, 5)
//Rank 1
diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm
index c664ca9fff9..d0dee297cd7 100644
--- a/code/game/objects/items/weapons/storage/backpack.dm
+++ b/code/game/objects/items/weapons/storage/backpack.dm
@@ -45,13 +45,13 @@
attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(crit_fail)
- to_chat(user, "\red The Bluespace generator isn't working.")
+ to_chat(user, "The Bluespace generator isn't working.")
return
else if(istype(W, /obj/item/weapon/storage/backpack/holding) && !W.crit_fail)
var/response = alert(user, "Are you sure you want to put the bag of holding inside another bag of holding?","Are you sure you want to die?","Yes","No")
if(response == "Yes")
user.visible_message("[user] grins as \he begins to put a Bag of Holding into a Bag of Holding!", "You begin to put the Bag of Holding into the Bag of Holding!")
- if(do_after(user,30,target=src))
+ if(do_after(user, 30, target=src))
investigate_log("has become a singularity. Caused by [user.key]","singulo")
user.visible_message("[user] erupts in evil laughter as \he puts the Bag of Holding into another Bag of Holding!", "You can't help but laugh wildly as you put the Bag of Holding into another Bag of Holding, complete darkness surrounding you."," You hear the sound of scientific evil brewing! ")
qdel(W)
@@ -68,10 +68,10 @@
proc/failcheck(mob/user as mob)
if(prob(src.reliability)) return 1 //No failure
if(prob(src.reliability))
- to_chat(user, "\red The Bluespace portal resists your attempt to add another item.")//light failure
+ to_chat(user, "The Bluespace portal resists your attempt to add another item.")//light failure
else
- to_chat(user, "\red The Bluespace generator malfunctions!")
+ to_chat(user, "The Bluespace generator malfunctions!")
for(var/obj/O in src.contents) //it broke, delete what was in it
qdel(O)
crit_fail = 1
@@ -189,7 +189,7 @@
/obj/item/weapon/storage/backpack/satchel_norm
name = "satchel"
desc = "A deluxe NT Satchel, made of the highest quality leather."
- icon_state = "satchel"
+ icon_state = "satchel-norm"
/obj/item/weapon/storage/backpack/satchel_eng
name = "industrial satchel"
@@ -447,4 +447,4 @@
/obj/item/weapon/storage/backpack/ert/janitor
name = "emergency response team janitor backpack"
desc = "A spacious backpack with lots of pockets, worn by janitorial members of a Nanotrasen Emergency Response Team."
- icon_state = "ert_janitor"
\ No newline at end of file
+ icon_state = "ert_janitor"
diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm
index 49ba664619f..b90d11a543e 100644
--- a/code/game/objects/items/weapons/storage/bags.dm
+++ b/code/game/objects/items/weapons/storage/bags.dm
@@ -37,7 +37,7 @@
max_w_class = 2
storage_slots = 30
can_hold = list() // any
- cant_hold = list("/obj/item/weapon/disk/nuclear")
+ cant_hold = list(/obj/item/weapon/disk/nuclear)
/obj/item/weapon/storage/bag/trash/suicide_act(mob/user)
user.visible_message("[user] puts the [src.name] over their head and starts chomping at the insides! Disgusting!")
@@ -93,12 +93,12 @@
storage_slots = 7
display_contents_with_number = 0 //or else this will lead to stupid behavior.
can_hold = list() // any
- cant_hold = list("/obj/item/weapon/disk/nuclear")
+ cant_hold = list(/obj/item/weapon/disk/nuclear)
/obj/item/weapon/storage/bag/plasticbag/mob_can_equip(M as mob, slot)
if(slot==slot_head && contents.len)
- to_chat(M, "\red You need to empty the bag first!")
+ to_chat(M, "You need to empty the bag first!")
return 0
return ..()
@@ -136,7 +136,7 @@
storage_slots = 50
max_combined_w_class = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * ore.w_class
max_w_class = 3
- can_hold = list("/obj/item/weapon/ore")
+ can_hold = list(/obj/item/weapon/ore)
/obj/item/weapon/storage/bag/ore/cyborg
name = "cyborg mining satchel"
@@ -166,7 +166,7 @@
max_combined_w_class = 100 //Doesn't matter what this is, so long as it's more or equal to storage_slots * plants.w_class
max_w_class = 3
w_class = 1
- can_hold = list("/obj/item/weapon/reagent_containers/food/snacks/grown","/obj/item/seeds","/obj/item/weapon/grown","/obj/item/weapon/reagent_containers/food/snacks/ash_flora")
+ can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/grown,/obj/item/seeds,/obj/item/weapon/grown,/obj/item/weapon/reagent_containers/food/snacks/ash_flora)
burn_state = FLAMMABLE
/obj/item/weapon/storage/bag/plants/portaseeder
@@ -220,7 +220,7 @@
current += S.amount
if(capacity == current)//If it's full, you're done
if(!stop_messages)
- to_chat(usr, "\red The snatcher is full.")
+ to_chat(usr, "The snatcher is full.")
return 0
return 1
@@ -345,8 +345,7 @@
max_combined_w_class = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * cash.w_class
max_w_class = 3
w_class = 1
-
- can_hold = list("/obj/item/weapon/coin","/obj/item/weapon/spacecash")
+ can_hold = list(/obj/item/weapon/coin,/obj/item/stack/spacecash)
// -----------------------------
// Book bag
@@ -362,7 +361,7 @@
max_combined_w_class = 21
max_w_class = 3
w_class = 4 //Bigger than a book because physics
- can_hold = list("/obj/item/weapon/book", "/obj/item/weapon/storage/bible", "/obj/item/weapon/tome", "/obj/item/weapon/spellbook")
+ can_hold = list(/obj/item/weapon/book, /obj/item/weapon/storage/bible, /obj/item/weapon/tome, /obj/item/weapon/spellbook)
burn_state = FLAMMABLE
/*
@@ -452,9 +451,9 @@
sleep(rand(2,4))
if( droppedSomething )
if( foundtable )
- user.visible_message("\blue [user] unloads their service tray.")
+ user.visible_message("[user] unloads their service tray.")
else
- user.visible_message("\blue [user] drops all the items on their tray.")
+ user.visible_message("[user] drops all the items on their tray.")
return ..()
@@ -471,7 +470,7 @@
storage_slots = 50
max_combined_w_class = 200
w_class = 1
- can_hold = list("/obj/item/weapon/reagent_containers/food/pill","/obj/item/weapon/reagent_containers/glass/beaker","/obj/item/weapon/reagent_containers/glass/bottle")
+ can_hold = list(/obj/item/weapon/reagent_containers/food/pill,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/glass/bottle)
burn_state = FLAMMABLE
/*
* Biowaste bag (mostly for xenobiologists)
@@ -485,5 +484,5 @@
storage_slots = 25
max_combined_w_class = 200
w_class = 1
- can_hold = list("/obj/item/slime_extract","/obj/item/weapon/reagent_containers/food/snacks/monkeycube","/obj/item/weapon/reagent_containers/syringe","/obj/item/weapon/reagent_containers/glass/beaker","/obj/item/weapon/reagent_containers/glass/bottle","/obj/item/weapon/reagent_containers/blood","/obj/item/weapon/reagent_containers/hypospray/autoinjector")
+ can_hold = list(/obj/item/slime_extract,/obj/item/weapon/reagent_containers/food/snacks/monkeycube,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/reagent_containers/blood,/obj/item/weapon/reagent_containers/hypospray/autoinjector)
burn_state = FLAMMABLE
diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm
index fe29ba5c23a..609edd2961f 100644
--- a/code/game/objects/items/weapons/storage/belt.dm
+++ b/code/game/objects/items/weapons/storage/belt.dm
@@ -48,19 +48,18 @@
item_state = "utility"
use_item_overlays = 1
can_hold = list(
- "/obj/item/weapon/crowbar",
- "/obj/item/weapon/screwdriver",
- "/obj/item/weapon/weldingtool",
- "/obj/item/weapon/wirecutters",
- "/obj/item/weapon/wrench",
- "/obj/item/device/multitool",
- "/obj/item/device/flashlight",
- "/obj/item/stack/cable_coil",
- "/obj/item/device/t_scanner",
- "/obj/item/device/analyzer",
- "/obj/item/taperoll/engineering",
- "/obj/item/weapon/extinguisher/mini")
-
+ /obj/item/weapon/crowbar,
+ /obj/item/weapon/screwdriver,
+ /obj/item/weapon/weldingtool,
+ /obj/item/weapon/wirecutters,
+ /obj/item/weapon/wrench,
+ /obj/item/device/multitool,
+ /obj/item/device/flashlight,
+ /obj/item/stack/cable_coil,
+ /obj/item/device/t_scanner,
+ /obj/item/device/analyzer,
+ /obj/item/taperoll/engineering,
+ /obj/item/weapon/extinguisher/mini)
/obj/item/weapon/storage/belt/utility/full/New()
..()
@@ -69,7 +68,7 @@
new /obj/item/weapon/weldingtool(src)
new /obj/item/weapon/crowbar(src)
new /obj/item/weapon/wirecutters(src)
- new /obj/item/stack/cable_coil(src,30,pick("red","yellow","orange"))
+ new /obj/item/stack/cable_coil(src, 30, pick(COLOR_RED, COLOR_YELLOW, COLOR_ORANGE))
update_icon()
/obj/item/weapon/storage/belt/utility/full/multitool/New()
@@ -88,7 +87,23 @@
new /obj/item/weapon/extinguisher/mini(src)
update_icon()
+/obj/item/weapon/storage/belt/utility/chief
+ name = "Chief Engineer's toolbelt"
+ desc = "Holds tools, looks snazzy"
+ icon_state = "utilitybelt_ce"
+ item_state = "utility_ce"
+/obj/item/weapon/storage/belt/utility/chief/full/New()
+ ..()
+ new /obj/item/weapon/screwdriver/power(src)
+ new /obj/item/weapon/crowbar/power(src)
+ new /obj/item/weapon/weldingtool/experimental(src)//This can be changed if this is too much
+ new /obj/item/device/multitool(src)
+ new /obj/item/stack/cable_coil(src, 30, pick(COLOR_RED, COLOR_YELLOW, COLOR_ORANGE))
+ new /obj/item/weapon/extinguisher/mini(src)
+ new /obj/item/device/analyzer(src)
+ update_icon()
+ //much roomier now that we've managed to remove two tools
/obj/item/weapon/storage/belt/medical
use_to_pickup = 1 //Allow medical belt to pick up medicine
@@ -98,24 +113,24 @@
item_state = "medical"
use_item_overlays = 1
can_hold = list(
- "/obj/item/device/healthanalyzer",
- "/obj/item/weapon/dnainjector",
- "/obj/item/weapon/reagent_containers/dropper",
- "/obj/item/weapon/reagent_containers/glass/beaker",
- "/obj/item/weapon/reagent_containers/glass/bottle",
- "/obj/item/weapon/reagent_containers/food/pill",
- "/obj/item/weapon/reagent_containers/syringe",
- "/obj/item/weapon/reagent_containers/glass/dispenser",
- "/obj/item/weapon/lighter/zippo",
- "/obj/item/weapon/storage/fancy/cigarettes",
- "/obj/item/weapon/storage/pill_bottle",
- "/obj/item/stack/medical",
- "/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/device/rad_laser",
- "/obj/item/device/sensor_device"
+ /obj/item/device/healthanalyzer,
+ /obj/item/weapon/dnainjector,
+ /obj/item/weapon/reagent_containers/dropper,
+ /obj/item/weapon/reagent_containers/glass/beaker,
+ /obj/item/weapon/reagent_containers/glass/bottle,
+ /obj/item/weapon/reagent_containers/food/pill,
+ /obj/item/weapon/reagent_containers/syringe,
+ /obj/item/weapon/lighter/zippo,
+ /obj/item/weapon/storage/fancy/cigarettes,
+ /obj/item/weapon/storage/pill_bottle,
+ /obj/item/stack/medical,
+ /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/device/rad_laser,
+ /obj/item/device/sensor_device,
+ /obj/item/weapon/wrench/medical,
)
/obj/item/weapon/storage/belt/medical/response_team
@@ -139,22 +154,19 @@
item_state = "botany"
use_item_overlays = 1
can_hold = list(
- "/obj/item/device/plant_analyzer",
- "/obj/item/weapon/cultivator",
- "/obj/item/weapon/hatchet",
- "/obj/item/weapon/reagent_containers/glass/bottle",
- "/obj/item/weapon/plantspray",
-// "/obj/item/weapon/reagent_containers/syringe",
-// "/obj/item/weapon/reagent_containers/glass/beaker",
- "/obj/item/weapon/lighter/zippo",
- "/obj/item/weapon/storage/fancy/cigarettes",
- "obj/item/weapon/rollingpaperpack",
- "/obj/item/weapon/shovel/spade",
- "/obj/item/device/flashlight/pen",
- "/obj/item/seeds",
- "/obj/item/weapon/wirecutters",
- "/obj/item/weapon/wrench",
- "/obj/item/weapon/disk/botany",
+ /obj/item/device/plant_analyzer,
+ /obj/item/weapon/cultivator,
+ /obj/item/weapon/hatchet,
+ /obj/item/weapon/reagent_containers/glass/bottle,
+// /obj/item/weapon/reagent_containers/syringe,
+// /obj/item/weapon/reagent_containers/glass/beaker,
+ /obj/item/weapon/lighter/zippo,
+ /obj/item/weapon/storage/fancy/cigarettes,
+ /obj/item/weapon/shovel/spade,
+ /obj/item/device/flashlight/pen,
+ /obj/item/seeds,
+ /obj/item/weapon/wirecutters,
+ /obj/item/weapon/wrench,
)
@@ -167,22 +179,22 @@
max_w_class = 3
use_item_overlays = 1
can_hold = list(
- "/obj/item/weapon/grenade/flashbang",
- "/obj/item/weapon/grenade/chem_grenade/teargas",
- "/obj/item/weapon/reagent_containers/spray/pepper",
- "/obj/item/weapon/restraints/handcuffs",
- "/obj/item/device/flash",
- "/obj/item/clothing/glasses",
- "/obj/item/ammo_casing/shotgun",
- "/obj/item/ammo_box",
- "/obj/item/weapon/reagent_containers/food/snacks/donut",
- "/obj/item/weapon/kitchen/knife/combat",
- "/obj/item/weapon/melee/baton",
- "/obj/item/weapon/melee/classic_baton",
- "/obj/item/device/flashlight/seclite",
- "/obj/item/taperoll/police",
- "/obj/item/weapon/melee/classic_baton/telescopic",
- "/obj/item/weapon/restraints/legcuffs/bola")
+ /obj/item/weapon/grenade/flashbang,
+ /obj/item/weapon/grenade/chem_grenade/teargas,
+ /obj/item/weapon/reagent_containers/spray/pepper,
+ /obj/item/weapon/restraints/handcuffs,
+ /obj/item/device/flash,
+ /obj/item/clothing/glasses,
+ /obj/item/ammo_casing/shotgun,
+ /obj/item/ammo_box,
+ /obj/item/weapon/reagent_containers/food/snacks/donut,
+ /obj/item/weapon/kitchen/knife/combat,
+ /obj/item/weapon/melee/baton,
+ /obj/item/weapon/melee/classic_baton,
+ /obj/item/device/flashlight/seclite,
+ /obj/item/taperoll/police,
+ /obj/item/weapon/melee/classic_baton/telescopic,
+ /obj/item/weapon/restraints/legcuffs/bola)
/obj/item/weapon/storage/belt/security/sec/New()
..()
@@ -236,6 +248,24 @@
desc = "A syndicate belt designed to be used by boarding parties. Its style is modelled after the hardsuits they wear."
icon_state = "militarybelt"
item_state = "military"
+ max_w_class = WEIGHT_CLASS_SMALL
+
+/obj/item/weapon/storage/belt/military/abductor
+ name = "agent belt"
+ desc = "A belt used by abductor agents."
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "belt"
+ item_state = "security"
+
+/obj/item/weapon/storage/belt/military/abductor/full/New()
+ ..()
+ new /obj/item/weapon/screwdriver/abductor(src)
+ new /obj/item/weapon/wrench/abductor(src)
+ new /obj/item/weapon/weldingtool/abductor(src)
+ new /obj/item/weapon/crowbar/abductor(src)
+ new /obj/item/weapon/wirecutters/abductor(src)
+ new /obj/item/device/multitool/abductor(src)
+ new /obj/item/stack/cable_coil(src, 30, COLOR_WHITE)
/obj/item/weapon/storage/belt/military/assault
name = "assault belt"
@@ -253,12 +283,12 @@
max_w_class = 4 // Set to this so the light replacer can fit.
use_item_overlays = 1
can_hold = list(
- "/obj/item/weapon/grenade/chem_grenade/cleaner",
- "/obj/item/device/lightreplacer",
- "/obj/item/device/flashlight",
- "/obj/item/weapon/reagent_containers/spray",
- "/obj/item/weapon/soap",
- "/obj/item/weapon/holosign_creator"
+ /obj/item/weapon/grenade/chem_grenade/cleaner,
+ /obj/item/device/lightreplacer,
+ /obj/item/device/flashlight,
+ /obj/item/weapon/reagent_containers/spray,
+ /obj/item/weapon/soap,
+ /obj/item/weapon/holosign_creator
)
/obj/item/weapon/storage/belt/janitor/full/New()
@@ -280,7 +310,7 @@
max_w_class = 1
max_combined_w_class = 6
storage_slots = 6
- can_hold = list("/obj/item/device/mobcapsule")
+ can_hold = list(/obj/item/device/mobcapsule)
/obj/item/weapon/storage/belt/lazarus/New()
..()
@@ -309,7 +339,7 @@
item_state = "bandolier"
storage_slots = 8
can_hold = list(
- "/obj/item/ammo_casing/shotgun"
+ /obj/item/ammo_casing/shotgun
)
/obj/item/weapon/storage/belt/bandolier/New()
@@ -351,8 +381,8 @@
storage_slots = 1
max_w_class = 3
can_hold = list(
- "/obj/item/weapon/gun/projectile/automatic/pistol",
- "/obj/item/weapon/gun/projectile/revolver/detective"
+ /obj/item/weapon/gun/projectile/automatic/pistol,
+ /obj/item/weapon/gun/projectile/revolver/detective
)
/obj/item/weapon/storage/belt/wands
@@ -363,7 +393,7 @@
storage_slots = 6
use_item_overlays = 1
can_hold = list(
- "/obj/item/weapon/gun/magic/wand"
+ /obj/item/weapon/gun/magic/wand
)
/obj/item/weapon/storage/belt/wands/full/New()
@@ -447,7 +477,7 @@
storage_slots = 1
w_class = 4
max_w_class = 4
- can_hold = list("/obj/item/weapon/melee/rapier")
+ can_hold = list(/obj/item/weapon/melee/rapier)
/obj/item/weapon/storage/belt/rapier/update_icon()
icon_state = "[initial(icon_state)]"
@@ -485,10 +515,10 @@
proc/failcheck(mob/user as mob)
if(prob(src.reliability)) return 1 //No failure
if(prob(src.reliability))
- to_chat(user, "\red The Bluespace portal resists your attempt to add another item.")//light failure
+ to_chat(user, "The Bluespace portal resists your attempt to add another item.")//light failure
else
- to_chat(user, "\red The Bluespace generator malfunctions!")
+ to_chat(user, "The Bluespace generator malfunctions!")
for(var/obj/O in src.contents) //it broke, delete what was in it
qdel(O)
crit_fail = 1
@@ -505,8 +535,8 @@
origin_tech = "bluespace=4;syndicate=2"
allow_quick_empty = 1
can_hold = list(
- "/obj/item/weapon/grenade/smokebomb",
- "/obj/item/weapon/restraints/legcuffs/bola"
+ /obj/item/weapon/grenade/smokebomb,
+ /obj/item/weapon/restraints/legcuffs/bola
)
flags = NODROP
@@ -554,48 +584,6 @@
if(H.s_active && H.s_active == src)
H.s_active.show_to(H)
-
-/* DEPRECATED DUE TO SUPERHERO CODE AND NODROP
- // As a last resort, the belt can be used as a plastic explosive with a fixed timer (15 seconds). Naturally, you'll lose all your gear...
- // Of course, it could be worse. It could spawn a singularity!
-/obj/item/weapon/storage/belt/bluespace/owlman/afterattack(atom/target as obj|turf, mob/user as mob, flag)
- if(!flag)
- return
- if(istype(target, /turf/unsimulated) || istype(target, /turf/simulated/shuttle) || istype(target, /obj/item/weapon/storage) || istype(target, /obj/structure/table) || istype(target, /obj/structure/closet))
- return
- to_chat(user, "Planting explosives...")
- user.visible_message("[user.name] is fiddling with their toolbelt.")
- if(ismob(target))
- user.create_attack_log(" [user.real_name] tried planting [name] on [target:real_name] ([target:ckey])")
- log_attack(" [user.real_name] ([user.ckey]) tried planting [name] on [target:real_name] ([target:ckey])")
- user.visible_message("\red [user.name] is trying to strap a belt to [target.name]!")
-
-
- if(do_after(user, 50, target = target) && in_range(user, target))
- user.drop_item()
- target = target
- loc = null
- var/location
- if(isturf(target)) location = target
- if(ismob(target))
- target:create_attack_log(" Had the [name] planted on them by [user.real_name] ([user.ckey])")
- user.visible_message("\red [user.name] finished planting an explosive on [target.name]!")
- target.overlays += image('icons/obj/assemblies.dmi', "plastic-explosive2")
- to_chat(user, "You sacrifice your belt for the sake of justice. Timer counting down from 15.")
- spawn(150)
- if(target)
- if(ismob(target) || isobj(target))
- location = target.loc // These things can move
- explosion(location, -1, -1, 2, 3)
- if(istype(target, /turf/simulated/wall)) target:dismantle_wall(1)
- else target.ex_act(1)
- if(isobj(target))
- if(target)
- qdel(target)
- if(src)
- qdel(src)
-*/
-
/obj/item/weapon/storage/belt/bluespace/attack(mob/M as mob, mob/user as mob, def_zone)
return
diff --git a/code/game/objects/items/weapons/storage/bible.dm b/code/game/objects/items/weapons/storage/bible.dm
index 21731113466..a992af864d4 100644
--- a/code/game/objects/items/weapons/storage/bible.dm
+++ b/code/game/objects/items/weapons/storage/bible.dm
@@ -23,9 +23,9 @@
..()
new /obj/item/weapon/reagent_containers/food/drinks/cans/beer(src)
new /obj/item/weapon/reagent_containers/food/drinks/cans/beer(src)
- new /obj/item/weapon/spacecash(src)
- new /obj/item/weapon/spacecash(src)
- new /obj/item/weapon/spacecash(src)
+ new /obj/item/stack/spacecash(src)
+ new /obj/item/stack/spacecash(src)
+ new /obj/item/stack/spacecash(src)
//BS12 EDIT
// All cult functionality moved to Null Rod
/obj/item/weapon/storage/bible/proc/bless(mob/living/carbon/M as mob)
@@ -54,15 +54,15 @@
M.LAssailant = user
if(!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
- to_chat(user, "\red You don't have the dexterity to do this!")
+ to_chat(user, "You don't have the dexterity to do this!")
return
if(!chaplain)
- to_chat(user, "\red The book sizzles in your hands.")
+ to_chat(user, "The book sizzles in your hands.")
user.take_organ_damage(0,10)
return
if((CLUMSY in user.mutations) && prob(50))
- to_chat(user, "\red The [src] slips out of your hand and hits your head.")
+ to_chat(user, "The [src] slips out of your hand and hits your head.")
user.take_organ_damage(10)
user.Paralyse(20)
return
@@ -72,19 +72,19 @@
if(M.stat !=2)
/*if((M.mind in ticker.mode.cult) && (prob(20)))
- to_chat(M, "\red The power of [src.deity_name] clears your mind of heresy!")
- to_chat(user, "\red You see how [M]'s eyes become clear, the cult no longer holds control over him!")
+ to_chat(M, "The power of [src.deity_name] clears your mind of heresy!")
+ to_chat(user, "You see how [M]'s eyes become clear, the cult no longer holds control over him!")
ticker.mode.remove_cultist(M.mind)*/
if((istype(M, /mob/living/carbon/human) && prob(60)))
bless(M)
for(var/mob/O in viewers(M, null))
O.show_message(text("[] heals [] with the power of [src.deity_name]!", user, M), 1)
- to_chat(M, "\red May the power of [src.deity_name] compel you to be healed!")
+ to_chat(M, "May the power of [src.deity_name] compel you to be healed!")
playsound(src.loc, "punch", 25, 1, -1)
else
if(ishuman(M) && !istype(M:head, /obj/item/clothing/head/helmet))
M.adjustBrainLoss(10)
- to_chat(M, "\red You feel dumber.")
+ to_chat(M, "You feel dumber.")
for(var/mob/O in viewers(M, null))
O.show_message(text("[] beats [] over the head with []!", user, M, src), 1)
playsound(src.loc, "punch", 25, 1, -1)
diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm
index 88820290a48..76ade089d9b 100644
--- a/code/game/objects/items/weapons/storage/boxes.dm
+++ b/code/game/objects/items/weapons/storage/boxes.dm
@@ -390,7 +390,7 @@
icon = 'icons/obj/food/food.dmi'
icon_state = "monkeycubebox"
storage_slots = 7
- can_hold = list("/obj/item/weapon/reagent_containers/food/snacks/monkeycube")
+ can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/monkeycube)
var/monkey_cube_type = /obj/item/weapon/reagent_containers/food/snacks/monkeycube
/obj/item/weapon/storage/box/monkeycubes/New()
@@ -423,11 +423,15 @@
desc = "A box for containing construction permits, used to officially declare built rooms as additions to the station."
icon_state = "id"
-/obj/item/weapon/storage/box/permits/New() //There's only a few, so blueprints are still useful beyond setting every room's name to PRIMARY FART STORAGE
+/obj/item/weapon/storage/box/permits/New()
..()
new /obj/item/areaeditor/permit(src)
new /obj/item/areaeditor/permit(src)
new /obj/item/areaeditor/permit(src)
+ new /obj/item/areaeditor/permit(src)
+ new /obj/item/areaeditor/permit(src)
+ new /obj/item/areaeditor/permit(src)
+ new /obj/item/areaeditor/permit(src)
/obj/item/weapon/storage/box/ids
@@ -561,7 +565,7 @@
icon = 'icons/obj/toy.dmi'
icon_state = "spbox"
storage_slots = 8
- can_hold = list("/obj/item/toy/snappop")
+ can_hold = list(/obj/item/toy/snappop)
New()
..()
for(var/i=1; i <= storage_slots; i++)
@@ -575,7 +579,9 @@
item_state = "zippo"
storage_slots = 10
w_class = 1
+ max_w_class = 1
slot_flags = SLOT_BELT
+ can_hold = list(/obj/item/weapon/match)
New()
..()
@@ -621,7 +627,7 @@
item_state = "syringe_kit"
foldable = /obj/item/stack/sheet/cardboard //BubbleWrap
storage_slots=21
- can_hold = list("/obj/item/weapon/light/tube", "/obj/item/weapon/light/bulb")
+ can_hold = list(/obj/item/weapon/light/tube, /obj/item/weapon/light/bulb)
max_combined_w_class = 21
use_to_pickup = 1 // for picking up broken bulbs, not that most people will try
diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm
index 168196f0480..a3f2a21a5fa 100644
--- a/code/game/objects/items/weapons/storage/fancy.dm
+++ b/code/game/objects/items/weapons/storage/fancy.dm
@@ -48,7 +48,7 @@
icon_type = "donut"
name = "donut box"
storage_slots = 6
- can_hold = list("/obj/item/weapon/reagent_containers/food/snacks/donut")
+ can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/donut)
/obj/item/weapon/storage/fancy/donut_box/New()
@@ -66,7 +66,7 @@
icon_type = "egg"
name = "egg box"
storage_slots = 12
- can_hold = list("/obj/item/weapon/reagent_containers/food/snacks/egg")
+ can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/egg)
/obj/item/weapon/storage/fancy/egg_box/New()
..()
@@ -119,7 +119,7 @@
storage_slots = 6
icon_type = "crayon"
can_hold = list(
- "/obj/item/toy/crayon"
+ /obj/item/toy/crayon
)
/obj/item/weapon/storage/fancy/crayons/New()
@@ -163,12 +163,12 @@
slot_flags = SLOT_BELT
storage_slots = 6
max_combined_w_class = 6
- can_hold = list("/obj/item/clothing/mask/cigarette",
- "/obj/item/weapon/lighter",
- "/obj/item/weapon/match")
- cant_hold = list("/obj/item/clothing/mask/cigarette/cigar",
- "/obj/item/clothing/mask/cigarette/pipe",
- "/obj/item/weapon/lighter/zippo")
+ can_hold = list(/obj/item/clothing/mask/cigarette,
+ /obj/item/weapon/lighter,
+ /obj/item/weapon/match)
+ cant_hold = list(/obj/item/clothing/mask/cigarette/cigar,
+ /obj/item/clothing/mask/cigarette/pipe,
+ /obj/item/weapon/lighter/zippo)
icon_type = "cigarette"
var/list/unlaced_cigarettes = list() // Cigarettes that haven't received reagents yet
var/default_reagents = list("nicotine" = 15) // List of reagents to pre-generate for each cigarette
@@ -186,7 +186,7 @@
/obj/item/weapon/storage/fancy/cigarettes/Destroy()
- qdel(reagents)
+ QDEL_NULL(reagents)
return ..()
@@ -323,7 +323,7 @@
icon_state = "cig_paper_pack"
storage_slots = 10
icon_type = "rolling paper"
- can_hold = list("/obj/item/weapon/rollingpaper")
+ can_hold = list(/obj/item/weapon/rollingpaper)
/obj/item/weapon/storage/fancy/rollingpapers/New()
..()
@@ -345,7 +345,7 @@
icon_type = "vial"
name = "vial storage box"
storage_slots = 6
- can_hold = list("/obj/item/weapon/reagent_containers/glass/beaker/vial")
+ can_hold = list(/obj/item/weapon/reagent_containers/glass/beaker/vial)
/obj/item/weapon/storage/fancy/vials/New()
@@ -361,7 +361,7 @@
icon_state = "vialbox0"
item_state = "syringe_kit"
max_w_class = 3
- can_hold = list("/obj/item/weapon/reagent_containers/glass/beaker/vial")
+ can_hold = list(/obj/item/weapon/reagent_containers/glass/beaker/vial)
max_combined_w_class = 14 //The sum of the w_classes of all the items in this storage item.
storage_slots = 6
req_access = list(access_virology)
diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm
index 67d44c53b2d..5ab8713a49a 100644
--- a/code/game/objects/items/weapons/storage/firstaid.dm
+++ b/code/game/objects/items/weapons/storage/firstaid.dm
@@ -184,8 +184,8 @@
max_w_class = 4
max_combined_w_class = 21
storage_slots = 10
- can_hold = list("/obj/item/roller","/obj/item/weapon/bonesetter","/obj/item/weapon/bonegel", "/obj/item/weapon/scalpel", "/obj/item/weapon/hemostat",
- "/obj/item/weapon/cautery", "/obj/item/weapon/retractor", "/obj/item/weapon/FixOVein", "/obj/item/weapon/surgicaldrill", "/obj/item/weapon/circular_saw")
+ can_hold = list(/obj/item/roller,/obj/item/weapon/bonesetter,/obj/item/weapon/bonegel, /obj/item/weapon/scalpel, /obj/item/weapon/hemostat,
+ /obj/item/weapon/cautery, /obj/item/weapon/retractor, /obj/item/weapon/FixOVein, /obj/item/weapon/surgicaldrill, /obj/item/weapon/circular_saw)
/obj/item/weapon/storage/firstaid/surgery/New()
..()
@@ -210,7 +210,7 @@
icon = 'icons/obj/chemical.dmi'
item_state = "contsolid"
w_class = 2
- can_hold = list("/obj/item/weapon/reagent_containers/food/pill","/obj/item/weapon/dice","/obj/item/weapon/paper")
+ can_hold = list(/obj/item/weapon/reagent_containers/food/pill, /obj/item/weapon/dice, /obj/item/weapon/paper)
allow_quick_gather = 1
use_to_pickup = 1
storage_slots = 14
diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm
index 448395df3e4..b622e469124 100644
--- a/code/game/objects/items/weapons/storage/lockbox.dm
+++ b/code/game/objects/items/weapons/storage/lockbox.dm
@@ -80,16 +80,16 @@
max_combined_w_class = 4 //The sum of the w_classes of all the items in this storage item.
storage_slots = 1
-/obj/item/weapon/storage/lockbox/loyalty
+/obj/item/weapon/storage/lockbox/mindshield
name = "Lockbox (Mindshield Implants)"
req_access = list(access_security)
-/obj/item/weapon/storage/lockbox/loyalty/New()
+/obj/item/weapon/storage/lockbox/mindshield/New()
..()
- new /obj/item/weapon/implantcase/loyalty(src)
- new /obj/item/weapon/implantcase/loyalty(src)
- new /obj/item/weapon/implantcase/loyalty(src)
- new /obj/item/weapon/implanter/loyalty(src)
+ new /obj/item/weapon/implantcase/mindshield(src)
+ new /obj/item/weapon/implantcase/mindshield(src)
+ new /obj/item/weapon/implantcase/mindshield(src)
+ new /obj/item/weapon/implanter/mindshield(src)
/obj/item/weapon/storage/lockbox/clusterbang
name = "lockbox (clusterbang)"
diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm
index e848eec1aca..e06cbb91255 100644
--- a/code/game/objects/items/weapons/storage/secure.dm
+++ b/code/game/objects/items/weapons/storage/secure.dm
@@ -37,7 +37,7 @@
emag_act(user, W)
if(istype(W, /obj/item/weapon/screwdriver))
- if(do_after(user, 20, target = src))
+ if(do_after(user, 20 * W.toolspeed, target = src))
open = !open
user.show_message("You [open ? "open" : "close"] the service panel.", 1)
return
@@ -45,18 +45,18 @@
if((istype(W, /obj/item/device/multitool)) && (open == 1) && (!l_hacking))
user.show_message("Now attempting to reset internal memory, please hold.", 1)
l_hacking = 1
- if(do_after(usr, 100, target = src))
+ if(do_after(usr, 100 * W.toolspeed, target = src))
if(prob(40))
l_setshort = 1
l_set = 0
- user.show_message("Internal memory reset. Please give it a few seconds to reinitialize.", 1)
+ user.show_message("Internal memory reset. Please give it a few seconds to reinitialize.", 1)
sleep(80)
l_setshort = 0
l_hacking = 0
else
user.show_message("Unable to reset internal memory.", 1)
l_hacking = 0
- else
+ else
l_hacking = 0
return
//At this point you have exhausted all the special things to do when locked
@@ -212,9 +212,9 @@
force = 15
/obj/item/weapon/storage/secure/briefcase/syndie/New()
- ..()
+ ..()
for(var/i = 0, i < storage_slots - 2, i++)
- handle_item_insertion(new /obj/item/weapon/spacecash/c1000, 1)
+ handle_item_insertion(new /obj/item/stack/spacecash/c1000, 1)
// -----------------------------
// Secure Safe
@@ -232,7 +232,7 @@
max_w_class = 8
anchored = 1
density = 0
- cant_hold = list("/obj/item/weapon/storage/secure/briefcase")
+ cant_hold = list(/obj/item/weapon/storage/secure/briefcase)
/obj/item/weapon/storage/secure/safe/New()
..()
diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm
index cdf123f2982..e5fb0646169 100644
--- a/code/game/objects/items/weapons/storage/storage.dm
+++ b/code/game/objects/items/weapons/storage/storage.dm
@@ -242,23 +242,15 @@
return 0 //Storage item is full
if(can_hold.len)
- var/ok = 0
- for(var/A in can_hold)
- if(istype(W, text2path(A) ))
- ok = 1
- break
- if(!ok)
+ if(!is_type_in_typecache(W, can_hold))
if(!stop_messages)
- if(istype(W, /obj/item/weapon/hand_labeler))
- return 0
to_chat(usr, "[src] cannot hold [W].")
return 0
- for(var/A in cant_hold) //Check for specific items which this container can't hold.
- if(istype(W, text2path(A) ))
- if(!stop_messages)
- to_chat(usr, "[src] cannot hold [W].")
- return 0
+ if(is_type_in_typecache(W, cant_hold)) //Check for specific items which this container can't hold.
+ if(!stop_messages)
+ to_chat(usr, "[src] cannot hold [W].")
+ return 0
if(W.w_class > max_w_class)
if(!stop_messages)
@@ -370,7 +362,7 @@
..()
if(isrobot(user))
- to_chat(user, "\blue You're a robot. No.")
+ to_chat(user, "You're a robot. No.")
return 1//Robots can't interact with storage items.
if(!can_be_inserted(W))
@@ -432,6 +424,8 @@
remove_from_storage(I, T)
/obj/item/weapon/storage/New()
+ can_hold = typecacheof(can_hold)
+ cant_hold = typecacheof(cant_hold)
if(allow_quick_empty)
verbs += /obj/item/weapon/storage/verb/quick_empty
@@ -455,14 +449,13 @@
src.closer.layer = 20
src.closer.plane = HUD_PLANE
orient2hud()
- return
/obj/item/weapon/storage/Destroy()
for(var/obj/O in contents)
O.mouse_opacity = initial(O.mouse_opacity)
- qdel(boxes)
- qdel(closer)
+ QDEL_NULL(boxes)
+ QDEL_NULL(closer)
return ..()
/obj/item/weapon/storage/emp_act(severity)
diff --git a/code/game/objects/items/weapons/storage/toolbox.dm b/code/game/objects/items/weapons/storage/toolbox.dm
index 74d4093beb5..a6ecd3d45ac 100644
--- a/code/game/objects/items/weapons/storage/toolbox.dm
+++ b/code/game/objects/items/weapons/storage/toolbox.dm
@@ -15,41 +15,35 @@
attack_verb = list("robusted")
hitsound = 'sound/weapons/smash.ogg'
- New()
- ..()
- if(src.type == /obj/item/weapon/storage/toolbox)
- to_chat(world, "BAD: [src] ([src.type]) spawned at [src.x] [src.y] [src.z]")
- qdel(src)
-
/obj/item/weapon/storage/toolbox/emergency
name = "emergency toolbox"
icon_state = "red"
item_state = "toolbox_red"
- New()
- ..()
- new /obj/item/weapon/crowbar/red(src)
- new /obj/item/weapon/weldingtool/mini(src)
- new /obj/item/weapon/extinguisher/mini(src)
- if(prob(50))
- new /obj/item/device/flashlight(src)
- else
- new /obj/item/device/flashlight/flare(src)
- new /obj/item/device/radio(src)
+/obj/item/weapon/storage/toolbox/emergency/New()
+ ..()
+ new /obj/item/weapon/crowbar/red(src)
+ new /obj/item/weapon/weldingtool/mini(src)
+ new /obj/item/weapon/extinguisher/mini(src)
+ if(prob(50))
+ new /obj/item/device/flashlight(src)
+ else
+ new /obj/item/device/flashlight/flare(src)
+ new /obj/item/device/radio(src)
/obj/item/weapon/storage/toolbox/mechanical
name = "mechanical toolbox"
icon_state = "blue"
item_state = "toolbox_blue"
- New()
- ..()
- new /obj/item/weapon/screwdriver(src)
- new /obj/item/weapon/wrench(src)
- new /obj/item/weapon/weldingtool(src)
- new /obj/item/weapon/crowbar(src)
- new /obj/item/device/analyzer(src)
- new /obj/item/weapon/wirecutters(src)
+/obj/item/weapon/storage/toolbox/mechanical/New()
+ ..()
+ new /obj/item/weapon/screwdriver(src)
+ new /obj/item/weapon/wrench(src)
+ new /obj/item/weapon/weldingtool(src)
+ new /obj/item/weapon/crowbar(src)
+ new /obj/item/device/analyzer(src)
+ new /obj/item/weapon/wirecutters(src)
/obj/item/weapon/storage/toolbox/mechanical/greytide
flags = NODROP
@@ -59,19 +53,19 @@
icon_state = "yellow"
item_state = "toolbox_yellow"
- New()
- ..()
- var/color = pick("red","yellow","green","blue","pink","orange","cyan","white")
- new /obj/item/weapon/screwdriver(src)
- new /obj/item/weapon/wirecutters(src)
- new /obj/item/device/t_scanner(src)
- new /obj/item/weapon/crowbar(src)
- new /obj/item/stack/cable_coil(src,30,color)
- new /obj/item/stack/cable_coil(src,30,color)
- if(prob(5))
- new /obj/item/clothing/gloves/color/yellow(src)
- else
- new /obj/item/stack/cable_coil(src,30,color)
+/obj/item/weapon/storage/toolbox/electrical/New()
+ ..()
+ var/pickedcolor = pick(COLOR_RED, COLOR_YELLOW, COLOR_GREEN, COLOR_BLUE, COLOR_PINK, COLOR_ORANGE, COLOR_CYAN, COLOR_WHITE)
+ new /obj/item/weapon/screwdriver(src)
+ new /obj/item/weapon/wirecutters(src)
+ new /obj/item/device/t_scanner(src)
+ new /obj/item/weapon/crowbar(src)
+ new /obj/item/stack/cable_coil(src, 30, pickedcolor)
+ new /obj/item/stack/cable_coil(src, 30, pickedcolor)
+ if(prob(5))
+ new /obj/item/clothing/gloves/color/yellow(src)
+ else
+ new /obj/item/stack/cable_coil(src, 30, pickedcolor)
/obj/item/weapon/storage/toolbox/syndicate
name = "suspicious looking toolbox"
@@ -82,12 +76,47 @@
force = 15.0
throwforce = 18.0
- New()
- ..()
- new /obj/item/weapon/screwdriver(src, "red")
- new /obj/item/weapon/wrench(src)
- new /obj/item/weapon/weldingtool/largetank(src)
- new /obj/item/weapon/crowbar/red(src)
- new /obj/item/weapon/wirecutters(src, "red")
- new /obj/item/device/multitool(src)
- new /obj/item/clothing/gloves/combat(src)
\ No newline at end of file
+/obj/item/weapon/storage/toolbox/syndicate/New()
+ ..()
+ new /obj/item/weapon/screwdriver(src, "red")
+ new /obj/item/weapon/wrench(src)
+ new /obj/item/weapon/weldingtool/largetank(src)
+ new /obj/item/weapon/crowbar/red(src)
+ new /obj/item/weapon/wirecutters(src, "red")
+ new /obj/item/device/multitool(src)
+ new /obj/item/clothing/gloves/combat(src)
+
+/obj/item/weapon/storage/toolbox/drone
+ name = "mechanical toolbox"
+ icon_state = "blue"
+ item_state = "toolbox_blue"
+
+/obj/item/weapon/storage/toolbox/drone/New()
+ ..()
+ var/pickedcolor = pick(pick(COLOR_RED, COLOR_YELLOW, COLOR_GREEN, COLOR_BLUE, COLOR_PINK, COLOR_ORANGE, COLOR_CYAN, COLOR_WHITE))
+ new /obj/item/weapon/screwdriver(src)
+ new /obj/item/weapon/wrench(src)
+ new /obj/item/weapon/weldingtool(src)
+ new /obj/item/weapon/crowbar(src)
+ new /obj/item/stack/cable_coil(src, 30, pickedcolor)
+ new /obj/item/weapon/wirecutters(src)
+ new /obj/item/device/multitool(src)
+
+/obj/item/weapon/storage/toolbox/brass
+ name = "brass box"
+ desc = "A huge brass box with several indentations in its surface."
+ icon_state = "brassbox"
+ item_state = null
+ w_class = WEIGHT_CLASS_HUGE
+ max_w_class = WEIGHT_CLASS_NORMAL
+ max_combined_w_class = 28
+ storage_slots = 28
+ attack_verb = list("robusted", "crushed", "smashed")
+
+/obj/item/weapon/storage/toolbox/brass/prefilled/New()
+ ..()
+ new /obj/item/weapon/screwdriver/brass(src)
+ new /obj/item/weapon/wirecutters/brass(src)
+ new /obj/item/weapon/wrench/brass(src)
+ new /obj/item/weapon/crowbar/brass(src)
+ new /obj/item/weapon/weldingtool/experimental/brass(src)
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm
index e3f21a93d30..03fc0a7b742 100644
--- a/code/game/objects/items/weapons/storage/uplink_kits.dm
+++ b/code/game/objects/items/weapons/storage/uplink_kits.dm
@@ -1,85 +1,84 @@
/obj/item/weapon/storage/box/syndicate/
New()
..()
- switch(pickweight(list("bloodyspai" = 1, "stealth" = 1, "bond" = 1, "screwed" = 1, "guns" = 1, "murder" = 1, "implant" = 1, "hacker" = 1, "lordsingulo" = 1, "darklord" = 1)))
+ switch(pickweight(list("bloodyspai" = 1, "thief" = 1, "bond" = 1, "sabotage" = 1, "payday" = 1, "implant" = 1, "hacker" = 1, "darklord" = 1, "gadgets" = 1)))
if("bloodyspai")
- new /obj/item/clothing/under/chameleon(src)
+ new /obj/item/weapon/twohanded/garrote(src)
+ new /obj/item/weapon/pinpointer/advpinpointer(src)
new /obj/item/clothing/mask/gas/voice(src)
+ new /obj/item/clothing/under/chameleon(src)
new /obj/item/weapon/card/id/syndicate(src)
- new /obj/item/weapon/card/id/syndicate(src)
- new /obj/item/clothing/shoes/syndigaloshes(src)
+ new /obj/item/weapon/storage/box/syndie_kit/emp(src)
new /obj/item/device/camera_bug(src)
return
- if("stealth")
+ if("thief")
new /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow(src)
- new /obj/item/weapon/pen/sleepy(src)
new /obj/item/device/chameleon(src)
+ new /obj/item/clothing/gloves/color/black/thief(src)
+ new /obj/item/weapon/card/id/syndicate(src)
return
if("bond")
new /obj/item/weapon/gun/projectile/automatic/pistol(src)
new /obj/item/weapon/suppressor(src)
- new /obj/item/ammo_box/magazine/m10mm(src)
- new /obj/item/ammo_box/magazine/m10mm(src)
- new /obj/item/clothing/under/chameleon(src)
- new /obj/item/weapon/card/id/syndicate(src)
-
- if("screwed")
- new /obj/item/device/radio/beacon/syndicate/bomb(src)
- new /obj/item/weapon/grenade/syndieminibomb(src)
- new /obj/item/device/powersink(src)
- new /obj/item/clothing/suit/space/syndicate/black/red(src)
- new /obj/item/clothing/head/helmet/space/syndicate/black/red(src)
+ new /obj/item/ammo_box/magazine/m10mm/hp(src)
+ new /obj/item/device/encryptionkey/syndicate(src)
+ new /obj/item/weapon/storage/fancy/cigarettes/cigpack_syndicate(src)
+ new /obj/item/weapon/implanter/krav_maga(src)
+ new /obj/item/weapon/reagent_containers/food/drinks/drinkingglass/alliescocktail(src)
return
- if("guns")
+ if("sabotage")
+ new /obj/item/device/powersink(src)
+ new /obj/item/weapon/grenade/syndieminibomb(src)
+ new /obj/item/weapon/card/emag(src)
+ new /obj/item/weapon/grenade/clusterbuster/n2o(src)
+ new /obj/item/weapon/storage/box/syndie_kit/space(src)
+ new /obj/item/clothing/gloves/color/yellow(src)
+ new /obj/item/weapon/rcd/preloaded(src)
+ return
+
+ if("payday")
new /obj/item/weapon/gun/projectile/revolver(src)
new /obj/item/ammo_box/a357(src)
new /obj/item/weapon/card/emag(src)
- new /obj/item/weapon/grenade/plastic/c4(src)
+ new /obj/item/weapon/grenade/plastic/x4(src)
+ new /obj/item/weapon/card/id/syndicate(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
new /obj/item/clothing/mask/gas/clown_hat(src)
- new /obj/item/clothing/under/suit_jacket/really_black(src)
- return
-
- if("murder")
- new /obj/item/weapon/melee/energy/sword/saber(src)
- new /obj/item/clothing/glasses/thermal/syndi(src)
- new /obj/item/weapon/card/emag(src)
- new /obj/item/clothing/shoes/syndigaloshes(src)
return
if("implant")
- new /obj/item/weapon/implanter/freedom(src)
new /obj/item/weapon/implanter/uplink(src)
- new /obj/item/weapon/implanter/emp(src)
new /obj/item/weapon/implanter/adrenalin(src)
- new /obj/item/weapon/implanter/explosive(src)
new /obj/item/weapon/implanter/storage(src)
+ new /obj/item/weapon/implanter/freedom(src)
return
if("hacker")
new /obj/item/weapon/aiModule/syndicate(src)
- new /obj/item/weapon/card/emag(src)
new /obj/item/device/encryptionkey/binary(src)
new /obj/item/weapon/aiModule/toyAI(src)
return
- if("lordsingulo")
- new /obj/item/device/radio/beacon/syndicate(src)
- new /obj/item/clothing/suit/space/syndicate/black/red(src)
- new /obj/item/clothing/head/helmet/space/syndicate/black/red(src)
- new /obj/item/weapon/card/emag(src)
- return
-
if("darklord")
- new /obj/item/weapon/melee/energy/sword/saber(src)
- new /obj/item/weapon/melee/energy/sword/saber(src)
+ new /obj/item/weapon/melee/energy/sword/saber/red(src)
+ new /obj/item/weapon/melee/energy/sword/saber/red(src)
new /obj/item/weapon/dnainjector/telemut/darkbundle(src)
new /obj/item/clothing/suit/hooded/chaplain_hoodie(src)
new /obj/item/weapon/card/id/syndicate(src)
return
+
+ if("gadgets")
+ new /obj/item/clothing/gloves/color/yellow/power(src)
+ new /obj/item/weapon/pen/sleepy(src)
+ new /obj/item/clothing/glasses/thermal/syndi(src)
+ new /obj/item/device/flashlight/emp(src)
+ new /obj/item/clothing/shoes/syndigaloshes(src)
+ new /obj/item/weapon/stamp/chameleon(src)
+ new /obj/item/device/multitool/ai_detect(src)
+ return
/obj/item/weapon/storage/box/syndie_kit
name = "Box"
@@ -88,7 +87,7 @@
/obj/item/weapon/storage/box/syndie_kit/space
name = "Boxed Space Suit and Helmet"
- can_hold = list("/obj/item/clothing/suit/space/syndicate/black/red", "/obj/item/clothing/head/helmet/space/syndicate/black/red")
+ can_hold = list(/obj/item/clothing/suit/space/syndicate/black/red, /obj/item/clothing/head/helmet/space/syndicate/black/red)
max_w_class = 3
/obj/item/weapon/storage/box/syndie_kit/space/New()
@@ -99,34 +98,34 @@
/obj/item/weapon/storage/box/syndie_kit/hardsuit
name = "Boxed Blood Red Suit and Helmet"
- can_hold = list("/obj/item/clothing/suit/space/rig/syndi", "/obj/item/clothing/head/helmet/space/rig/syndi")
+ can_hold = list(/obj/item/clothing/suit/space/hardsuit/syndi, /obj/item/clothing/head/helmet/space/hardsuit/syndi)
max_w_class = 3
/obj/item/weapon/storage/box/syndie_kit/hardsuit/New()
..()
- new /obj/item/clothing/suit/space/rig/syndi(src)
- new /obj/item/clothing/head/helmet/space/rig/syndi(src)
+ new /obj/item/clothing/suit/space/hardsuit/syndi(src)
+ new /obj/item/clothing/head/helmet/space/hardsuit/syndi(src)
return
/obj/item/weapon/storage/box/syndie_kit/elite_hardsuit
name = "Boxed Elite Syndicate Hardsuit and Helmet"
- can_hold = list("/obj/item/clothing/suit/space/rig/syndi/elite", "/obj/item/clothing/head/helmet/space/rig/syndi/elite")
+ can_hold = list(/obj/item/clothing/suit/space/hardsuit/syndi/elite, /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite)
max_w_class = 3
/obj/item/weapon/storage/box/syndie_kit/elite_hardsuit/New()
..()
- new /obj/item/clothing/suit/space/rig/syndi/elite(src)
- new /obj/item/clothing/head/helmet/space/rig/syndi/elite(src)
+ new /obj/item/clothing/suit/space/hardsuit/syndi/elite(src)
+ new /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite(src)
/obj/item/weapon/storage/box/syndie_kit/shielded_hardsuit
name = "Boxed Shielded Syndicate Hardsuit and Helmet"
- can_hold = list("/obj/item/clothing/suit/space/rig/shielded/syndi", "/obj/item/clothing/head/helmet/space/rig/shielded/syndi")
+ can_hold = list(/obj/item/clothing/suit/space/hardsuit/shielded/syndi, /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi)
max_w_class = 4
/obj/item/weapon/storage/box/syndie_kit/shielded_hardsuit/New()
..()
- new /obj/item/clothing/suit/space/rig/shielded/syndi(src)
- new /obj/item/clothing/head/helmet/space/rig/shielded/syndi(src)
+ new /obj/item/clothing/suit/space/hardsuit/shielded/syndi(src)
+ new /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi(src)
/obj/item/weapon/storage/box/syndie_kit/conversion
name = "box (CK)"
diff --git a/code/game/objects/items/weapons/storage/wallets.dm b/code/game/objects/items/weapons/storage/wallets.dm
index 5bc1ae65e84..0d9712ed43f 100644
--- a/code/game/objects/items/weapons/storage/wallets.dm
+++ b/code/game/objects/items/weapons/storage/wallets.dm
@@ -7,25 +7,25 @@
w_class = 2
burn_state = FLAMMABLE
can_hold = list(
- "/obj/item/weapon/spacecash",
- "/obj/item/weapon/card",
- "/obj/item/clothing/mask/cigarette",
- "/obj/item/device/flashlight/pen",
- "/obj/item/seeds",
- "/obj/item/stack/medical",
- "/obj/item/toy/crayon",
- "/obj/item/weapon/coin",
- "/obj/item/weapon/dice",
- "/obj/item/weapon/disk",
- "/obj/item/weapon/implanter",
- "/obj/item/weapon/lighter",
- "/obj/item/weapon/match",
- "/obj/item/weapon/paper",
- "/obj/item/weapon/pen",
- "/obj/item/weapon/photo",
- "/obj/item/weapon/reagent_containers/dropper",
- "/obj/item/weapon/screwdriver",
- "/obj/item/weapon/stamp")
+ /obj/item/stack/spacecash,
+ /obj/item/weapon/card,
+ /obj/item/clothing/mask/cigarette,
+ /obj/item/device/flashlight/pen,
+ /obj/item/seeds,
+ /obj/item/stack/medical,
+ /obj/item/toy/crayon,
+ /obj/item/weapon/coin,
+ /obj/item/weapon/dice,
+ /obj/item/weapon/disk,
+ /obj/item/weapon/implanter,
+ /obj/item/weapon/lighter,
+ /obj/item/weapon/match,
+ /obj/item/weapon/paper,
+ /obj/item/weapon/pen,
+ /obj/item/weapon/photo,
+ /obj/item/weapon/reagent_containers/dropper,
+ /obj/item/weapon/screwdriver,
+ /obj/item/weapon/stamp)
slot_flags = SLOT_ID
var/obj/item/weapon/card/id/front_id = null
@@ -76,18 +76,18 @@
/obj/item/weapon/storage/wallet/random/New()
..()
- var/item1_type = pick(/obj/item/weapon/spacecash,
- /obj/item/weapon/spacecash/c10,
- /obj/item/weapon/spacecash/c100,
- /obj/item/weapon/spacecash/c500,
- /obj/item/weapon/spacecash/c1000)
+ var/item1_type = pick(/obj/item/stack/spacecash,
+ /obj/item/stack/spacecash/c10,
+ /obj/item/stack/spacecash/c100,
+ /obj/item/stack/spacecash/c500,
+ /obj/item/stack/spacecash/c1000)
var/item2_type
if(prob(50))
- item2_type = pick(/obj/item/weapon/spacecash,
- /obj/item/weapon/spacecash/c10,
- /obj/item/weapon/spacecash/c100,
- /obj/item/weapon/spacecash/c500,
- /obj/item/weapon/spacecash/c1000)
+ item2_type = pick(/obj/item/stack/spacecash,
+ /obj/item/stack/spacecash/c10,
+ /obj/item/stack/spacecash/c100,
+ /obj/item/stack/spacecash/c500,
+ /obj/item/stack/spacecash/c1000)
var/item3_type = pick( /obj/item/weapon/coin/silver, /obj/item/weapon/coin/silver, /obj/item/weapon/coin/gold, /obj/item/weapon/coin/iron, /obj/item/weapon/coin/iron, /obj/item/weapon/coin/iron )
spawn(2)
diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm
index f2bd9cafedf..1de82690573 100644
--- a/code/game/objects/items/weapons/stunbaton.dm
+++ b/code/game/objects/items/weapons/stunbaton.dm
@@ -2,6 +2,7 @@
name = "stunbaton"
desc = "A stun baton for incapacitating people with."
icon_state = "stunbaton"
+ var/base_icon = "stunbaton"
item_state = "baton"
slot_flags = SLOT_BELT
force = 10
@@ -12,7 +13,7 @@
var/stunforce = 7
var/status = 0
var/obj/item/weapon/stock_parts/cell/high/bcell = null
- var/hitcost = 1500
+ var/hitcost = 1000
/obj/item/weapon/melee/baton/suicide_act(mob/user)
user.visible_message("[user] is putting the live [name] in \his mouth! It looks like \he's trying to commit suicide.")
@@ -24,9 +25,7 @@
return
/obj/item/weapon/melee/baton/Destroy()
- if(bcell)
- qdel(bcell)
- bcell = null
+ QDEL_NULL(bcell)
return ..()
/obj/item/weapon/melee/baton/loaded/New() //this one starts with a cell pre-installed.
@@ -48,11 +47,11 @@
/obj/item/weapon/melee/baton/update_icon()
if(status)
- icon_state = "[initial(name)]_active"
+ icon_state = "[base_icon]_active"
else if(!bcell)
- icon_state = "[initial(name)]_nocell"
+ icon_state = "[base_icon]_nocell"
else
- icon_state = "[initial(name)]"
+ icon_state = "[base_icon]"
/obj/item/weapon/melee/baton/examine(mob/user)
..(user)
@@ -184,28 +183,28 @@
return 1
..()
-
-//secborg stun baton module
-/obj/item/weapon/melee/baton/loaded/robot
- hitcost = 1000
-
//Makeshift stun baton. Replacement for stun gloves.
/obj/item/weapon/melee/baton/cattleprod
name = "stunprod"
desc = "An improvised stun baton."
icon_state = "stunprod_nocell"
+ base_icon = "stunprod"
item_state = "prod"
w_class = 3
force = 3
throwforce = 5
stunforce = 5
- hitcost = 3750
+ hitcost = 2000
slot_flags = SLOT_BACK
- var/obj/item/device/assembly/igniter/sparkler = 0
+ var/obj/item/device/assembly/igniter/sparkler = null
/obj/item/weapon/melee/baton/cattleprod/New()
..()
- sparkler = new (src)
+ sparkler = new(src)
+
+/obj/item/weapon/melee/baton/cattleprod/Destroy()
+ QDEL_NULL(sparkler)
+ return ..()
/obj/item/weapon/melee/baton/cattleprod/baton_stun()
if(sparkler.activate())
diff --git a/code/game/objects/items/weapons/tanks/jetpack.dm b/code/game/objects/items/weapons/tanks/jetpack.dm
index c9c9497cb71..1bd8d8b761c 100644
--- a/code/game/objects/items/weapons/tanks/jetpack.dm
+++ b/code/game/objects/items/weapons/tanks/jetpack.dm
@@ -19,8 +19,7 @@
ion_trail.set_up(src)
/obj/item/weapon/tank/jetpack/Destroy()
- qdel(ion_trail)
- ion_trail = null
+ QDEL_NULL(ion_trail)
return ..()
/obj/item/weapon/tank/jetpack/ui_action_click(mob/user, actiontype)
@@ -82,7 +81,7 @@
var/datum/gas_mixture/removed = air_contents.remove(num)
if(removed.total_moles() < 0.005)
- turn_off()
+ turn_off()
return 0
var/turf/T = get_turf(user)
diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm
index a61a3cea5ce..bd62357ba76 100644
--- a/code/game/objects/items/weapons/tanks/tanks.dm
+++ b/code/game/objects/items/weapons/tanks/tanks.dm
@@ -33,9 +33,7 @@
return
/obj/item/weapon/tank/Destroy()
- if(air_contents)
- qdel(air_contents)
- air_contents = null
+ QDEL_NULL(air_contents)
processing_objects.Remove(src)
@@ -45,7 +43,7 @@
/obj/item/weapon/tank/ui_action_click(mob/user)
toggle_internals(user)
-/obj/item/weapon/tank/proc/toggle_internals(mob/user)
+/obj/item/weapon/tank/proc/toggle_internals(mob/user, silent = FALSE)
var/mob/living/carbon/C = user
if(!istype(C))
return 0
@@ -65,13 +63,16 @@
if(can_open_valve)
if(C.internal)
- to_chat(C, "You switch your internals to [src].")
+ if(!silent)
+ to_chat(C, "You switch your internals to [src].")
else
- to_chat(C, "You open \the [src] valve.")
+ if(!silent)
+ to_chat(C, "You open \the [src] valve.")
C.internal = src
C.update_internals_hud_icon(1)
else
- to_chat(C, "You are not wearing a suitable mask or helmet.")
+ if(!silent)
+ to_chat(C, "You are not wearing a suitable mask or helmet.")
return 0
C.update_action_buttons_icon()
@@ -244,7 +245,7 @@
if(!istype(loc,/obj/item/device/transfer_valve))
message_admins("Explosive tank rupture! last key to touch the tank was [fingerprintslast] (JMP)")
log_game("Explosive tank rupture! last key to touch the tank was [fingerprintslast] at [x], [y], [z]")
-// to_chat(world, "\blue[x],[y] tank is exploding: [pressure] kPa")
+// to_chat(world, "[x],[y] tank is exploding: [pressure] kPa")
//Give the gas a chance to build up more pressure through reacting
air_contents.react()
air_contents.react()
@@ -253,7 +254,7 @@
var/range = (pressure-TANK_FRAGMENT_PRESSURE)/TANK_FRAGMENT_SCALE
var/turf/epicenter = get_turf(loc)
-// to_chat(world, "\blue Exploding Pressure: [pressure] kPa, intensity: [range]")
+// to_chat(world, "Exploding Pressure: [pressure] kPa, intensity: [range]")
explosion(epicenter, round(range*0.25), round(range*0.5), round(range), round(range*1.5))
if(istype(loc,/obj/item/device/transfer_valve))
@@ -262,7 +263,7 @@
qdel(src)
else if(pressure > TANK_RUPTURE_PRESSURE)
-// to_chat(world, "\blue[x],[y] tank is rupturing: [pressure] kPa, integrity [integrity]")
+// to_chat(world, "[x],[y] tank is rupturing: [pressure] kPa, integrity [integrity]")
if(integrity <= 0)
var/turf/simulated/T = get_turf(src)
if(!T)
@@ -274,7 +275,7 @@
integrity--
else if(pressure > TANK_LEAK_PRESSURE)
-// to_chat(world, "\blue[x],[y] tank is leaking: [pressure] kPa, integrity [integrity]")
+// to_chat(world, "[x],[y] tank is leaking: [pressure] kPa, integrity [integrity]")
if(integrity <= 0)
var/turf/simulated/T = get_turf(src)
if(!T)
diff --git a/code/game/objects/items/weapons/tanks/watertank.dm b/code/game/objects/items/weapons/tanks/watertank.dm
index 9068460ae80..00dc66e1b94 100644
--- a/code/game/objects/items/weapons/tanks/watertank.dm
+++ b/code/game/objects/items/weapons/tanks/watertank.dm
@@ -301,7 +301,7 @@
if(!Adj|| !istype(target, /turf))
return
if(metal_synthesis_cooldown < 5)
- var/obj/effect/effect/foam/F = new /obj/effect/effect/foam(get_turf(target), 1)
+ var/obj/structure/foam/F = new /obj/structure/foam(get_turf(target), 1)
F.amount = 0
metal_synthesis_cooldown++
spawn(100)
diff --git a/code/game/objects/items/weapons/teleprod.dm b/code/game/objects/items/weapons/teleprod.dm
index 0bc1b23f6d6..dfaa52ba396 100644
--- a/code/game/objects/items/weapons/teleprod.dm
+++ b/code/game/objects/items/weapons/teleprod.dm
@@ -2,6 +2,7 @@
name = "teleprod"
desc = "A prod with a bluespace crystal on the end. The crystal doesn't look too fun to touch."
icon_state = "teleprod_nocell"
+ base_icon = "teleprod"
item_state = "teleprod"
origin_tech = "combat=2;bluespace=4;materials=3"
@@ -15,4 +16,4 @@
deductcharge(hitcost)
do_teleport(user, get_turf(user), 50)//honk honk
else if(iscarbon(M) && !M.anchored)
- do_teleport(M, get_turf(M), 15)
\ No newline at end of file
+ do_teleport(M, get_turf(M), 15)
diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm
index 7e0c7296fc9..76f2dcb84a8 100644
--- a/code/game/objects/items/weapons/tools.dm
+++ b/code/game/objects/items/weapons/tools.dm
@@ -22,60 +22,137 @@
slot_flags = SLOT_BELT
force = 5
throwforce = 7
- w_class = 2
+ usesound = 'sound/items/Ratchet.ogg'
+ w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=150)
origin_tech = "materials=1;engineering=1"
attack_verb = list("bashed", "battered", "bludgeoned", "whacked")
+ toolspeed = 1
+
+/obj/item/weapon/wrench/suicide_act(mob/user)
+ user.visible_message("[user] is beating themselves to death with [src]! It looks like they're trying to commit suicide!")
+ playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1)
+ return (BRUTELOSS)
+
+/obj/item/weapon/wrench/cyborg
+ name = "automatic wrench"
+ desc = "An advanced robotic wrench. Can be found in construction cyborgs."
+ toolspeed = 0.5
+
+/obj/item/weapon/wrench/brass
+ name = "brass wrench"
+ desc = "A brass wrench. It's faintly warm to the touch."
+ icon_state = "wrench_brass"
+ toolspeed = 0.5
+
+/obj/item/weapon/wrench/abductor
+ name = "alien wrench"
+ desc = "A polarized wrench. It causes anything placed between the jaws to turn."
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "wrench"
+ usesound = 'sound/effects/EMPulse.ogg'
+ toolspeed = 0.1
+ origin_tech = "materials=5;engineering=5;abductor=3"
+
+/obj/item/weapon/wrench/power
+ name = "hand drill"
+ desc = "A simple powered drill with a bolt bit."
+ icon_state = "drill_bolt"
+ item_state = "drill"
+ usesound = 'sound/items/drill_use.ogg'
+ materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_GOLD=25)
+ origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get
+ force = 8 //might or might not be too high, subject to change
+ throwforce = 8
+ attack_verb = list("drilled", "screwed", "jabbed")
+ toolspeed = 0.25
+
+/obj/item/weapon/wrench/power/attack_self(mob/user)
+ playsound(get_turf(user),'sound/items/change_drill.ogg', 50, 1)
+ var/obj/item/weapon/wirecutters/power/s_drill = new /obj/item/weapon/screwdriver/power
+ to_chat(user, "You attach the screwdriver bit to [src].")
+ qdel(src)
+ user.put_in_active_hand(s_drill)
+
+/obj/item/weapon/wrench/power/suicide_act(mob/user)
+ user.visible_message("[user] is pressing [src] against their head! It looks like they're trying to commit suicide!")
+ return (BRUTELOSS)
+
+/obj/item/weapon/wrench/medical
+ name = "medical wrench"
+ desc = "A medical wrench with common (medical?) uses. Can be found in your hand."
+ icon_state = "wrench_medical"
+ force = 2 //MEDICAL
+ throwforce = 4
+ origin_tech = "materials=1;engineering=1;biotech=3"
+ attack_verb = list("wrenched", "medicaled", "tapped", "jabbed", "whacked")
+
+/obj/item/weapon/wrench/medical/suicide_act(mob/user)
+ user.visible_message("[user] is praying to the medical wrench to take their soul. It looks like they're trying to commit suicide!")
+ // TODO Make them glow with the power of the M E D I C A L W R E N C H
+ // during their ascension
+
+ // Stun stops them from wandering off
+ user.Stun(5)
+ playsound(loc, 'sound/effects/pray.ogg', 50, 1, -1)
+
+ // Let the sound effect finish playing
+ sleep(20)
+
+ if(!user)
+ return
+
+ for(var/obj/item/W in user)
+ user.unEquip(W)
+
+ var/obj/item/weapon/wrench/medical/W = new /obj/item/weapon/wrench/medical(loc)
+ W.add_fingerprint(user)
+ W.desc += " For some reason, it reminds you of [user.name]."
+
+ if(!user)
+ return
+
+ user.dust()
+ return OXYLOSS
//Screwdriver
/obj/item/weapon/screwdriver
name = "screwdriver"
desc = "You can be totally screwy with this."
icon = 'icons/obj/tools.dmi'
- icon_state = "screwdriver"
+ icon_state = null
flags = CONDUCT
slot_flags = SLOT_BELT
force = 5
- w_class = 1
+ w_class = WEIGHT_CLASS_TINY
throwforce = 5
throw_speed = 3
throw_range = 5
materials = list(MAT_METAL=75)
attack_verb = list("stabbed")
hitsound = 'sound/weapons/bladeslice.ogg'
+ usesound = 'sound/items/Screwdriver.ogg'
+ toolspeed = 1
+
+/obj/item/weapon/screwdriver/nuke
+ name = "screwdriver"
+ desc = "A screwdriver with an ultra thin tip."
+ icon_state = "screwdriver_nuke"
+ toolspeed = 0.5
/obj/item/weapon/screwdriver/suicide_act(mob/user)
- to_chat(viewers(user), pick("[user] is stabbing the [name] into \his temple! It looks like \he's trying to commit suicide.", \
- "[user] is stabbing the [name] into \his heart! It looks like \he's trying to commit suicide."))
+ user.visible_message("[user] is stabbing [src] into their [pick("temple", "heart")]! It looks like they're trying to commit suicide!")
return(BRUTELOSS)
-/obj/item/weapon/screwdriver/New()
- switch(pick("red","blue","purple","brown","green","cyan","yellow"))
- if("red")
- icon_state = "screwdriver2"
- item_state = "screwdriver"
- if("blue")
- icon_state = "screwdriver"
- item_state = "screwdriver_blue"
- if("purple")
- icon_state = "screwdriver3"
- item_state = "screwdriver_purple"
- if("brown")
- icon_state = "screwdriver4"
- item_state = "screwdriver_brown"
- if("green")
- icon_state = "screwdriver5"
- item_state = "screwdriver_green"
- if("cyan")
- icon_state = "screwdriver6"
- item_state = "screwdriver_cyan"
- if("yellow")
- icon_state = "screwdriver7"
- item_state = "screwdriver_yellow"
+/obj/item/weapon/screwdriver/New(loc, var/param_color = null)
+ ..()
+ if(!icon_state)
+ if(!param_color)
+ param_color = pick("red","blue","pink","brown","green","cyan","yellow")
+ icon_state = "screwdriver_[param_color]"
- if(prob(75))
+ if (prob(75))
src.pixel_y = rand(0, 16)
- return
/obj/item/weapon/screwdriver/attack(mob/living/carbon/M, mob/living/carbon/user)
if(!istype(M) || user.a_intent == I_HELP)
@@ -86,48 +163,149 @@
M = user
return eyestab(M,user)
+/obj/item/weapon/screwdriver/brass
+ name = "brass screwdriver"
+ desc = "A screwdriver made of brass. The handle feels freezing cold."
+ icon_state = "screwdriver_brass"
+ toolspeed = 0.5
+
+/obj/item/weapon/screwdriver/abductor
+ name = "alien screwdriver"
+ desc = "An ultrasonic screwdriver."
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "screwdriver"
+ usesound = 'sound/items/PSHOOM.ogg'
+ toolspeed = 0.1
+
+/obj/item/weapon/screwdriver/power
+ name = "hand drill"
+ desc = "A simple hand drill with a screwdriver bit attached."
+ icon_state = "drill_screw"
+ item_state = "drill"
+ materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_GOLD=25)
+ origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get
+ force = 8 //might or might not be too high, subject to change
+ throwforce = 8
+ throw_speed = 2
+ throw_range = 3//it's heavier than a screw driver/wrench, so it does more damage, but can't be thrown as far
+ attack_verb = list("drilled", "screwed", "jabbed","whacked")
+ hitsound = 'sound/items/drill_hit.ogg'
+ usesound = 'sound/items/drill_use.ogg'
+ toolspeed = 0.25
+
+/obj/item/weapon/screwdriver/power/suicide_act(mob/user)
+ user.visible_message("[user] is putting [src] to their temple. It looks like they're trying to commit suicide!")
+ return(BRUTELOSS)
+
+/obj/item/weapon/screwdriver/power/attack_self(mob/user)
+ playsound(get_turf(user), 'sound/items/change_drill.ogg', 50, 1)
+ var/obj/item/weapon/wrench/power/b_drill = new /obj/item/weapon/wrench/power
+ to_chat(user, "You attach the bolt driver bit to [src].")
+ qdel(src)
+ user.put_in_active_hand(b_drill)
+
+/obj/item/weapon/screwdriver/cyborg
+ name = "powered screwdriver"
+ desc = "An electrical screwdriver, designed to be both precise and quick."
+ usesound = 'sound/items/drill_use.ogg'
+ toolspeed = 0.5
+
//Wirecutters
/obj/item/weapon/wirecutters
name = "wirecutters"
desc = "This cuts wires."
icon = 'icons/obj/tools.dmi'
- icon_state = "cutters"
+ icon_state = null
flags = CONDUCT
slot_flags = SLOT_BELT
force = 6
throw_speed = 3
throw_range = 7
- w_class = 2
+ w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=80)
origin_tech = "materials=1;engineering=1"
attack_verb = list("pinched", "nipped")
hitsound = 'sound/items/Wirecutter.ogg'
+ usesound = 'sound/items/Wirecutter.ogg'
sharp = 1
edge = 1
+ toolspeed = 1
/obj/item/weapon/wirecutters/New(loc, param_color = null)
..()
- if((!param_color && prob(50)) || param_color == "yellow")
- icon_state = "cutters-y"
- item_state = "cutters_yellow"
+ if(!icon_state)
+ if(!param_color)
+ param_color = pick("yellow", "red")
+ icon_state = "cutters_[param_color]"
-/obj/item/weapon/wirecutters/attack(mob/living/carbon/human/H, mob/user)
- if(istype(H) && H.handcuffed)
- if(istype(H.handcuffed, /obj/item/weapon/restraints/handcuffs/cable))
- usr.visible_message("\The [usr] cuts \the [H]'s restraints with \the [src]!",\
- "You cut \the [H]'s restraints with \the [src]!",\
- "You hear cable being cut.")
- H.handcuffed = null
- if(H.buckled && H.buckled.buckle_requires_restraints)
- H.buckled.unbuckle_mob()
- H.update_handcuffed()
- return
+/obj/item/weapon/wirecutters/attack(mob/living/carbon/C, mob/user)
+ if(istype(C) && C.handcuffed && istype(C.handcuffed, /obj/item/weapon/restraints/handcuffs/cable))
+ user.visible_message("[user] cuts [C]'s restraints with [src]!")
+ qdel(C.handcuffed)
+ C.handcuffed = null
+ if(C.buckled && C.buckled.buckle_requires_restraints)
+ C.buckled.unbuckle_mob(C)
+ C.update_handcuffed()
+ return
else
..()
+/obj/item/weapon/wirecutters/suicide_act(mob/user)
+ user.visible_message("[user] is cutting at their arteries with [src]! It looks like they're trying to commit suicide!")
+ playsound(loc, usesound, 50, 1, -1)
+ return (BRUTELOSS)
+
+/obj/item/weapon/wirecutters/brass
+ name = "brass wirecutters"
+ desc = "A pair of wirecutters made of brass. The handle feels freezing cold to the touch."
+ icon_state = "cutters_brass"
+ toolspeed = 0.5
+
+/obj/item/weapon/wirecutters/abductor
+ name = "alien wirecutters"
+ desc = "Extremely sharp wirecutters, made out of a silvery-green metal."
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "cutters"
+ toolspeed = 0.1
+ origin_tech = "materials=5;engineering=4;abductor=3"
+
+/obj/item/weapon/wirecutters/cyborg
+ name = "wirecutters"
+ desc = "This cuts wires."
+ toolspeed = 0.5
+
+/obj/item/weapon/wirecutters/power
+ name = "jaws of life"
+ desc = "A set of jaws of life, the magic of science has managed to fit it down into a device small enough to fit in a tool belt. It's fitted with a cutting head."
+ icon_state = "jaws_cutter"
+ item_state = "jawsoflife"
+ origin_tech = "materials=2;engineering=2"
+ materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_GOLD=25)
+ usesound = 'sound/items/jaws_cut.ogg'
+ toolspeed = 0.25
+
+/obj/item/weapon/wirecutters/power/suicide_act(mob/user)
+ user.visible_message("[user] is wrapping \the [src] around their neck. It looks like they're trying to rip their head off!")
+ playsound(loc, 'sound/items/jaws_cut.ogg', 50, 1, -1)
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ var/obj/item/organ/external/head/head = H.organs_by_name["head"]
+ if(head)
+ head.droplimb(0, DROPLIMB_BLUNT, FALSE, TRUE)
+ playsound(loc,pick('sound/misc/desceration-01.ogg','sound/misc/desceration-02.ogg','sound/misc/desceration-01.ogg') ,50, 1, -1)
+ return (BRUTELOSS)
+
+/obj/item/weapon/wirecutters/power/attack_self(mob/user)
+ playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1)
+ var/obj/item/weapon/crowbar/power/pryjaws = new /obj/item/weapon/crowbar/power
+ to_chat(user, "You attach the pry jaws to [src].")
+ qdel(src)
+ user.put_in_active_hand(pryjaws)
+
//Welding Tool
/obj/item/weapon/weldingtool
name = "welding tool"
+ desc = "A standard edition welder provided by Nanotrasen."
icon = 'icons/obj/tools.dmi'
icon_state = "welder"
item_state = "welder"
@@ -137,15 +315,21 @@
throwforce = 5
throw_speed = 3
throw_range = 5
- w_class = 2
+ hitsound = "swing_hit"
+ usesound = 'sound/items/Welder.ogg'
+ var/acti_sound = 'sound/items/WelderActivate.ogg'
+ var/deac_sound = 'sound/items/WelderDeactivate.ogg'
+ w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=70, MAT_GLASS=30)
- origin_tech = "engineering=1"
+ origin_tech = "engineering=1;plasmatech=1"
+ toolspeed = 1
var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2)
var/status = 1 //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower)
var/max_fuel = 20 //The max amount of fuel the welder can hold
var/change_icons = 1
var/can_off_process = 0
var/light_intensity = 2 //how powerful the emitted light is when used.
+ var/nextrefueltick = 0
/obj/item/weapon/weldingtool/New()
..()
@@ -158,7 +342,7 @@
to_chat(user, "It contains [get_fuel()] unit\s of fuel out of [max_fuel].")
/obj/item/weapon/weldingtool/suicide_act(mob/user)
- user.visible_message("[user] welds \his every orifice closed! It looks like \he's trying to commit suicide..")
+ user.visible_message("[user] welds their every orifice closed! It looks like they're trying to commit suicide!")
return (FIRELOSS)
/obj/item/weapon/weldingtool/proc/update_torch()
@@ -179,13 +363,6 @@
icon_state = "[initial(icon_state)][ratio]"
update_torch()
-/obj/item/weapon/weldingtool/attackby(obj/item/I, mob/user, params)
- if(isscrewdriver(I))
- flamethrower_screwdriver(I, user)
- if(istype(I, /obj/item/stack/rods))
- flamethrower_rods(I, user)
- ..()
-
/obj/item/weapon/weldingtool/process()
switch(welding)
if(0)
@@ -212,6 +389,14 @@
if(isturf(location))
location.hotspot_expose(700, 5)
+/obj/item/weapon/weldingtool/attackby(obj/item/I, mob/user, params)
+ if(isscrewdriver(I))
+ flamethrower_screwdriver(I, user)
+ else if(istype(I, /obj/item/stack/rods))
+ flamethrower_rods(I, user)
+ else
+ ..()
+
/obj/item/weapon/weldingtool/attack(mob/M, mob/user)
if(ishuman(M))
var/mob/living/carbon/human/H = M
@@ -233,7 +418,7 @@
if(!do_mob(user, H, 10))
return 1
if(remove_fuel(1,null))
- playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(src.loc, usesound, 50, 1)
S.heal_damage(15,0,0,1)
user.visible_message("\The [user] patches some dents on \the [M]'s [S.name] with \the [src].")
else if(S.open != 2)
@@ -250,10 +435,13 @@
/obj/item/weapon/weldingtool/afterattack(atom/O, mob/user, proximity)
if(!proximity)
return
+
if(welding)
remove_fuel(1)
var/turf/location = get_turf(user)
location.hotspot_expose(700, 50, 1)
+ if(get_fuel() <= 0)
+ set_light(0)
if(isliving(O))
var/mob/living/L = O
@@ -262,7 +450,10 @@
log_game("[key_name(user)] set [key_name(L)] on fire")
/obj/item/weapon/weldingtool/attack_self(mob/user)
- toggle(user)
+ switched_on(user)
+ if(welding)
+ set_light(light_intensity)
+
update_icon()
//Returns the amount of fuel in the welder
@@ -272,17 +463,17 @@
//Removes fuel from the welding tool. If a mob is passed, it will try to flash the mob's eyes. This should probably be renamed to use()
/obj/item/weapon/weldingtool/proc/remove_fuel(amount = 1, mob/living/M = null)
if(!welding || !check_fuel())
- return 0
+ return FALSE
if(get_fuel() >= amount)
reagents.remove_reagent("fuel", amount)
check_fuel()
if(M)
M.flash_eyes(light_intensity)
- return 1
+ return TRUE
else
if(M)
- to_chat(M, "\blue You need more welding fuel to complete this task.")
- return 0
+ to_chat(M, "You need more welding fuel to complete this task.")
+ return FALSE
//Returns whether or not the welding tool is currently on.
/obj/item/weapon/weldingtool/proc/isOn()
@@ -291,19 +482,18 @@
//Turns off the welder if there is no more fuel (does this really need to be its own proc?)
/obj/item/weapon/weldingtool/proc/check_fuel(mob/user)
if(get_fuel() <= 0 && welding)
- toggle(user, 1)
+ switched_on(user)
update_icon()
//mob icon update
if(ismob(loc))
var/mob/M = loc
M.update_inv_r_hand(0)
M.update_inv_l_hand(0)
-
return 0
return 1
-//Toggles the welder off and on
-/obj/item/weapon/weldingtool/proc/toggle(mob/user, message = 0)
+//Switches the welder on
+/obj/item/weapon/weldingtool/proc/switched_on(mob/user)
if(!status)
to_chat(user, "[src] can't be turned on while unsecured!")
return
@@ -311,23 +501,29 @@
if(welding)
if(get_fuel() >= 1)
to_chat(user, "You switch [src] on.")
+ playsound(loc, acti_sound, 50, 1)
force = 15
damtype = "fire"
hitsound = 'sound/items/welder.ogg'
update_icon()
- processing_objects |= src
+ processing_objects.Add(src)
else
to_chat(user, "You need more fuel!")
- welding = 0
+ switched_off(user)
else
- if(!message)
- to_chat(user, "You switch [src] off.")
- else
- visible_message("[src] shuts off!")
- force = 3
- damtype = "brute"
- hitsound = "swing_hit"
- update_icon()
+ to_chat(user, "You switch [src] off.")
+ playsound(loc, deac_sound, 50, 1)
+ switched_off(user)
+
+//Switches the welder off
+/obj/item/weapon/weldingtool/proc/switched_off(mob/user)
+ welding = 0
+ set_light(0)
+
+ force = 3
+ damtype = "brute"
+ hitsound = "swing_hit"
+ update_icon()
/obj/item/weapon/weldingtool/proc/flamethrower_screwdriver(obj/item/I, mob/user)
if(welding)
@@ -354,7 +550,6 @@
user.put_in_hands(F)
else
to_chat(user, "You need one rod to start building a flamethrower!")
- return
/obj/item/weapon/weldingtool/largetank
name = "Industrial Welding Tool"
@@ -362,9 +557,12 @@
icon_state = "indwelder"
max_fuel = 40
materials = list(MAT_METAL=70, MAT_GLASS=60)
- origin_tech = "engineering=2"
+ origin_tech = "engineering=2;plasmatech=2"
/obj/item/weapon/weldingtool/largetank/cyborg
+ name = "integrated welding tool"
+ desc = "An advanced welder designed to be used in robotic systems."
+ toolspeed = 0.5
/obj/item/weapon/weldingtool/largetank/flamethrower_screwdriver()
return
@@ -374,22 +572,37 @@
desc = "A miniature welder used during emergencies."
icon_state = "miniwelder"
max_fuel = 10
- w_class = 1
+ w_class = WEIGHT_CLASS_TINY
materials = list(MAT_METAL=30, MAT_GLASS=10)
change_icons = 0
/obj/item/weapon/weldingtool/mini/flamethrower_screwdriver()
return
+/obj/item/weapon/weldingtool/abductor
+ name = "alien welding tool"
+ desc = "An alien welding tool. Whatever fuel it uses, it never runs out."
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "welder"
+ toolspeed = 0.1
+ light_intensity = 0
+ change_icons = 0
+ origin_tech = "plasmatech=5;engineering=5;abductor=3"
+ can_off_process = 1
+
+/obj/item/weapon/weldingtool/abductor/process()
+ if(get_fuel() <= max_fuel)
+ reagents.add_reagent("fuel", 1)
+ ..()
+
/obj/item/weapon/weldingtool/hugetank
name = "Upgraded Welding Tool"
desc = "An upgraded welder based off the industrial welder."
icon_state = "upindwelder"
item_state = "upindwelder"
max_fuel = 80
- w_class = 3
materials = list(MAT_METAL=70, MAT_GLASS=120)
- origin_tech = "engineering=3"
+ origin_tech = "engineering=3;plasmatech=2"
/obj/item/weapon/weldingtool/experimental
name = "Experimental Welding Tool"
@@ -397,25 +610,25 @@
icon_state = "exwelder"
item_state = "exwelder"
max_fuel = 40
- w_class = 3
materials = list(MAT_METAL=70, MAT_GLASS=120)
- origin_tech = "engineering=4;plasmatech=3"
+ origin_tech = "materials=4;engineering=4;bluespace=3;plasmatech=4"
change_icons = 0
can_off_process = 1
light_intensity = 1
+ toolspeed = 0.5
var/last_gen = 0
-/obj/item/weapon/weldingtool/experimental/proc/fuel_gen()
- if(!welding && !last_gen)
- last_gen = 1
- reagents.add_reagent("fuel",1)
- spawn(10)
- last_gen = 0
+/obj/item/weapon/weldingtool/experimental/brass
+ name = "brass welding tool"
+ desc = "A brass welder that seems to constantly refuel itself. It is faintly warm to the touch."
+ icon_state = "brasswelder"
+ item_state = "brasswelder"
-/obj/item/weapon/weldingtool/experimental/process()
+obj/item/weapon/weldingtool/experimental/process()
..()
- if(reagents.total_volume < max_fuel)
- fuel_gen()
+ if(get_fuel() < max_fuel && nextrefueltick < world.time)
+ nextrefueltick = world.time + 10
+ reagents.add_reagent("fuel", 1)
//Crowbar
/obj/item/weapon/crowbar
@@ -423,37 +636,91 @@
desc = "A small crowbar. This handy tool is useful for lots of things, such as prying floor tiles or opening unpowered doors."
icon = 'icons/obj/tools.dmi'
icon_state = "crowbar"
+ item_state = "crowbar"
+ usesound = 'sound/items/Crowbar.ogg'
flags = CONDUCT
slot_flags = SLOT_BELT
force = 5
throwforce = 7
item_state = "crowbar"
- w_class = 2
+ w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=50)
- origin_tech = "engineering=1"
+ origin_tech = "engineering=1;combat=1"
attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked")
+ toolspeed = 1
/obj/item/weapon/crowbar/red
- icon_state = "red_crowbar"
+ icon_state = "crowbar_red"
item_state = "crowbar_red"
+ force = 8
+
+/obj/item/weapon/crowbar/brass
+ name = "brass crowbar"
+ desc = "A brass crowbar. It feels faintly warm to the touch."
+ icon_state = "crowbar_brass"
+ item_state = "crowbar_brass"
+ toolspeed = 0.5
+
+/obj/item/weapon/crowbar/abductor
+ name = "alien crowbar"
+ desc = "A hard-light crowbar. It appears to pry by itself, without any effort required."
+ icon = 'icons/obj/abductor.dmi'
+ usesound = 'sound/weapons/sonic_jackhammer.ogg'
+ icon_state = "crowbar"
+ toolspeed = 0.1
+ origin_tech = "combat=4;engineering=4;abductor=3"
/obj/item/weapon/crowbar/large
name = "crowbar"
- desc = "It's a big crowbar. It doesn't fit in your pockets, because it's big."
+ desc = "It's a big crowbar. It doesn't fit in your pockets, because its too big."
force = 12
- w_class = 3
+ w_class = WEIGHT_CLASS_NORMAL
throw_speed = 3
throw_range = 3
materials = list(MAT_METAL=70)
icon_state = "crowbar_large"
+ item_state = "crowbar_large"
+ toolspeed = 0.5
+/obj/item/weapon/crowbar/cyborg
+ name = "hydraulic crowbar"
+ desc = "A hydraulic prying tool, compact but powerful. Designed to replace crowbar in construction cyborgs."
+ usesound = 'sound/items/jaws_pry.ogg'
+ force = 10
+ toolspeed = 0.5
+
+/obj/item/weapon/crowbar/power
+ name = "jaws of life"
+ desc = "A set of jaws of life, the magic of science has managed to fit it down into a device small enough to fit in a tool belt. It's fitted with a prying head."
+ icon_state = "jaws_pry"
+ item_state = "jawsoflife"
+ materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_DIAMOND=25)
+ origin_tech = "materials=2;engineering=2"
+ usesound = 'sound/items/jaws_pry.ogg'
+ force = 15
+ toolspeed = 0.25
+ var/airlock_open_time = 100 // Time required to open powered airlocks
+
+/obj/item/weapon/crowbar/power/suicide_act(mob/user)
+ user.visible_message("[user] is putting their head in [src], it looks like they're trying to commit suicide!")
+ playsound(loc, 'sound/items/jaws_pry.ogg', 50, 1, -1)
+ return (BRUTELOSS)
+
+/obj/item/weapon/crowbar/power/attack_self(mob/user)
+ playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1)
+ var/obj/item/weapon/wirecutters/power/cutjaws = new /obj/item/weapon/wirecutters/power
+ to_chat(user, "You attach the cutting jaws to [src].")
+ qdel(src)
+ user.put_in_active_hand(cutjaws)
+
+// Conversion kit
/obj/item/weapon/conversion_kit
name = "\improper Revolver Conversion Kit"
- desc = "A professional conversion kit used to convert any knock off revolver into the real deal capable of shooting lethal .357 rounds without the possibility of catastrophic failure"
+ desc = "A professional conversion kit used to convert any knock off revolver into the real deal capable of shooting lethal .357 rounds without the possibility of catastrophic failure."
icon = 'icons/obj/weapons.dmi'
icon_state = "kit"
flags = CONDUCT
- w_class = 2
+ w_class = WEIGHT_CLASS_SMALL
origin_tech = "combat=2"
var/open = 0
@@ -466,5 +733,5 @@
/obj/item/weapon/conversion_kit/attack_self(mob/user)
open = !open
- to_chat(user, "\blue You [open?"open" : "close"] the conversion kit.")
+ to_chat(user, "You [open ? "open" : "close"] the conversion kit.")
update_icon()
diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm
index 5c66759dc52..ce2b5965c6c 100644
--- a/code/game/objects/items/weapons/twohanded.dm
+++ b/code/game/objects/items/weapons/twohanded.dm
@@ -169,6 +169,7 @@
force_wielded = 24
attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut")
hitsound = 'sound/weapons/bladeslice.ogg'
+ usesound = 'sound/items/Crowbar.ogg'
/obj/item/weapon/twohanded/fireaxe/update_icon() //Currently only here to fuck with the on-mob icons.
icon_state = "fireaxe[wielded]"
@@ -227,7 +228,7 @@
return
..()
if((CLUMSY in user.mutations) && (wielded) &&prob(40))
- to_chat(user, "\red You twirl around a bit before losing your balance and impaling yourself on the [src].")
+ to_chat(user, "You twirl around a bit before losing your balance and impaling yourself on the [src].")
user.take_organ_damage(20,25)
return
if((wielded) && prob(50))
diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm
index 3c8a25ca739..d5b679fde56 100644
--- a/code/game/objects/items/weapons/weaponry.dm
+++ b/code/game/objects/items/weapons/weaponry.dm
@@ -138,4 +138,67 @@ obj/item/weapon/wirerod/attackby(obj/item/I, mob/user, params)
icon_state = "kidanspear"
item_state = "kidanspear"
force = 10
- throwforce = 15
\ No newline at end of file
+ throwforce = 15
+
+/obj/item/weapon/melee/baseball_bat
+ name = "baseball bat"
+ desc = "There ain't a skull in the league that can withstand a swatter."
+ icon = 'icons/obj/items.dmi'
+ icon_state = "baseball_bat"
+ item_state = "baseball_bat"
+ force = 10
+ throwforce = 12
+ attack_verb = list("beat", "smacked")
+ w_class = WEIGHT_CLASS_HUGE
+ var/homerun_ready = 0
+ var/homerun_able = 0
+
+/obj/item/weapon/melee/baseball_bat/homerun
+ name = "home run bat"
+ desc = "This thing looks dangerous... Dangerously good at baseball, that is."
+ homerun_able = 1
+
+/obj/item/weapon/melee/baseball_bat/attack_self(mob/user)
+ if(!homerun_able)
+ ..()
+ return
+ if(homerun_ready)
+ to_chat(user, "You're already ready to do a home run!")
+ ..()
+ return
+ to_chat(user, "You begin gathering strength...")
+ playsound(get_turf(src), 'sound/magic/lightning_chargeup.ogg', 65, 1)
+ if(do_after(user, 90, target = src))
+ to_chat(user, "You gather power! Time for a home run!")
+ homerun_ready = 1
+ ..()
+
+/obj/item/weapon/melee/baseball_bat/attack(mob/living/target, mob/living/user)
+ . = ..()
+ var/atom/throw_target = get_edge_target_turf(target, user.dir)
+ if(homerun_ready)
+ user.visible_message("It's a home run!")
+ target.throw_at(throw_target, rand(8,10), 14, user)
+ target.ex_act(2)
+ playsound(get_turf(src), 'sound/weapons/HOMERUN.ogg', 100, 1)
+ homerun_ready = 0
+ return
+ else
+ target.throw_at(throw_target, rand(1,2), 7, user)
+
+/obj/item/weapon/melee/baseball_bat/ablative
+ name = "metal baseball bat"
+ desc = "This bat is made of highly reflective, highly armored material."
+ icon_state = "baseball_bat_metal"
+ item_state = "baseball_bat_metal"
+ force = 12
+ throwforce = 15
+
+/obj/item/weapon/melee/baseball_bat/ablative/IsReflect()//some day this will reflect thrown items instead of lasers
+ var/picksound = rand(1,2)
+ var/turf = get_turf(src)
+ if(picksound == 1)
+ playsound(turf, 'sound/weapons/effects/batreflect1.ogg', 50, 1)
+ if(picksound == 2)
+ playsound(turf, 'sound/weapons/effects/batreflect2.ogg', 50, 1)
+ return 1
diff --git a/code/game/objects/items/weapons/whetstone.dm b/code/game/objects/items/weapons/whetstone.dm
index d19c411899f..d498d4c75e8 100644
--- a/code/game/objects/items/weapons/whetstone.dm
+++ b/code/game/objects/items/weapons/whetstone.dm
@@ -4,6 +4,7 @@
icon_state = "whetstone"
desc = "A block of stone used to sharpen things."
w_class = 2
+ usesound = 'sound/items/Screwdriver.ogg'
var/used = 0
var/increment = 4
var/max = 30
@@ -43,7 +44,7 @@
I.force = Clamp(I.force + increment, 0, max)
I.throwforce = Clamp(I.throwforce + increment, 0, max)
I.name = "[prefix] [I.name]"
- playsound(get_turf(src), 'sound/items/Screwdriver.ogg', 50, 1)
+ playsound(get_turf(src), usesound, 50, 1)
name = "worn out [name]"
desc = "[desc] At least, it used to."
used = 1
@@ -54,7 +55,7 @@
var/datum/unarmed_attack/attack = H.species.unarmed
if(istype(attack, /datum/unarmed_attack/claws))
H.visible_message("[H] sharpens \his claws on the [src]!", "You sharpen your claws on the [src].")
- playsound(get_turf(H), 'sound/items/Screwdriver.ogg', 50, 1)
+ playsound(get_turf(H), usesound, 50, 1)
/obj/item/weapon/whetstone/super
name = "super whetstone block"
diff --git a/code/game/objects/items/weapons/wires.dm b/code/game/objects/items/weapons/wires.dm
index 4d2e539042f..0f1e261699b 100644
--- a/code/game/objects/items/weapons/wires.dm
+++ b/code/game/objects/items/weapons/wires.dm
@@ -28,9 +28,9 @@
/obj/item/weapon/wire/attack_self(mob/user as mob)
if(src.laying)
src.laying = 0
- to_chat(user, "\blue You're done laying wire!")
+ to_chat(user, "You're done laying wire!")
else
- to_chat(user, "\blue You are not using this to lay wire...")
+ to_chat(user, "You are not using this to lay wire...")
return
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 70b3e3c1d67..91b232c051a 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -71,11 +71,11 @@
for(var/obj/O in range(0, src))
if(O.density == 1 && O != src && !istype(O, /obj/machinery/door/window)) //Ignores windoors, as those already block climbing, otherwise a windoor on the opposite side of a table would prevent climbing.
- to_chat(user, "\red You cannot climb [src], as it is blocked by \a [O]!")
+ to_chat(user, "You cannot climb [src], as it is blocked by \a [O]!")
return
for(var/turf/T in range(0, src))
if(T.density == 1)
- to_chat(user, "\red You cannot climb [src], as it is blocked by \a [T]!")
+ to_chat(user, "You cannot climb [src], as it is blocked by \a [T]!")
return
var/turf/T = src.loc
if(!T || !istype(T)) return
@@ -85,7 +85,7 @@
usr.visible_message("[user] starts climbing onto \the [src]!")
climber = user
- if(!do_after(user,50, target = src))
+ if(!do_after(user, 50, target = src))
climber = null
return
@@ -111,14 +111,14 @@
if(M.lying) return //No spamming this on people.
M.Weaken(5)
- to_chat(M, "\red You topple as \the [src] moves under you!")
+ to_chat(M, "You topple as \the [src] moves under you!")
if(prob(25))
var/damage = rand(15,30)
var/mob/living/carbon/human/H = M
if(!istype(H))
- to_chat(H, "\red You land heavily!")
+ to_chat(H, "You land heavily!")
M.adjustBruteLoss(damage)
return
@@ -137,12 +137,12 @@
affecting = H.get_organ("head")
if(affecting)
- to_chat(M, "\red You land heavily on your [affecting.name]!")
+ to_chat(M, "You land heavily on your [affecting.name]!")
affecting.take_damage(damage, 0)
if(affecting.parent)
affecting.parent.add_autopsy_data("Misadventure", damage)
else
- to_chat(H, "\red You land heavily!")
+ to_chat(H, "You land heavily!")
H.adjustBruteLoss(damage)
H.UpdateDamageIcon()
diff --git a/code/game/objects/structures/artstuff.dm b/code/game/objects/structures/artstuff.dm
index 045f58d577d..9636e1407b6 100644
--- a/code/game/objects/structures/artstuff.dm
+++ b/code/game/objects/structures/artstuff.dm
@@ -19,6 +19,9 @@
burntime = 15
var/obj/item/weapon/canvas/painting = null
+/obj/structure/easel/Destroy()
+ QDEL_NULL(painting)
+ return ..()
//Adding canvases
/obj/structure/easel/attackby(var/obj/item/I, var/mob/user, params)
diff --git a/code/game/objects/structures/coathanger.dm b/code/game/objects/structures/coathanger.dm
index 3c68792fece..0a30a914063 100644
--- a/code/game/objects/structures/coathanger.dm
+++ b/code/game/objects/structures/coathanger.dm
@@ -28,7 +28,7 @@
to_chat(user, "You cannot hang [W] on [src]")
return ..()
-/obj/structure/coatrack/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+/obj/structure/coatrack/CanPass(atom/movable/mover, turf/target, height=0)
var/can_hang = 0
for(var/T in allowed)
if(istype(mover,T))
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index e213c555c43..7180e59b800 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -13,7 +13,7 @@
var/lastbang
var/cutting_tool = /obj/item/weapon/weldingtool
var/sound = 'sound/machines/click.ogg'
- var/cutting_sound = 'sound/items/Welder.ogg'
+ var/cutting_sound
var/storage_capacity = 30 //This is so that someone can't pack hundreds of items in a locker/crate then open it in a populated area to crash clients.
var/material_drop = /obj/item/stack/sheet/metal
var/material_drop_amount = 2
@@ -22,7 +22,7 @@
..()
spawn(1)
if(!opened) // if closed, any item at the crate's loc is put in the contents
- for(var/obj/item/I in src.loc)
+ for(var/obj/item/I in loc)
if(I.density || I.anchored || I == src) continue
I.forceMove(src)
@@ -34,12 +34,12 @@
/obj/structure/closet/alter_health()
return get_turf(src)
-/obj/structure/closet/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if(air_group || (height==0 || wall_mounted)) return 1
+/obj/structure/closet/CanPass(atom/movable/mover, turf/target, height=0)
+ if(height==0 || wall_mounted) return 1
return (!density)
/obj/structure/closet/proc/can_open()
- if(src.welded)
+ if(welded)
return 0
return 1
@@ -59,46 +59,46 @@
throwing = 0
/obj/structure/closet/proc/open()
- if(src.opened)
+ if(opened)
return 0
- if(!src.can_open())
+ if(!can_open())
return 0
- src.dump_contents()
+ dump_contents()
- src.icon_state = src.icon_opened
- src.opened = 1
+ icon_state = icon_opened
+ opened = 1
if(sound)
- playsound(src.loc, src.sound, 15, 1, -3)
+ playsound(loc, sound, 15, 1, -3)
else
- playsound(src.loc, 'sound/machines/click.ogg', 15, 1, -3)
+ playsound(loc, 'sound/machines/click.ogg', 15, 1, -3)
density = 0
return 1
/obj/structure/closet/proc/close()
- if(!src.opened)
+ if(!opened)
return 0
- if(!src.can_close())
+ if(!can_close())
return 0
var/itemcount = 0
//Cham Projector Exception
- for(var/obj/effect/dummy/chameleon/AD in src.loc)
+ for(var/obj/effect/dummy/chameleon/AD in loc)
if(itemcount >= storage_capacity)
break
AD.forceMove(src)
itemcount++
- for(var/obj/item/I in src.loc)
+ for(var/obj/item/I in loc)
if(itemcount >= storage_capacity)
break
if(!I.anchored)
I.forceMove(src)
itemcount++
- for(var/mob/M in src.loc)
+ for(var/mob/M in loc)
if(itemcount >= storage_capacity)
break
if(istype (M, /mob/dead/observer))
@@ -109,37 +109,37 @@
M.forceMove(src)
itemcount++
- src.icon_state = src.icon_closed
- src.opened = 0
+ icon_state = icon_closed
+ opened = 0
if(sound)
- playsound(src.loc, src.sound, 15, 1, -3)
+ playsound(loc, sound, 15, 1, -3)
else
- playsound(src.loc, 'sound/machines/click.ogg', 15, 1, -3)
+ playsound(loc, 'sound/machines/click.ogg', 15, 1, -3)
density = 1
return 1
-/obj/structure/closet/proc/toggle(mob/user as mob)
- if(!(src.opened ? src.close() : src.open()))
+/obj/structure/closet/proc/toggle(mob/user)
+ if(!(opened ? close() : open()))
to_chat(user, "It won't budge!")
// this should probably use dump_contents()
/obj/structure/closet/ex_act(severity)
switch(severity)
if(1)
- for(var/atom/movable/A as mob|obj in src)//pulls everything out of the locker and hits it with an explosion
- A.forceMove(src.loc)
+ for(var/atom/movable/A in src)//pulls everything out of the locker and hits it with an explosion
+ A.forceMove(loc)
A.ex_act(severity++)
qdel(src)
if(2)
if(prob(50))
- for(var/atom/movable/A as mob|obj in src)
+ for(var/atom/movable/A in src)
A.forceMove(loc)
A.ex_act(severity++)
new /obj/item/stack/sheet/metal(loc)
qdel(src)
if(3)
if(prob(5))
- for(var/atom/movable/A as mob|obj in src)
+ for(var/atom/movable/A in src)
A.forceMove(loc)
A.ex_act(severity++)
new /obj/item/stack/sheet/metal(loc)
@@ -150,32 +150,32 @@
if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
health -= Proj.damage
if(health <= 0)
- for(var/atom/movable/A as mob|obj in src)
+ for(var/atom/movable/A in src)
A.forceMove(loc)
qdel(src)
-/obj/structure/closet/attack_animal(mob/living/simple_animal/user as mob)
+/obj/structure/closet/attack_animal(mob/living/simple_animal/user)
if(user.environment_smash)
user.do_attack_animation(src)
- visible_message("\red [user] destroys the [src]. ")
- for(var/atom/movable/A as mob|obj in src)
+ visible_message("[user] destroys the [src].")
+ for(var/atom/movable/A in src)
A.forceMove(loc)
qdel(src)
// this should probably use dump_contents()
/obj/structure/closet/blob_act()
if(prob(75))
- for(var/atom/movable/A as mob|obj in src)
+ for(var/atom/movable/A in src)
A.forceMove(loc)
qdel(src)
-/obj/structure/closet/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
- if(istype(W, /obj/item/weapon/rcs) && !src.opened)
+/obj/structure/closet/attackby(obj/item/weapon/W, mob/user, params)
+ if(istype(W, /obj/item/weapon/rcs) && !opened)
if(user in contents) //to prevent self-teleporting.
return
var/obj/item/weapon/rcs/E = W
if(E.rcell && (E.rcell.charge >= E.chargecost))
- if(!is_level_reachable(src.z))
+ if(!is_level_reachable(z))
to_chat(user, "The rapid-crate-sender can't locate any telepads!")
return
if(E.mode == 0)
@@ -193,10 +193,10 @@
L[tmpname] = R
var/desc = input("Please select a telepad.", "RCS") in L
E.pad = L[desc]
- playsound(E.loc, 'sound/machines/click.ogg', 50, 1)
- to_chat(user, "\blue Teleporting [src.name]...")
+ playsound(E.loc, E.usesound, 50, 1)
+ to_chat(user, "Teleporting [name]...")
E.teleporting = 1
- if(!do_after(user, 50, target = src))
+ if(!do_after(user, 50 * E.toolspeed, target = src))
E.teleporting = 0
return
E.teleporting = 0
@@ -215,10 +215,10 @@
E.rand_x = rand(50,200)
E.rand_y = rand(50,200)
var/L = locate(E.rand_x, E.rand_y, 6)
- playsound(E.loc, 'sound/machines/click.ogg', 50, 1)
- to_chat(user, "\blue Teleporting [src.name]...")
+ playsound(E.loc, E.usesound, 50, 1)
+ to_chat(user, "Teleporting [name]...")
E.teleporting = 1
- if(!do_after(user, 50, target = src))
+ if(!do_after(user, 50, E.toolspeed, target = src))
E.teleporting = 0
return
E.teleporting = 0
@@ -237,9 +237,9 @@
to_chat(user, "Out of charges.")
return
- if(src.opened)
+ if(opened)
if(istype(W, /obj/item/weapon/grab))
- src.MouseDrop_T(W:affecting, user) //act like they were dragged onto the closet
+ MouseDrop_T(W:affecting, user) //act like they were dragged onto the closet
if(istype(W,/obj/item/tk_grab))
return 0
if(istype(W, cutting_tool))
@@ -248,11 +248,11 @@
if(!WT.remove_fuel(0, user))
return
to_chat(user, "You begin cutting \the [src] apart...")
- playsound(loc, cutting_sound, 40, 1)
- if(do_after(user, 40, 1, target = src))
+ playsound(loc, cutting_sound ? cutting_sound : WT.usesound, 40, 1)
+ if(do_after(user, 40 * WT.toolspeed, 1, target = src))
if(!opened || !WT.isOn())
return
- playsound(loc, cutting_sound, 50, 1)
+ playsound(loc, cutting_sound ? cutting_sound : WT.usesound, 50, 1)
visible_message("[user] slices apart \the [src].",
"You cut \the [src] apart with \the [WT].",
"You hear welding.")
@@ -262,7 +262,8 @@
return
if(isrobot(user))
return
- if(!usr.drop_item())
+ if(!user.drop_item()) //couldn't drop the item
+ to_chat(user, "\The [W] is stuck to your hand, you cannot put it in \the [src]!")
return
if(W)
W.forceMove(loc)
@@ -276,14 +277,14 @@
if(!WT.remove_fuel(0,user))
to_chat(user, "You need more welding fuel to complete this task.")
return
- src.welded = !src.welded
- src.update_icon()
+ welded = !welded
+ update_icon()
for(var/mob/M in viewers(src))
M.show_message("[src] has been [welded?"welded shut":"unwelded"] by [user.name].", 3, "You hear welding.", 2)
else
- src.attack_hand(user)
+ attack_hand(user)
-/obj/structure/closet/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob)
+/obj/structure/closet/MouseDrop_T(atom/movable/O, mob/user)
..()
if(istype(O, /obj/screen)) //fix for HUD elements making their way into the world -Pete
return
@@ -297,24 +298,24 @@
return
if(!istype(user.loc, /turf)) // are you in a container/closet/pod/etc?
return
- if(!src.opened)
+ if(!opened)
return
if(istype(O, /obj/structure/closet))
return
- step_towards(O, src.loc)
+ step_towards(O, loc)
if(user != O)
user.visible_message("[user] stuffs [O] into [src]!", "You stuff [O] into [src]!")
- src.add_fingerprint(user)
+ add_fingerprint(user)
/obj/structure/closet/attack_ai(mob/user)
- if(istype(user, /mob/living/silicon/robot) && Adjacent(user)) //Robots can open/close it, but not the AI
+ if(isrobot(user) && Adjacent(user)) //Robots can open/close it, but not the AI
attack_hand(user)
-/obj/structure/closet/relaymove(mob/user as mob)
- if(user.stat || !isturf(src.loc))
+/obj/structure/closet/relaymove(mob/user)
+ if(user.stat || !isturf(loc))
return
- if(!src.open())
+ if(!open())
to_chat(user, "It won't budge!")
if(!lastbang)
lastbang = 1
@@ -323,14 +324,18 @@
spawn(30)
lastbang = 0
-/obj/structure/closet/attack_hand(mob/user as mob)
- src.add_fingerprint(user)
- src.toggle(user)
+/obj/structure/closet/attack_hand(mob/user)
+ add_fingerprint(user)
+ toggle(user)
+
+/obj/structure/closet/attack_ghost(mob/user)
+ if(user.can_advanced_admin_interact())
+ toggle(user)
// tk grab then use on self
-/obj/structure/closet/attack_self_tk(mob/user as mob)
- src.add_fingerprint(user)
- if(!src.toggle())
+/obj/structure/closet/attack_self_tk(mob/user)
+ add_fingerprint(user)
+ if(!toggle())
to_chat(usr, "It won't budge!")
/obj/structure/closet/verb/verb_toggleopen()
@@ -338,12 +343,12 @@
set category = null
set name = "Toggle Open"
- if(!usr.canmove || usr.stat || usr.restrained())
+ if(usr.incapacitated())
return
if(ishuman(usr))
- src.add_fingerprint(usr)
- src.toggle(usr)
+ add_fingerprint(usr)
+ toggle(usr)
else
to_chat(usr, "This mob type can't use this verb.")
@@ -399,8 +404,8 @@
to_chat(usr, "You successfully break out!")
for(var/mob/O in viewers(L.loc))
O.show_message("\the [usr] successfully broke out of \the [src]!", 1)
- if(istype(src.loc, /obj/structure/bigDelivery)) //nullspace ect.. read the comment above
- var/obj/structure/bigDelivery/BD = src.loc
+ if(istype(loc, /obj/structure/bigDelivery)) //nullspace ect.. read the comment above
+ var/obj/structure/bigDelivery/BD = loc
BD.attack_hand(usr)
open()
diff --git a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm
index 715d16f9ebd..aeb8101fc75 100644
--- a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm
+++ b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm
@@ -23,9 +23,9 @@
if(isrobot(user) || src.locked)
if(istype(O, /obj/item/device/multitool))
- to_chat(user, "\red Resetting circuitry...")
+ to_chat(user, "Resetting circuitry...")
playsound(user, 'sound/machines/lockreset.ogg', 50, 1)
- if(do_after(user, 20, target = src))
+ if(do_after(user, 20 * O.toolspeed, target = src))
src.locked = 0
to_chat(user, " You disable the locking modules.")
update_icon()
@@ -43,7 +43,7 @@
user.do_attack_animation(src)
playsound(user, 'sound/effects/Glasshit.ogg', 100, 1) //We don't want this playing every time
if(W.force < 15)
- to_chat(user, "\blue The cabinet's protective glass glances off the hit.")
+ to_chat(user, "The cabinet's protective glass glances off the hit.")
else
src.hitstaken++
if(src.hitstaken == 4)
@@ -56,12 +56,12 @@
if(istype(O, /obj/item/weapon/twohanded/fireaxe) && src.localopened)
if(!fireaxe)
if(O:wielded)
- to_chat(user, "\red Unwield the axe first.")
+ to_chat(user, "Unwield the axe first.")
return
fireaxe = O
user.drop_item(O)
src.contents += O
- to_chat(user, "\blue You place the fire axe back in the [src.name].")
+ to_chat(user, "You place the fire axe back in the [src.name].")
update_icon()
else
if(src.smashed)
@@ -84,12 +84,12 @@
spawn(10) update_icon()
return
else
- to_chat(user, "\red Resetting circuitry...")
+ to_chat(user, "Resetting circuitry...")
sleep(50)
src.locked = 1
- to_chat(user, "\blue You re-enable the locking modules.")
+ to_chat(user, "You re-enable the locking modules.")
playsound(user, 'sound/machines/lockenable.ogg', 50, 1)
- if(do_after(user,20, target = src))
+ if(do_after(user, 20 * O.toolspeed, target = src))
src.locked = 1
to_chat(user, " You re-enable the locking modules.")
return
@@ -112,13 +112,13 @@
hasaxe = 1
if(src.locked)
- to_chat(user, "\red The cabinet won't budge!")
+ to_chat(user, "The cabinet won't budge!")
return
if(localopened)
if(fireaxe)
user.put_in_hands(fireaxe)
fireaxe = null
- to_chat(user, "\blue You take the fire axe from the [name].")
+ to_chat(user, "You take the fire axe from the [name].")
src.add_fingerprint(user)
update_icon()
else
@@ -145,7 +145,7 @@
attack_tk(mob/user as mob)
if(localopened && fireaxe)
fireaxe.forceMove(loc)
- to_chat(user, "\blue You telekinetically remove the fire axe.")
+ to_chat(user, "You telekinetically remove the fire axe.")
fireaxe = null
update_icon()
return
@@ -157,9 +157,9 @@
if(isrobot(usr) || src.locked || src.smashed)
if(src.locked)
- to_chat(usr, "\red The cabinet won't budge!")
+ to_chat(usr, "The cabinet won't budge!")
else if(src.smashed)
- to_chat(usr, "\blue The protective glass is broken!")
+ to_chat(usr, "The protective glass is broken!")
return
localopened = !localopened
@@ -176,23 +176,23 @@
if(fireaxe)
usr.put_in_hands(fireaxe)
fireaxe = null
- to_chat(usr, "\blue You take the Fire axe from the [name].")
+ to_chat(usr, "You take the Fire axe from the [name].")
else
- to_chat(usr, "\blue The [src.name] is empty.")
+ to_chat(usr, "The [src.name] is empty.")
else
- to_chat(usr, "\blue The [src.name] is closed.")
+ to_chat(usr, "The [src.name] is closed.")
update_icon()
attack_ai(mob/user as mob)
if(src.smashed)
- to_chat(user, "\red The security of the cabinet is compromised.")
+ to_chat(user, "The security of the cabinet is compromised.")
return
else
locked = !locked
if(locked)
- to_chat(user, "\red Cabinet locked.")
+ to_chat(user, "Cabinet locked.")
else
- to_chat(user, "\blue Cabinet unlocked.")
+ to_chat(user, "Cabinet unlocked.")
update_icon() //Template: fireaxe[has fireaxe][is opened][hits taken][is smashed]. If you want the opening or closing animations, add "opening" or "closing" right after the numbers
var/hasaxe = 0
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm
index a008e3843e9..b0e7c0e00cb 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm
@@ -1,4 +1,5 @@
/obj/structure/closet/secure_closet/freezer
+ desc = "It's a card-locked refrigerative storage unit. This one is lead-lined."
/obj/structure/closet/secure_closet/freezer/update_icon()
if(broken)
@@ -87,11 +88,14 @@
icon_off = "fridge1"
req_access = list(access_heads_vault)
-
- New()
- ..()
- dispense_cash(6700, src)
-
+/obj/structure/closet/secure_closet/freezer/money/New()
+ ..()
+ for(var/i in 1 to 3)
+ new /obj/item/stack/spacecash/c1000(src)
+ for(var/i in 1 to 5)
+ new /obj/item/stack/spacecash/c500(src)
+ for(var/i in 1 to 6)
+ new /obj/item/stack/spacecash/c200(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm
index 7eab1e6de85..e6d21e79244 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm
@@ -62,7 +62,7 @@
if(W) W.forceMove(loc)
else if(istype(W, /obj/item/weapon/card/id))
if(src.broken)
- to_chat(user, "\red It appears to be broken.")
+ to_chat(user, "It appears to be broken.")
return
var/obj/item/weapon/card/id/I = W
if(!I || !I.registered_name) return
@@ -82,8 +82,8 @@
src.registered_name = I.registered_name
src.desc = "Owned by [I.registered_name]."
else
- to_chat(user, "\red Access Denied")
+ to_chat(user, "Access Denied")
else if((istype(W, /obj/item/weapon/card/emag) || istype(W, /obj/item/weapon/melee/energy/blade)) && !broken)
emag_act(user)
else
- to_chat(user, "\red Access Denied")
+ to_chat(user, "Access Denied")
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
index db589c027e6..19dc1622ffe 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
@@ -19,14 +19,14 @@
/obj/structure/closet/secure_closet/can_open()
if(!..())
return 0
- if(src.locked)
+ if(locked)
return 0
return ..()
/obj/structure/closet/secure_closet/close()
if(..())
if(broken)
- icon_state = src.icon_off
+ icon_state = icon_off
return 1
else
return 0
@@ -36,29 +36,29 @@
O.emp_act(severity)
if(!broken)
if(prob(50/severity))
- src.locked = !src.locked
- src.update_icon()
+ locked = !locked
+ update_icon()
if(prob(20/severity) && !opened)
if(!locked)
open()
else
- src.req_access = list()
- src.req_access += pick(get_all_accesses())
+ req_access = list()
+ req_access += pick(get_all_accesses())
..()
-/obj/structure/closet/secure_closet/proc/togglelock(mob/user as mob)
- if(src.opened)
+/obj/structure/closet/secure_closet/proc/togglelock(mob/user)
+ if(opened)
to_chat(user, "Close the locker first.")
return
- if(src.broken)
+ if(broken)
to_chat(user, "The locker appears to be broken.")
return
if(user.loc == src)
to_chat(user, "You can't reach the lock from inside.")
return
- if(src.allowed(user))
- src.locked = !src.locked
- playsound(src.loc, 'sound/machines/click.ogg', 15, 1, -3)
+ if(allowed(user))
+ locked = !locked
+ playsound(loc, 'sound/machines/click.ogg', 15, 1, -3)
for(var/mob/O in viewers(user, 3))
if((O.client && !( O.blinded )))
to_chat(O, "The locker has been [locked ? null : "un"]locked by [user].")
@@ -66,19 +66,21 @@
else
to_chat(user, "Access Denied")
-/obj/structure/closet/secure_closet/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
+/obj/structure/closet/secure_closet/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/rcs))
return ..()
- if(src.opened)
+ if(opened)
if(istype(W, /obj/item/weapon/grab))
- if(src.large)
- src.MouseDrop_T(W:affecting, user) //act like they were dragged onto the closet
+ if(large)
+ MouseDrop_T(W:affecting, user) //act like they were dragged onto the closet
else
to_chat(user, "The locker is too small to stuff [W:affecting] into!")
if(isrobot(user))
return
- user.drop_item()
+ if(!user.drop_item()) //couldn't drop the item
+ to_chat(user, "\The [W] is stuck to your hand, you cannot put it in \the [src]!")
+ return
if(W)
W.forceMove(loc)
else if((istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)) && !broken)
@@ -88,7 +90,7 @@
else
togglelock(user)
-/obj/structure/closet/secure_closet/emag_act(user as mob)
+/obj/structure/closet/secure_closet/emag_act(mob/user)
if(!broken)
broken = 1
locked = 0
@@ -97,24 +99,24 @@
flick(icon_broken, src)
to_chat(user, "You unlock \the [src].")
-/obj/structure/closet/secure_closet/attack_hand(mob/user as mob)
- src.add_fingerprint(user)
- if(src.locked)
- src.togglelock(user)
+/obj/structure/closet/secure_closet/attack_hand(mob/user)
+ add_fingerprint(user)
+ if(locked)
+ togglelock(user)
else
- src.toggle(user)
+ toggle(user)
/obj/structure/closet/secure_closet/verb/verb_togglelock()
set src in oview(1) // One square distance
set category = "Object"
set name = "Toggle Lock"
- if(!usr.canmove || usr.stat || usr.restrained()) // Don't use it if you're not able to! Checks for stuns, ghost and restrain
+ if(usr.incapacitated()) // Don't use it if you're not able to! Checks for stuns, ghost and restrain
return
if(ishuman(usr))
- src.add_fingerprint(usr)
- src.togglelock(usr)
+ add_fingerprint(usr)
+ togglelock(usr)
else
to_chat(usr, "This mob type can't use this verb.")
@@ -167,10 +169,10 @@
locked = 0
welded = 0
update_icon()
- to_chat(usr, "\red You successfully break out!")
+ to_chat(usr, "You successfully break out!")
for(var/mob/O in viewers(L.loc))
O.show_message("\the [usr] successfully broke out of \the [src]!", 1)
- if(istype(src.loc, /obj/structure/bigDelivery)) //Do this to prevent contents from being opened into nullspace (read: bluespace)
- var/obj/structure/bigDelivery/BD = src.loc
+ if(istype(loc, /obj/structure/bigDelivery)) //Do this to prevent contents from being opened into nullspace (read: bluespace)
+ var/obj/structure/bigDelivery/BD = loc
BD.attack_hand(usr)
open()
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 fce3cd376e2..1d7b32fe950 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
@@ -15,7 +15,6 @@
else
new /obj/item/weapon/storage/backpack/satchel_cap(src)
new /obj/item/weapon/book/manual/faxes(src)
- new /obj/item/clothing/head/crown/fancy(src)
new /obj/item/weapon/storage/backpack/duffel/captain(src)
new /obj/item/clothing/suit/captunic(src)
new /obj/item/clothing/suit/captunic/capjacket(src)
@@ -113,7 +112,7 @@
new /obj/item/clothing/head/HoS(src)
new /obj/item/clothing/head/HoS/beret(src)
new /obj/item/clothing/glasses/hud/security/sunglasses(src)
- new /obj/item/weapon/storage/lockbox/loyalty(src)
+ new /obj/item/weapon/storage/lockbox/mindshield(src)
new /obj/item/weapon/storage/box/flashbangs(src)
new /obj/item/clothing/mask/gas/sechailer/hos(src)
new /obj/item/weapon/shield/riot/tele(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/statue.dm b/code/game/objects/structures/crates_lockers/closets/statue.dm
index 3c198e4dd08..0692c90ec6d 100644
--- a/code/game/objects/structures/crates_lockers/closets/statue.dm
+++ b/code/game/objects/structures/crates_lockers/closets/statue.dm
@@ -71,7 +71,7 @@
M.forceMove(loc)
M.disabilities -= MUTE
M.take_overall_damage((M.health - health - 100),0) //any new damage the statue incurred is transfered to the mob
-
+
..()
/obj/structure/closet/statue/open()
@@ -114,7 +114,7 @@
/obj/structure/closet/statue/attackby(obj/item/I as obj, mob/user as mob, params)
user.changeNext_move(CLICK_CD_MELEE)
health -= I.force
- visible_message("\red [user] strikes [src] with [I].")
+ visible_message("[user] strikes [src] with [I].")
check_health()
/obj/structure/closet/statue/MouseDrop_T()
@@ -136,20 +136,5 @@
if(user)
user.dust()
dump_contents()
- visible_message("\red [src] shatters!. ")
+ visible_message("[src] shatters!. ")
qdel(src)
-
-
-/obj/structure/statue
- name = "statue"
- desc = "An incredibly lifelike marble carving"
- icon = 'icons/obj/statue.dmi'
- icon_state = "human_male"
- density = 1
- anchored = 1
-
-obj/structure/statue/angel
- icon_state = "angelseen"
-
-obj/structure/statue/corgi
- icon_state = "corgi"
\ No newline at end of file
diff --git a/code/game/objects/structures/crates_lockers/closets/syndicate.dm b/code/game/objects/structures/crates_lockers/closets/syndicate.dm
index e4aa901436e..26bd0d88759 100644
--- a/code/game/objects/structures/crates_lockers/closets/syndicate.dm
+++ b/code/game/objects/structures/crates_lockers/closets/syndicate.dm
@@ -23,9 +23,9 @@
/obj/structure/closet/syndicate/suits/New()
..()
- new /obj/item/clothing/head/helmet/space/rig/syndi(src)
+ new /obj/item/clothing/head/helmet/space/hardsuit/syndi(src)
new /obj/item/clothing/mask/gas/syndicate(src)
- new /obj/item/clothing/suit/space/rig/syndi(src)
+ new /obj/item/clothing/suit/space/hardsuit/syndi(src)
new /obj/item/weapon/tank/jetpack/oxygen/harness(src)
/obj/structure/closet/syndicate/nuclear
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index 23f5330e48a..07a738a8c94 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -80,7 +80,7 @@
src.opened = 0
return 1
-/obj/structure/closet/crate/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
+/obj/structure/closet/crate/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/rcs) && !src.opened)
var/obj/item/weapon/rcs/E = W
if(E.rcell && (E.rcell.charge >= E.chargecost))
@@ -102,10 +102,10 @@
L[tmpname] = R
var/desc = input("Please select a telepad.", "RCS") in L
E.pad = L[desc]
- playsound(E.loc, 'sound/machines/click.ogg', 50, 1)
- to_chat(user, "\blue Teleporting [src.name]...")
+ playsound(E.loc, E.usesound, 50, 1)
+ to_chat(user, "Teleporting [src.name]...")
E.teleporting = 1
- if(!do_after(user, 50, target = src))
+ if(!do_after(user, 50 * E.toolspeed, target = src))
E.teleporting = 0
return
E.teleporting = 0
@@ -120,10 +120,10 @@
E.rand_x = rand(50,200)
E.rand_y = rand(50,200)
var/L = locate(E.rand_x, E.rand_y, 6)
- playsound(E.loc, 'sound/machines/click.ogg', 50, 1)
- to_chat(user, "\blue Teleporting [src.name]...")
+ playsound(E.loc, E.usesound, 50, 1)
+ to_chat(user, "Teleporting [src.name]...")
E.teleporting = 1
- if(!do_after(user, 50, target = src))
+ if(!do_after(user, 50 * E.toolspeed, target = src))
E.teleporting = 0
return
E.teleporting = 0
@@ -166,7 +166,7 @@
else if(istype(W, /obj/item/weapon/wirecutters))
if(rigged)
to_chat(user, "You cut away the wiring.")
- playsound(loc, 'sound/items/Wirecutter.ogg', 100, 1)
+ playsound(loc, W.usesound, 100, 1)
rigged = 0
return
else return attack_hand(user)
@@ -191,7 +191,7 @@
else
return
-/obj/structure/closet/crate/attack_hand(mob/user as mob)
+/obj/structure/closet/crate/attack_hand(mob/user)
if(manifest)
to_chat(user, "You tear the manifest off of the crate.")
playsound(src.loc, 'sound/items/poster_ripped.ogg', 75, 1)
@@ -250,7 +250,7 @@
/obj/structure/closet/crate/secure/can_open()
return !locked
-/obj/structure/closet/crate/secure/proc/togglelock(mob/user as mob)
+/obj/structure/closet/crate/secure/proc/togglelock(mob/user)
if(src.opened)
to_chat(user, "Close the crate first.")
return
@@ -280,7 +280,7 @@
else
to_chat(usr, "This mob type can't use this verb.")
-/obj/structure/closet/crate/secure/attack_hand(mob/user as mob)
+/obj/structure/closet/crate/secure/attack_hand(mob/user)
if(manifest)
to_chat(user, "You tear the manifest off of the crate.")
playsound(src.loc, 'sound/items/poster_ripped.ogg', 75, 1)
@@ -296,7 +296,7 @@
src.toggle(user)
-/obj/structure/closet/crate/secure/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
+/obj/structure/closet/crate/secure/attackby(obj/item/weapon/W, mob/user, params)
if(is_type_in_list(W, list(/obj/item/stack/packageWrap, /obj/item/stack/cable_coil, /obj/item/device/radio/electropack, /obj/item/weapon/wirecutters,/obj/item/weapon/rcs)))
return ..()
if((istype(W, /obj/item/weapon/card/emag) || istype(W, /obj/item/weapon/melee/energy/blade)))
@@ -307,7 +307,7 @@
return
return ..()
-/obj/structure/closet/crate/secure/emag_act(user as mob)
+/obj/structure/closet/crate/secure/emag_act(mob/user)
if(locked)
overlays += sparks
spawn(6) overlays -= sparks //Tried lots of stuff but nothing works right. so i have to use this *sadface*
diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm
index 30e7031db2f..9ecf82a54fb 100644
--- a/code/game/objects/structures/displaycase.dm
+++ b/code/game/objects/structures/displaycase.dm
@@ -22,6 +22,11 @@ var/global/list/captain_display_cases = list()
var/obj/item/device/assembly/prox_sensor/sensor = null
var/state = DISPLAYCASE_FRAME_CIRCUIT
+/obj/structure/displaycase_frame/Destroy()
+ QDEL_NULL(circuit)
+ QDEL_NULL(sensor)
+ return ..()
+
/obj/structure/displaycase_frame/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
var/pstate = state
var/turf/T = get_turf(src)
@@ -33,14 +38,14 @@ var/global/list/captain_display_cases = list()
circuit.forceMove(src)
state++
to_chat(user, "You add the airlock electronics to the frame.")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src),W.usesound, 50, 1)
if(istype(W, /obj/item/weapon/crowbar))
new /obj/machinery/constructable_frame/machine_frame(T)
var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(T)
G.amount = 5
qdel(src)
to_chat(user, "You pry the glass out of the frame.")
- playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1)
+ playsound(get_turf(src), W.usesound, 50, 1)
return
if(DISPLAYCASE_FRAME_SCREWDRIVER)
@@ -54,7 +59,7 @@ var/global/list/captain_display_cases = list()
C.req_one_access = null
if(isprox(sensor))
C.burglar_alarm = 1
- playsound(get_turf(src), 'sound/items/Screwdriver.ogg', 50, 1)
+ playsound(get_turf(src), W.usesound, 50, 1)
qdel(src)
return
if(istype(W, /obj/item/weapon/crowbar))
@@ -65,13 +70,13 @@ var/global/list/captain_display_cases = list()
sensor = null
state--
to_chat(user, "You pry the electronics out of the frame.")
- playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1)
+ playsound(get_turf(src), W.usesound, 50, 1)
if(isprox(W) && !isprox(sensor))
user.drop_item()
sensor = W
sensor.forceMove(src)
to_chat(user, "You add the proximity sensor to the frame.")
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, W.usesound, 50, 1)
if(pstate != state)
pstate = state
@@ -116,8 +121,7 @@ var/global/list/captain_display_cases = list()
/obj/structure/displaycase/Destroy()
dump()
- qdel(circuit)
- circuit = null
+ QDEL_NULL(circuit)
return ..()
/obj/structure/displaycase/captains_laser/Destroy()
@@ -227,7 +231,7 @@ var/global/list/captain_display_cases = list()
"You pry \the [src] apart.", \
"You hear something pop.")
var/turf/T = get_turf(src)
- playsound(T, 'sound/items/Crowbar.ogg', 50, 1)
+ playsound(T, W.usesound, 50, 1)
dump()
var/obj/item/weapon/airlock_electronics/C = circuit
if(!C)
diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm
index dc7152bbd5f..b8ab485512a 100644
--- a/code/game/objects/structures/door_assembly.dm
+++ b/code/game/objects/structures/door_assembly.dm
@@ -13,10 +13,15 @@
var/glass_type = "/glass"
var/glass = 0 // 0 = glass can be installed. -1 = glass can't be installed. 1 = glass is already installed. Text = mineral plating is installed instead.
var/created_name = null
+ var/heat_proof_finished = 0 //whether to heat-proof the finished airlock
/obj/structure/door_assembly/New()
update_state()
+/obj/structure/door_assembly/Destroy()
+ QDEL_NULL(electronics)
+ return ..()
+
/obj/structure/door_assembly/door_assembly_com
base_icon_state = "com"
base_name = "Command Airlock"
@@ -94,7 +99,7 @@
base_name = "Maintenance Hatch"
airlock_type = "/maintenance_hatch"
glass = -1
-
+
/obj/structure/door_assembly/door_assembly_highsecurity // Borrowing this until WJohnston makes sprites for the assembly
base_icon_state = "highsec"
base_name = "High Security Airlock"
@@ -103,7 +108,7 @@
/obj/structure/door_assembly/door_assembly_shuttle
base_icon_state = "shuttle"
- base_name = "shuttle airlock"
+ base_name = "Shuttle Airlock"
airlock_type = "/shuttle"
glass = -1
@@ -115,12 +120,6 @@
airlock_type = "/multi_tile/glass"
glass = -1 //To prevent bugs in deconstruction process.
-/obj/structure/door_assembly/door_assembly_cult
- base_name = "cult airlock assembly"
- icon = 'icons/obj/doors/Doorcult.dmi'
- base_icon_state ="construction"
- airlock_type = "/cult"
-
/obj/structure/door_assembly/multi_tile/New()
if(dir in list(EAST, WEST))
bound_width = width * world.icon_size
@@ -146,7 +145,6 @@
airlock_type = "/cult"
glass = -1
-
/obj/structure/door_assembly/door_assembly_cultruned
icon = 'icons/obj/doors/Doorcultruned.dmi'
base_icon_state = "construction"
@@ -154,7 +152,6 @@
airlock_type = "/cult/runed"
glass = -1
-
/obj/structure/door_assembly/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/weapon/pen))
var/t = copytext(stripped_input(user, "Enter the name for the door.", src.name, src.created_name),1,MAX_NAME_LEN)
@@ -166,73 +163,78 @@
if(istype(W, /obj/item/weapon/weldingtool) && ( (istext(glass)) || (glass == 1) || (!anchored) ))
var/obj/item/weapon/weldingtool/WT = W
if(WT.remove_fuel(0, user))
- playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(src.loc, WT.usesound, 50, 1)
if(istext(glass))
user.visible_message("[user] welds the [glass] plating off the airlock assembly.", "You start to weld the [glass] plating off the airlock assembly.")
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * WT.toolspeed, target = src))
if(!src || !WT.isOn()) return
- to_chat(user, "\blue You welded the [glass] plating off!")
+ to_chat(user, "You welded the [glass] plating off!")
var/M = text2path("/obj/item/stack/sheet/mineral/[glass]")
new M(src.loc, 2)
glass = 0
else if(glass == 1)
user.visible_message("[user] welds the glass panel out of the airlock assembly.", "You start to weld the glass panel out of the airlock assembly.")
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * WT.toolspeed, target = src))
if(!src || !WT.isOn()) return
- to_chat(user, "\blue You welded the glass panel out!")
- new /obj/item/stack/sheet/rglass(src.loc)
+ to_chat(user, "You welded the glass panel out!")
+ if(heat_proof_finished)
+ new /obj/item/stack/sheet/rglass(get_turf(src))
+ heat_proof_finished = 0
+ else
+ new /obj/item/stack/sheet/glass(get_turf(src))
glass = 0
else if(!anchored)
- user.visible_message("[user] dissassembles the airlock assembly.", "You start to dissassemble the airlock assembly.")
- if(do_after(user, 40, target = src))
+ user.visible_message("[user] disassembles the airlock assembly.", "You start to disassemble the airlock assembly.")
+ if(do_after(user, 40 * WT.toolspeed, target = src))
if(!src || !WT.isOn()) return
- to_chat(user, "\blue You dissasembled the airlock assembly!")
+ to_chat(user, "You dissasembled the airlock assembly!")
new /obj/item/stack/sheet/metal(src.loc, 4)
qdel(src)
else
- to_chat(user, "\blue You need more welding fuel.")
+ to_chat(user, "You need more welding fuel.")
return
else if(istype(W, /obj/item/weapon/wrench) && state == 0)
- playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
+ playsound(src.loc, W.usesound, 100, 1)
if(anchored)
user.visible_message("[user] unsecures the airlock assembly from the floor.", "You start to unsecure the airlock assembly from the floor.")
else
user.visible_message("[user] secures the airlock assembly to the floor.", "You start to secure the airlock assembly to the floor.")
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * W.toolspeed, target = src))
if(!src) return
- to_chat(user, "\blue You [anchored? "un" : ""]secured the airlock assembly!")
+ to_chat(user, "You [anchored ? "un" : ""]secured the airlock assembly!")
anchored = !anchored
else if(istype(W, /obj/item/stack/cable_coil) && state == 0 && anchored )
var/obj/item/stack/cable_coil/coil = W
user.visible_message("[user] wires the airlock assembly.", "You start to wire the airlock assembly.")
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * coil.toolspeed, target = src))
if(!src) return
coil.use(1)
src.state = 1
- to_chat(user, "\blue You wire the Airlock!")
+ to_chat(user, "You wire the Airlock!")
else if(istype(W, /obj/item/weapon/wirecutters) && state == 1 )
- playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
+ playsound(src.loc, W.usesound, 100, 1)
user.visible_message("[user] cuts the wires from the airlock assembly.", "You start to cut the wires from airlock assembly.")
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * W.toolspeed, target = src))
if(!src) return
- to_chat(user, "\blue You cut the airlock wires.!")
- new/obj/item/stack/cable_coil(src.loc, 1)
+ to_chat(user, "You cut the airlock's wires!")
+ if(state == 1)
+ new/obj/item/stack/cable_coil(src.loc, 1)
src.state = 0
else if(istype(W, /obj/item/weapon/airlock_electronics) && state == 1 && W:icon_state != "door_electronics_smoked")
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1)
+ playsound(src.loc, W.usesound, 100, 1)
user.visible_message("[user] installs the electronics into the airlock assembly.", "You start to install electronics into the airlock assembly.")
user.drop_item()
W.loc = src
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * W.toolspeed, target = src))
if(!src) return
- to_chat(user, "\blue You installed the airlock electronics!")
+ to_chat(user, "You installed the airlock electronics!")
src.state = 2
src.name = "Near finished Airlock Assembly"
src.electronics = W
@@ -240,12 +242,12 @@
W.loc = src.loc
else if(istype(W, /obj/item/weapon/crowbar) && state == 2 )
- playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1)
+ playsound(src.loc, W.usesound, 100, 1)
user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to install electronics into the airlock assembly.")
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * W.toolspeed, target = src))
if(!src) return
- to_chat(user, "\blue You removed the airlock electronics!")
+ to_chat(user, "You removed the airlock electronics!")
src.state = 1
src.name = "Wired Airlock Assembly"
var/obj/item/weapon/airlock_electronics/ae
@@ -260,30 +262,34 @@
var/obj/item/stack/sheet/S = W
if(S)
if(S.amount>=1)
- if(istype(S, /obj/item/stack/sheet/rglass))
- playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1)
+ if(istype(S, /obj/item/stack/sheet/rglass) || istype(S, /obj/item/stack/sheet/glass))
+ playsound(src.loc, S.usesound, 100, 1)
user.visible_message("[user] adds [S.name] to the airlock assembly.", "You start to install [S.name] into the airlock assembly.")
- if(do_after(user, 40, target = src))
- to_chat(user, "\blue You installed reinforced glass windows into the airlock assembly!")
+ if(do_after(user, 40 * S.toolspeed, target = src))
+ if(S.type == /obj/item/stack/sheet/rglass)
+ to_chat(user, "You install reinforced glass windows into the airlock assembly.")
+ heat_proof_finished = 1 //reinforced glass makes the airlock heat-proof
+ else
+ to_chat(user, "You install regular glass windows into the airlock assembly.")
S.use(1)
glass = 1
else if(istype(S, /obj/item/stack/sheet/mineral) && S.sheettype)
var/M = S.sheettype
if(S.amount>=2)
- playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1)
+ playsound(src.loc, S.usesound, 100, 1)
user.visible_message("[user] adds [S.name] to the airlock assembly.", "You start to install [S.name] into the airlock assembly.")
- if(do_after(user, 40, target = src))
- to_chat(user, "\blue You installed [M] plating into the airlock assembly!")
+ if(do_after(user, 40 * S.toolspeed, target = src))
+ to_chat(user, "You installed [M] plating into the airlock assembly!")
S.use(2)
glass = "[M]"
else if(istype(W, /obj/item/weapon/screwdriver) && state == 2 )
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1)
- to_chat(user, "\blue Now finishing the airlock.")
+ playsound(src.loc, W.usesound, 100, 1)
+ to_chat(user, "Now finishing the airlock.")
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * W.toolspeed, target = src))
if(!src) return
- to_chat(user, "\blue You finish the airlock!")
+ to_chat(user, "You finish the airlock!")
var/path
if(istext(glass))
path = text2path("/obj/machinery/door/airlock/[glass]")
@@ -292,8 +298,10 @@
else
path = text2path("/obj/machinery/door/airlock[airlock_type]")
var/obj/machinery/door/airlock/door = new path(src.loc)
+ door.setDir(dir)
door.assembly_type = type
door.electronics = src.electronics
+ door.heat_proof = heat_proof_finished
if(src.electronics.one_access)
door.req_access = null
door.req_one_access = src.electronics.conf_access
@@ -320,4 +328,4 @@
name = "Wired "
if(2)
name = "Near Finished "
- name += "[glass == 1 ? "Window " : ""][istext(glass) ? "[glass] Airlock" : base_name] Assembly"
\ No newline at end of file
+ name += "[heat_proof_finished ? "Heat-Proofed " : ""][glass == 1 ? "Window " : ""][istext(glass) ? "[glass] Airlock" : base_name] Assembly"
diff --git a/code/game/objects/structures/electricchair.dm b/code/game/objects/structures/electricchair.dm
index 7719f9b547d..2995bda23c3 100644
--- a/code/game/objects/structures/electricchair.dm
+++ b/code/game/objects/structures/electricchair.dm
@@ -24,7 +24,7 @@
/obj/structure/stool/bed/chair/e_chair/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/weapon/wrench))
var/obj/structure/stool/bed/chair/C = new /obj/structure/stool/bed/chair(loc)
- playsound(loc, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(loc, W.usesound, 50, 1)
C.dir = dir
part.loc = loc
part.master = null
diff --git a/code/game/objects/structures/engicart.dm b/code/game/objects/structures/engicart.dm
index 742664b68b0..56cb984de8a 100644
--- a/code/game/objects/structures/engicart.dm
+++ b/code/game/objects/structures/engicart.dm
@@ -14,6 +14,17 @@
var/obj/item/weapon/storage/toolbox/emergency/myredtoolbox = null
var/obj/item/taperoll/engineering/myengitape = null
+/obj/structure/engineeringcart/Destroy()
+ QDEL_NULL(myglass)
+ QDEL_NULL(mymetal)
+ QDEL_NULL(myplasteel)
+ QDEL_NULL(myflashlight)
+ QDEL_NULL(mybluetoolbox)
+ QDEL_NULL(myyellowtoolbox)
+ QDEL_NULL(myredtoolbox)
+ QDEL_NULL(myengitape)
+ return ..()
+
/obj/structure/engineeringcart/proc/put_in_cart(obj/item/I, mob/user)
user.drop_item()
I.loc = src
@@ -81,14 +92,14 @@
to_chat(user, fail_msg)
else if(istype(I, /obj/item/weapon/wrench))
if(!anchored && !isinspace())
- playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(src.loc, I.usesound, 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)
+ playsound(src.loc, I.usesound, 50, 1)
user.visible_message( \
"[user] loosens \the [src]'s casters.", \
" You have loosened \the [src]'s casters.", \
diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm
index e5a89aa1fad..a68c387eadb 100644
--- a/code/game/objects/structures/extinguisher.dm
+++ b/code/game/objects/structures/extinguisher.dm
@@ -8,6 +8,9 @@
var/obj/item/weapon/extinguisher/has_extinguisher = new/obj/item/weapon/extinguisher
var/opened = 0
+/obj/structure/extinguisher_cabinet/Destroy()
+ QDEL_NULL(has_extinguisher)
+ return ..()
/obj/structure/extinguisher_cabinet/attackby(obj/item/O, mob/user, params)
if(isrobot(user) || isalien(user))
diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm
index a10d5add7fb..57909ebc6d7 100644
--- a/code/game/objects/structures/false_walls.dm
+++ b/code/game/objects/structures/false_walls.dm
@@ -38,7 +38,14 @@
/obj/structure/falsewall/CanAtmosPass(turf/T)
return !density
+/obj/structure/falsewall/attack_ghost(mob/user)
+ if(user.can_advanced_admin_interact())
+ toggle(user)
+
/obj/structure/falsewall/attack_hand(mob/user)
+ toggle(user)
+
+/obj/structure/falsewall/proc/toggle(mob/user)
if(opening)
return
diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm
index 4d03bfcdb27..ed690192098 100644
--- a/code/game/objects/structures/flora.dm
+++ b/code/game/objects/structures/flora.dm
@@ -314,12 +314,12 @@
if(istype(I, /obj/item/weapon/hatchet) && !stump)
if(indestructable)
//this bush marks the edge of the map, you can't destroy it
- to_chat(user, "\red You flail away at the undergrowth, but it's too thick here.")
+ to_chat(user, "You flail away at the undergrowth, but it's too thick here.")
else
- user.visible_message("[user] begins clearing away [src].","\red You begin clearing away [src].")
+ user.visible_message("[user] begins clearing away [src].","You begin clearing away [src].")
spawn(rand(15,30))
if(get_dist(user,src) < 2)
- to_chat(user, "\blue You clear away [src].")
+ to_chat(user, "You clear away [src].")
var/obj/item/stack/sheet/wood/W = new(src.loc)
W.amount = rand(3,15)
if(prob(50))
diff --git a/code/game/objects/structures/foodcart.dm b/code/game/objects/structures/foodcart.dm
index de103cc5d57..614f4dc27aa 100644
--- a/code/game/objects/structures/foodcart.dm
+++ b/code/game/objects/structures/foodcart.dm
@@ -56,14 +56,14 @@
to_chat(user, fail_msg)
else if(istype(I, /obj/item/weapon/wrench))
if(!anchored && !isinspace())
- playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(src.loc, I.usesound, 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)
+ playsound(src.loc, I.usesound, 50, 1)
user.visible_message( \
"[user] loosens \the [src]'s casters.", \
" You have loosened \the [src]'s casters.", \
diff --git a/code/game/objects/structures/fullwindow.dm b/code/game/objects/structures/fullwindow.dm
index ac6e57a4135..48b2268d8cc 100644
--- a/code/game/objects/structures/fullwindow.dm
+++ b/code/game/objects/structures/fullwindow.dm
@@ -6,7 +6,7 @@
/obj/structure/window/full/CheckExit(atom/movable/O as mob|obj, target as turf)
return 1
-/obj/structure/window/full/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+/obj/structure/window/full/CanPass(atom/movable/mover, turf/target, height=0)
if(istype(mover) && mover.checkpass(PASSGLASS))
return 1
return 0
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index 6051bbebef6..793398a9c07 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -32,63 +32,64 @@
/obj/structure/girder/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/weapon/wrench) && state == 0)
if(anchored && !istype(src,/obj/structure/girder/displaced))
- playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
- to_chat(user, "\blue Now disassembling the girder")
- if(do_after(user,40, target = src))
+ playsound(src.loc, W.usesound, 100, 1)
+ to_chat(user, "Now disassembling the girder")
+ if(do_after(user, 40 * W.toolspeed, target = src))
if(!src) return
- to_chat(user, "\blue You dissasembled the girder!")
+ to_chat(user, "You dissasembled the girder!")
refundMetal(metalUsed)
qdel(src)
else if(!anchored)
- playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
- to_chat(user, "\blue Now securing the girder")
- if(do_after(user, 40, target = src))
- to_chat(user, "\blue You secured the girder!")
+ playsound(src.loc, W.usesound, 100, 1)
+ to_chat(user, "Now securing the girder")
+ if(do_after(user, 40 * W.toolspeed, target = src))
+ to_chat(user, "You secured the girder!")
new/obj/structure/girder( src.loc )
qdel(src)
else if(istype(W, /obj/item/weapon/gun/energy/plasmacutter))
- to_chat(user, "\blue Now slicing apart the girder")
- if(do_after(user,30, target = src))
+ to_chat(user, "Now slicing apart the girder")
+ if(do_after(user, 30 * W.toolspeed, target = src))
if(!src) return
- to_chat(user, "\blue You slice apart the girder!")
+ playsound(loc, W.usesound, 100, 1)
+ to_chat(user, "You slice apart the girder!")
refundMetal(metalUsed)
qdel(src)
else if(istype(W, /obj/item/weapon/pickaxe/drill/diamonddrill))
- to_chat(user, "\blue You drill through the girder!")
+ to_chat(user, "You drill through the girder!")
refundMetal(metalUsed)
qdel(src)
else if(istype(W, /obj/item/weapon/pickaxe/drill/jackhammer))
- playsound(src.loc, 'sound/weapons/sonic_jackhammer.ogg', 100, 1)
+ playsound(src.loc, W.usesound, 100, 1)
to_chat(user, "You Disintegrate the girder!")
refundMetal(metalUsed)
qdel(src)
else if(istype(W, /obj/item/weapon/screwdriver) && state == 2 && istype(src,/obj/structure/girder/reinforced))
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1)
- to_chat(user, "\blue Now unsecuring support struts")
- if(do_after(user,40, target = src))
+ playsound(src.loc, W.usesound, 100, 1)
+ to_chat(user, "Now unsecuring support struts")
+ if(do_after(user, 40 * W.toolspeed, target = src))
if(!src) return
- to_chat(user, "\blue You unsecured the support struts!")
+ to_chat(user, "You unsecured the support struts!")
state = 1
else if(istype(W, /obj/item/weapon/wirecutters) && istype(src,/obj/structure/girder/reinforced) && state == 1)
- playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
- to_chat(user, "\blue Now removing support struts")
- if(do_after(user,40, target = src))
+ playsound(src.loc, W.usesound, 100, 1)
+ to_chat(user, "Now removing support struts")
+ if(do_after(user, 40 * W.toolspeed, target = src))
if(!src) return
- to_chat(user, "\blue You removed the support struts!")
+ to_chat(user, "You removed the support struts!")
new/obj/structure/girder( src.loc )
qdel(src)
else if(istype(W, /obj/item/weapon/crowbar) && state == 0 && anchored )
- playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1)
- to_chat(user, "\blue Now dislodging the girder")
- if(do_after(user, 40, target = src))
+ playsound(src.loc, W.usesound, 100, 1)
+ to_chat(user, "Now dislodging the girder")
+ if(do_after(user, 40 * W.toolspeed, target = src))
if(!src) return
- to_chat(user, "\blue You dislodged the girder!")
+ to_chat(user, "You dislodged the girder!")
new/obj/structure/girder/displaced( src.loc )
qdel(src)
@@ -101,16 +102,16 @@
if(!anchored)
if(S.amount < 2) return
S.use(2)
- to_chat(user, "\blue You create a false wall! Push on it to open or close the passage.")
+ to_chat(user, "You create a false wall! Push on it to open or close the passage.")
new /obj/structure/falsewall (src.loc)
qdel(src)
else
if(S.amount < 2) return ..()
- to_chat(user, "\blue Now adding plating...")
- if(do_after(user,40, target = src))
+ to_chat(user, "Now adding plating...")
+ if(do_after(user, 40 * W.toolspeed, target = src))
if(!src || !S || S.amount < 2) return
S.use(2)
- to_chat(user, "\blue You added the plating!")
+ to_chat(user, "You added the plating!")
var/turf/Tsrc = get_turf(src)
Tsrc.ChangeTurf(/turf/simulated/wall)
for(var/turf/simulated/wall/X in Tsrc.loc)
@@ -122,17 +123,17 @@
if(!anchored)
if(S.amount < 2) return
S.use(2)
- to_chat(user, "\blue You create a false wall! Push on it to open or close the passage.")
+ to_chat(user, "You create a false wall! Push on it to open or close the passage.")
new /obj/structure/falsewall/reinforced (src.loc)
qdel(src)
else
if(src.icon_state == "reinforced") //I cant believe someone would actually write this line of code...
if(S.amount < 1) return ..()
- to_chat(user, "\blue Now finalising reinforced wall.")
+ to_chat(user, "Now finalising reinforced wall.")
if(do_after(user, 50, target = src))
if(!src || !S || S.amount < 1) return
S.use(1)
- to_chat(user, "\blue Wall fully reinforced!")
+ to_chat(user, "Wall fully reinforced!")
var/turf/Tsrc = get_turf(src)
Tsrc.ChangeTurf(/turf/simulated/wall/r_wall)
for(var/turf/simulated/wall/r_wall/X in Tsrc.loc)
@@ -141,11 +142,11 @@
return
else
if(S.amount < 1) return ..()
- to_chat(user, "\blue Now reinforcing girders")
+ to_chat(user, "Now reinforcing girders")
if(do_after(user,60, target = src))
if(!src || !S || S.amount < 1) return
S.use(1)
- to_chat(user, "\blue Girders reinforced!")
+ to_chat(user, "Girders reinforced!")
new/obj/structure/girder/reinforced( src.loc )
qdel(src)
return
@@ -155,17 +156,17 @@
if(!anchored)
if(S.amount < 2) return
S.use(2)
- to_chat(user, "\blue You create a false wall! Push on it to open or close the passage.")
+ to_chat(user, "You create a false wall! Push on it to open or close the passage.")
var/F = text2path("/obj/structure/falsewall/[M]")
new F (src.loc)
qdel(src)
else
if(S.amount < 2) return ..()
- to_chat(user, "\blue Now adding plating...")
+ to_chat(user, "Now adding plating...")
if(do_after(user,40, target = src))
if(!src || !S || S.amount < 2) return
S.use(2)
- to_chat(user, "\blue You added the plating!")
+ to_chat(user, "You added the plating!")
var/turf/Tsrc = get_turf(src)
Tsrc.ChangeTurf(text2path("/turf/simulated/wall/mineral/[M]"))
for(var/turf/simulated/wall/mineral/X in Tsrc.loc)
@@ -180,7 +181,7 @@
if(P.pipe_type in list(0, 1, 5)) //simple pipes, simple bends, and simple manifolds.
user.drop_item()
P.loc = src.loc
- to_chat(user, "\blue You fit the pipe into the [src]!")
+ to_chat(user, "You fit the pipe into the [src]!")
else
..()
@@ -240,20 +241,21 @@
/obj/structure/cultgirder/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/weapon/wrench))
- playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
- to_chat(user, "\blue Now disassembling the girder")
- if(do_after(user,40, target = src))
- to_chat(user, "\blue You dissasembled the girder!")
+ playsound(loc, W.usesound, 100, 1)
+ to_chat(user, "Now disassembling the girder")
+ if(do_after(user, 40 * W.toolspeed, target = src))
+ to_chat(user, "You dissasembled the girder!")
dismantle()
else if(istype(W, /obj/item/weapon/gun/energy/plasmacutter))
- to_chat(user, "\blue Now slicing apart the girder")
- if(do_after(user,30, target = src))
- to_chat(user, "\blue You slice apart the girder!")
+ to_chat(user, "Now slicing apart the girder")
+ if(do_after(user, 30 * W.toolspeed, target = src))
+ playsound(loc, W.usesound, 100, 1)
+ to_chat(user, "You slice apart the girder!")
dismantle()
else if(istype(W, /obj/item/weapon/pickaxe/drill/diamonddrill))
- to_chat(user, "\blue You drill through the girder!")
+ to_chat(user, "You drill through the girder!")
dismantle()
/obj/structure/cultgirder/proc/dismantle()
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index 4cb2b20f99e..df1309b3d03 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -7,11 +7,16 @@
anchored = 1
flags = CONDUCT
pressure_resistance = 5*ONE_ATMOSPHERE
- layer = 2.9
- var/health = 10
- var/destroyed = 0
+ layer = BELOW_OBJ_LAYER
level = 3
-
+ var/health = 10
+ var/broken = 0
+ var/can_deconstruct = TRUE
+ var/rods_type = /obj/item/stack/rods
+ var/rods_amount = 2
+ var/rods_broken = 1
+ var/grille_type = null
+ var/broken_type = /obj/structure/grille/broken
/obj/structure/grille/fence/
var/width = 3
@@ -26,7 +31,6 @@
bound_width = world.icon_size
bound_height = width * world.icon_size
-
/obj/structure/grille/fence/east_west
//width=80
//height=42
@@ -38,19 +42,23 @@
icon='icons/fence-ns.dmi'
/obj/structure/grille/ex_act(severity)
- qdel(src)
+ switch(severity)
+ if(1)
+ qdel(src)
+ else
+ take_damage(rand(5,10), BRUTE, 0)
/obj/structure/grille/blob_act()
- qdel(src)
+ if(!broken)
+ obj_break()
/obj/structure/grille/Bumped(atom/user)
- if(ismob(user)) shock(user, 70)
+ if(ismob(user))
+ shock(user, 70)
-
-/obj/structure/grille/attack_hand(mob/living/user as mob)
+/obj/structure/grille/attack_hand(mob/living/user)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
- playsound(loc, 'sound/effects/grillehit.ogg', 80, 1)
user.visible_message("[user] kicks [src].", \
"You kick [src].", \
"You hear twisting metal.")
@@ -58,26 +66,23 @@
if(shock(user, 70))
return
if(HULK in user.mutations)
- health -= 5
+ take_damage(5)
else
- health -= 1
- healthcheck()
+ take_damage(rand(1,2))
-/obj/structure/grille/attack_alien(mob/living/user as mob)
- if(istype(user, /mob/living/carbon/alien/larva)) return
+/obj/structure/grille/attack_alien(mob/living/user)
+ if(istype(user, /mob/living/carbon/alien/larva))
+ return
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
- playsound(loc, 'sound/effects/grillehit.ogg', 80, 1)
user.visible_message("[user] mangles [src].", \
"You mangle [src].", \
"You hear twisting metal.")
if(!shock(user, 70))
- health -= 5
- healthcheck()
- return
+ take_damage(5)
-/obj/structure/grille/attack_slime(mob/living/user as mob)
+/obj/structure/grille/attack_slime(mob/living/user)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
var/mob/living/carbon/slime/S = user
@@ -89,12 +94,11 @@
"You smash against [src].", \
"You hear twisting metal.")
- health -= rand(2,3)
- healthcheck()
- return
+ take_damage(rand(1,2))
-/obj/structure/grille/attack_animal(var/mob/living/simple_animal/M as mob)
- if(M.melee_damage_upper == 0) return
+/obj/structure/grille/attack_animal(mob/living/simple_animal/M)
+ if(M.melee_damage_upper == 0 || (M.melee_damage_type != BRUTE && M.melee_damage_type != BURN))
+ return
M.changeNext_move(CLICK_CD_MELEE)
M.do_attack_animation(src)
playsound(loc, 'sound/effects/grillehit.ogg', 80, 1)
@@ -102,18 +106,15 @@
"You smash against [src].", \
"You hear twisting metal.")
- health -= M.melee_damage_upper
- healthcheck()
- return
+ take_damage(rand(M.melee_damage_lower,M.melee_damage_upper), M.melee_damage_type)
/obj/structure/grille/mech_melee_attack(obj/mecha/M)
if(..())
- playsound(loc, 'sound/effects/grillehit.ogg', 80, 1)
- health -= M.force * 0.5
- healthcheck()
+ take_damage(M.force * 0.5, M.damtype)
-/obj/structure/grille/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if(air_group || (height==0)) return 1
+/obj/structure/grille/CanPass(atom/movable/mover, turf/target, height=0)
+ if(height==0)
+ return 1
if(istype(mover) && mover.checkpass(PASSGRILLE))
return 1
else
@@ -128,118 +129,144 @@
var/atom/movable/mover = caller
. = . || mover.checkpass(PASSGRILLE)
-/obj/structure/grille/bullet_act(var/obj/item/projectile/Proj)
- if(!Proj)
- return
- ..()
- if((Proj.damage_type != STAMINA)) //Grilles can't be exhausted to death
- src.health -= Proj.damage*0.3
- healthcheck()
- return
+/obj/structure/grille/bullet_act(obj/item/projectile/Proj)
+ . = ..()
+ take_damage(Proj.damage*0.3, Proj.damage_type)
-/obj/structure/grille/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
+/obj/structure/grille/attackby(obj/item/weapon/W, mob/user, params)
user.changeNext_move(CLICK_CD_MELEE)
+ add_fingerprint(user)
if(iswirecutter(W))
if(!shock(user, 100))
- playsound(loc, 'sound/items/Wirecutter.ogg', 100, 1)
- if(!destroyed)
- new /obj/item/stack/rods(loc, 2)
- else
- new /obj/item/stack/rods(loc)
- qdel(src)
+ playsound(loc, W.usesound, 100, 1)
+ deconstruct()
else if((isscrewdriver(W)) && (istype(loc, /turf/simulated) || anchored))
if(!shock(user, 90))
- playsound(loc, 'sound/items/Screwdriver.ogg', 100, 1)
+ playsound(loc, W.usesound, 100, 1)
anchored = !anchored
- user.visible_message("[user] [anchored ? "fastens" : "unfastens"] the grille.", \
- "You have [anchored ? "fastened the grille to" : "unfastened the grill from"] the floor.")
+ user.visible_message("[user] [anchored ? "fastens" : "unfastens"] [src].", \
+ "You [anchored ? "fasten [src] to" : "unfasten [src] from"] the floor.")
+ return
+ else if(istype(W, /obj/item/stack/rods) && broken)
+ var/obj/item/stack/rods/R = W
+ if(!shock(user, 90))
+ user.visible_message("[user] rebuilds the broken grille.", \
+ "You rebuild the broken grille.")
+ new grille_type(loc)
+ R.use(1)
+ qdel(src)
return
//window placing begin
- else if( istype(W,/obj/item/stack/sheet/rglass) || istype(W,/obj/item/stack/sheet/glass) || istype(W,/obj/item/stack/sheet/plasmaglass) || istype(W,/obj/item/stack/sheet/plasmarglass) )
- var/dir_to_set = 1
- if(loc == user.loc)
- dir_to_set = user.dir
- else
- if( ( x == user.x ) || (y == user.y) ) //Only supposed to work for cardinal directions.
- if( x == user.x )
- if( y > user.y )
- dir_to_set = 2
- else
- dir_to_set = 1
- else if( y == user.y )
- if( x > user.x )
- dir_to_set = 8
- else
- dir_to_set = 4
- else
- to_chat(user, "You can't reach.")
- return //Only works for cardinal direcitons, diagonals aren't supposed to work like this.
- for(var/obj/structure/window/WINDOW in loc)
- if(WINDOW.dir == dir_to_set)
- to_chat(user, "There is already a window facing this way there.")
+ else if(istype(W,/obj/item/stack/sheet/rglass) || istype(W,/obj/item/stack/sheet/glass) || istype(W,/obj/item/stack/sheet/plasmaglass) || istype(W,/obj/item/stack/sheet/plasmarglass))
+ if(!broken)
+ var/obj/item/stack/ST = W
+ if (ST.get_amount() < 1)
+ to_chat(user, "You need at least one sheet of glass for that!")
return
- to_chat(user, "You start placing the window.")
- if(do_after(user,20, target = src))
- if(!src) return //Grille destroyed while waiting
+ var/dir_to_set = NORTH
+ if(!anchored)
+ to_chat(user, "[src] needs to be fastened to the floor first!")
+ return
+ if(loc == user.loc)
+ dir_to_set = user.dir
+ else
+ if((x == user.x) || (y == user.y)) //Only supposed to work for cardinal directions.
+ if(x == user.x)
+ if(y > user.y)
+ dir_to_set = SOUTH
+ else
+ dir_to_set = NORTH
+ else if(y == user.y)
+ if(x > user.x)
+ dir_to_set = WEST
+ else
+ dir_to_set = EAST
+ else
+ to_chat(user, "You can't reach.")
+ return //Only works for cardinal direcitons, diagonals aren't supposed to work like this.
for(var/obj/structure/window/WINDOW in loc)
- if(WINDOW.dir == dir_to_set)//checking this for a 2nd time to check if a window was made while we were waiting.
+ if(WINDOW.dir == dir_to_set)
to_chat(user, "There is already a window facing this way there.")
return
- var/obj/structure/window/WD
- if(istype(W,/obj/item/stack/sheet/rglass))
- WD = new/obj/structure/window/reinforced(loc) //reinforced window
- else if(istype(W,/obj/item/stack/sheet/glass))
- WD = new/obj/structure/window/basic(loc) //normal window
- else if(istype(W,/obj/item/stack/sheet/plasmaglass))
- WD = new/obj/structure/window/plasmabasic(loc) //basic plasma window
- else
- WD = new/obj/structure/window/plasmareinforced(loc) //reinforced plasma window
- WD.dir = dir_to_set
- WD.ini_dir = dir_to_set
- WD.anchored = 0
- WD.state = 0
- var/obj/item/stack/ST = W
- ST.use(1)
- to_chat(user, "You place the [WD] on [src].")
- WD.update_icon()
- return
+ to_chat(user, "You start placing the window...")
+ if(do_after(user, 20 * W.toolspeed, target = src))
+ if(!loc || !anchored) //Grille destroyed or unanchored while waiting
+ return
+ for(var/obj/structure/window/WINDOW in loc)
+ if(WINDOW.dir == dir_to_set)//checking this for a 2nd time to check if a window was made while we were waiting.
+ to_chat(user, "There is already a window facing this way there.")
+ return
+ var/obj/structure/window/WD
+ if(istype(W,/obj/item/stack/sheet/rglass))
+ WD = new/obj/structure/window/reinforced(loc) //reinforced window
+ else if(istype(W,/obj/item/stack/sheet/glass))
+ WD = new/obj/structure/window/basic(loc) //normal window
+ else if(istype(W,/obj/item/stack/sheet/plasmaglass))
+ WD = new/obj/structure/window/plasmabasic(loc) //basic plasma window
+ else
+ WD = new/obj/structure/window/plasmareinforced(loc) //reinforced plasma window
+ WD.setDir(dir_to_set)
+ WD.ini_dir = dir_to_set
+ WD.anchored = 0
+ WD.state = 0
+ ST.use(1)
+ to_chat(user, "You place the [WD] on [src].")
+ WD.update_icon()
+ return
//window placing end
+ else if(istype(W, /obj/item/weapon/shard) || !shock(user, 70))
+ return attacked_by(W, user)
- else if(istype(W, /obj/item/weapon/shard))
- health -= W.force * 0.1
- else if(!shock(user, 70))
- playsound(loc, 'sound/effects/grillehit.ogg', 80, 1)
- switch(W.damtype)
- if("fire")
- health -= W.force
- if("brute")
- health -= W.force * 0.1
- healthcheck()
- ..()
- return
+/obj/structure/grille/proc/attacked_by(obj/item/I, mob/living/user)
+ user.changeNext_move(CLICK_CD_MELEE)
+ user.do_attack_animation(src)
+ if(!(I.flags&NOBLUDGEON))
+ if(I.force)
+ visible_message("[user] has hit [src] with [I]!")
+ take_damage(I.force * 0.3, I.damtype)
+/obj/structure/grille/proc/deconstruct(disassembled = TRUE)
+ if(!loc) //if already qdel'd somehow, we do nothing
+ return
+ if(can_deconstruct)
+ var/obj/R = new rods_type(loc, rods_amount)
+ transfer_fingerprints_to(R)
+ qdel(src)
-/obj/structure/grille/proc/healthcheck()
+/obj/structure/grille/proc/obj_break()
+ if(!broken && can_deconstruct)
+ new broken_type(loc)
+ var/obj/R = new rods_type(loc, rods_broken)
+ transfer_fingerprints_to(R)
+ qdel(src)
+
+/obj/structure/grille/proc/take_damage(damage, damage_type = BRUTE, sound_effect = 1)
+ switch(damage_type)
+ if(BURN)
+ if(sound_effect)
+ playsound(loc, 'sound/items/welder.ogg', 80, 1)
+ if(BRUTE)
+ if(sound_effect)
+ if(damage)
+ playsound(loc, 'sound/effects/grillehit.ogg', 80, 1)
+ else
+ playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
+ else
+ return
+ health -= damage
if(health <= 0)
- if(!destroyed)
- icon_state = "brokengrille"
- density = 0
- destroyed = 1
- new /obj/item/stack/rods(loc)
-
+ if(!broken)
+ obj_break()
else
if(health <= -6)
- new /obj/item/stack/rods(loc)
- qdel(src)
- return
- return
+ deconstruct()
// shock user with probability prb (if all connections & power are working)
// returns 1 if shocked, 0 otherwise
-/obj/structure/grille/proc/shock(mob/user as mob, prb)
- if(!anchored || destroyed) // deanchored/destroyed grilles are never connected
+/obj/structure/grille/proc/shock(mob/user, prb)
+ if(!anchored || broken) // unanchored/broken grilles are never connected
return 0
if(!prob(prb))
return 0
@@ -258,8 +285,35 @@
return 0
/obj/structure/grille/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
- if(!destroyed)
+ if(!broken)
if(exposed_temperature > T0C + 1500)
- health -= 1
- healthcheck()
+ take_damage(1)
..()
+
+/obj/structure/grille/hitby(atom/movable/AM)
+ ..()
+ var/tforce = 0
+ if(ismob(AM))
+ tforce = 5
+ else if(isobj(AM))
+ if(prob(50))
+ var/obj/item/I = AM
+ tforce = max(0, I.throwforce * 0.5)
+ else if(anchored && !broken)
+ var/turf/T = get_turf(src)
+ var/obj/structure/cable/C = T.get_cable_node()
+ if(C)
+ playsound(loc, 'sound/magic/LightningShock.ogg', 100, 1, extrarange = 5)
+ tesla_zap(src, 3, C.powernet.avail * 0.01) //Zap for 1/100 of the amount of power. At a million watts in the grid, it will be as powerful as a tesla revolver shot.
+ C.powernet.load += C.powernet.avail * 0.0375 // you can gain up to 3.5 via the 4x upgrades power is halved by the pole so thats 2x then 1X then .5X for 3.5x the 3 bounces shock.
+ take_damage(tforce)
+
+/obj/structure/grille/broken // Pre-broken grilles for map placement
+ icon_state = "brokengrille"
+ density = 0
+ health = 0
+ broken = 1
+ rods_amount = 1
+ rods_broken = 0
+ grille_type = /obj/structure/grille
+ broken_type = null
diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm
index aee81bdf7f8..265d1d1c236 100644
--- a/code/game/objects/structures/inflatable.dm
+++ b/code/game/objects/structures/inflatable.dm
@@ -7,7 +7,7 @@
/obj/item/inflatable/attack_self(mob/user)
playsound(loc, 'sound/items/zip.ogg', 75, 1)
- to_chat(user, "\blue You inflate [src].")
+ to_chat(user, "You inflate [src].")
var/obj/structure/inflatable/R = new /obj/structure/inflatable(user.loc)
src.transfer_fingerprints_to(R)
R.add_fingerprint(user)
@@ -33,7 +33,7 @@
air_update_turf(1)
return ..()
-/obj/structure/inflatable/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+/obj/structure/inflatable/CanPass(atom/movable/mover, turf/target, height=0)
return 0
/obj/structure/inflatable/CanAtmosPass(turf/T)
@@ -150,7 +150,7 @@
/obj/item/inflatable/door/attack_self(mob/user)
playsound(loc, 'sound/items/zip.ogg', 75, 1)
- to_chat(user, "\blue You inflate [src].")
+ to_chat(user, "You inflate [src].")
var/obj/structure/inflatable/door/R = new /obj/structure/inflatable/door(user.loc)
src.transfer_fingerprints_to(R)
R.add_fingerprint(user)
@@ -178,9 +178,7 @@
/obj/structure/inflatable/door/attack_hand(mob/user as mob)
return TryToSwitchState(user)
-/obj/structure/inflatable/door/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if(air_group)
- return state
+/obj/structure/inflatable/door/CanPass(atom/movable/mover, turf/target, height=0)
if(istype(mover, /obj/effect/beam))
return !opacity
return !density
diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm
index c5abbad1c96..f4ee54ad893 100644
--- a/code/game/objects/structures/janicart.dm
+++ b/code/game/objects/structures/janicart.dm
@@ -19,12 +19,16 @@
/obj/structure/janitorialcart/New()
+ ..()
create_reagents(100)
janitorial_equipment += src
-
/obj/structure/janitorialcart/Destroy()
janitorial_equipment -= src
+ QDEL_NULL(mybag)
+ QDEL_NULL(mymop)
+ QDEL_NULL(myspray)
+ QDEL_NULL(myreplacer)
return ..()
/obj/structure/janitorialcart/proc/wet_mop(obj/item/weapon/mop, mob/user)
@@ -85,20 +89,20 @@
to_chat(user, "[src] can't hold any more signs.")
else if(istype(I, /obj/item/weapon/crowbar))
user.visible_message("[user] begins to empty the contents of [src].")
- if(do_after(user, 30, target = src))
+ if(do_after(user, 30 * I.toolspeed, target = src))
to_chat(usr, "You empty the contents of [src]'s bucket onto the floor.")
reagents.reaction(src.loc)
src.reagents.clear_reagents()
else if(istype(I, /obj/item/weapon/wrench))
if(!anchored && !isinspace())
- playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(src.loc, I.usesound, 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)
+ playsound(src.loc, I.usesound, 50, 1)
user.visible_message( \
"[user] loosens \the [src]'s casters.", \
" You have loosened \the [src]'s casters.", \
diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm
index 31ab9c94ca2..043177551ff 100644
--- a/code/game/objects/structures/kitchen_spike.dm
+++ b/code/game/objects/structures/kitchen_spike.dm
@@ -43,8 +43,8 @@
/obj/structure/kitchenspike/attackby(obj/item/weapon/grab/G as obj, mob/user as mob)
if(istype(G, /obj/item/weapon/crowbar))
if(!buckled_mob)
- playsound(loc, 'sound/items/Crowbar.ogg', 100, 1)
- if(do_after(user, 20, target = src))
+ playsound(loc, G.usesound, 100, 1)
+ if(do_after(user, 20 * G.toolspeed, target = src))
to_chat(user, "You pry the spikes out of the frame.")
new /obj/item/stack/rods(loc, 4)
new /obj/structure/kitchenspike_frame(loc)
diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm
index 133a3d15b39..53805b45886 100644
--- a/code/game/objects/structures/ladders.dm
+++ b/code/game/objects/structures/ladders.dm
@@ -76,7 +76,7 @@
return attack_hand(user)
/obj/structure/ladder/dive_point/buoy
- name = "diving point bouy"
+ name = "diving point buoy"
desc = "A buoy marking the location of an underwater dive area."
icon = 'icons/misc/beach.dmi'
icon_state = "buoy"
diff --git a/code/game/objects/structures/lamarr_cage.dm b/code/game/objects/structures/lamarr_cage.dm
index d661fb60b9e..56a60bc651d 100644
--- a/code/game/objects/structures/lamarr_cage.dm
+++ b/code/game/objects/structures/lamarr_cage.dm
@@ -69,10 +69,10 @@
if(src.destroyed)
return
else
- to_chat(usr, text("\blue You kick the lab cage."))
+ to_chat(usr, text("You kick the lab cage."))
for(var/mob/O in oviewers())
if((O.client && !( O.blinded )))
- to_chat(O, text("\red [] kicks the lab cage.", usr))
+ to_chat(O, text("[] kicks the lab cage.", usr))
src.health -= 2
healthcheck()
return
diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm
index bfb607585b0..003daa76645 100644
--- a/code/game/objects/structures/lattice.dm
+++ b/code/game/objects/structures/lattice.dm
@@ -50,7 +50,6 @@
return
/obj/structure/lattice/attackby(obj/item/C as obj, mob/user as mob, params)
-
if(istype(C, /obj/item/stack/tile/plasteel) || istype(C, /obj/item/stack/rods))
var/turf/T = get_turf(src)
T.attackby(C, user) //BubbleWrap - hand this off to the underlying turf instead
@@ -58,11 +57,10 @@
if(istype(C, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = C
if(WT.remove_fuel(0, user))
- to_chat(user, "\blue Slicing lattice joints ...")
- new /obj/item/stack/rods(src.loc)
- qdel(src)
+ to_chat(user, "Slicing lattice joints...")
+ new /obj/item/stack/rods(src.loc)
+ qdel(src)
- return
/obj/structure/lattice/proc/updateOverlays()
//if(!(istype(src.loc, /turf/space)))
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index 824759b35cb..43d08cccee9 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -1,8 +1,6 @@
-//NOT using the existing /obj/machinery/door type, since that has some complications on its own, mainly based on its
-//machineryness
-
+//NOT using the existing /obj/machinery/door type, since that has some complications on its own, mainly based on its machineryness
/obj/structure/mineral_door
- name = "mineral door"
+ name = "metal door"
density = 1
anchored = 1
opacity = 1
@@ -10,16 +8,21 @@
icon = 'icons/obj/doors/mineral_doors.dmi'
icon_state = "metal"
- var/mineralType = "metal"
+ var/initial_state
var/state = 0 //closed, 1 == open
var/isSwitchingStates = 0
+ var/close_delay = -1 //-1 if does not auto close.
+
var/hardness = 1
- var/oreAmount = 7
+ var/sheetType = /obj/item/stack/sheet/metal
+ var/sheetAmount = 7
+ var/openSound = 'sound/effects/stonedoor_openclose.ogg'
+ var/closeSound = 'sound/effects/stonedoor_openclose.ogg'
+ var/damageSound = null
/obj/structure/mineral_door/New(location)
..()
- icon_state = mineralType
- name = "[mineralType] door"
+ initial_state = icon_state
/obj/structure/mineral_door/initialize()
..()
@@ -39,32 +42,38 @@
..()
if(!state)
return TryToSwitchState(user)
- return
-/obj/structure/mineral_door/attack_ai(mob/user as mob) //those aren't machinery, they're just big fucking slabs of a mineral
+/obj/structure/mineral_door/attack_ai(mob/user) //those aren't machinery, they're just big fucking slabs of a mineral
if(isAI(user)) //so the AI can't open it
return
- else if(isrobot(user)) //but cyborgs can
- if(get_dist(user,src) <= 1) //not remotely though
- return TryToSwitchState(user)
+ else if(isrobot(user) && Adjacent(user)) //but cyborgs can, but not remotely
+ return TryToSwitchState(user)
-/obj/structure/mineral_door/attack_hand(mob/user as mob)
+/obj/structure/mineral_door/attack_hand(mob/user)
return TryToSwitchState(user)
-/obj/structure/mineral_door/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if(air_group) return 0
+/obj/structure/mineral_door/attack_animal(mob/user)
+ return TryToSwitchState(user)
+
+/obj/structure/mineral_door/attack_ghost(mob/user)
+ if(user.can_advanced_admin_interact())
+ SwitchState()
+
+/obj/structure/mineral_door/CanPass(atom/movable/mover, turf/target, height = 0)
if(istype(mover, /obj/effect/beam))
return !opacity
return !density
-/obj/structure/mineral_door/CanAtmosPass()
+/obj/structure/mineral_door/CanAtmosPass(turf/T)
return !density
/obj/structure/mineral_door/proc/TryToSwitchState(atom/user)
- if(isSwitchingStates) return
- if(ismob(user))
- var/mob/M = user
- if(world.time - user.last_bumped <= 60) return //NOTE do we really need that?
+ if(isSwitchingStates)
+ return
+ if(isliving(user))
+ var/mob/living/M = user
+ if(world.time - user.last_bumped <= 60)
+ return //NOTE do we really need that?
if(M.client)
if(iscarbon(M))
var/mob/living/carbon/C = M
@@ -83,211 +92,175 @@
/obj/structure/mineral_door/proc/Open()
isSwitchingStates = 1
- playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 100, 1)
- flick("[mineralType]opening",src)
+ playsound(loc, openSound, 100, 1)
+ flick("[initial_state]opening",src)
sleep(10)
density = 0
opacity = 0
state = 1
+ air_update_turf(1)
update_icon()
isSwitchingStates = 0
- air_update_turf(1)
+
+ if(close_delay != -1)
+ spawn(close_delay)
+ Close()
/obj/structure/mineral_door/proc/Close()
+ if(isSwitchingStates || state != 1)
+ return
+ var/turf/T = get_turf(src)
+ for(var/mob/living/L in T)
+ return
isSwitchingStates = 1
- playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 100, 1)
- flick("[mineralType]closing",src)
+ playsound(loc, closeSound, 100, 1)
+ flick("[initial_state]closing",src)
sleep(10)
density = 1
opacity = 1
state = 0
+ air_update_turf(1)
update_icon()
isSwitchingStates = 0
- air_update_turf(1)
/obj/structure/mineral_door/update_icon()
if(state)
- icon_state = "[mineralType]open"
+ icon_state = "[initial_state]open"
else
- icon_state = mineralType
+ icon_state = initial_state
-/obj/structure/mineral_door/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
- if(istype(W,/obj/item/weapon/pickaxe))
+/obj/structure/mineral_door/attackby(obj/item/weapon/W, mob/user, params)
+ if(istype(W, /obj/item/weapon/pickaxe))
var/obj/item/weapon/pickaxe/digTool = W
- to_chat(user, "You start digging the [name].")
- if(do_after(user,digTool.digspeed*hardness, target = src) && src)
- to_chat(user, "You finished digging.")
- Dismantle()
- else if(istype(W,/obj/item/weapon)) //not sure, can't not just weapons get passed to this proc?
- hardness -= W.force/100
- to_chat(user, "You hit the [name] with your [W.name]!")
- CheckHardness()
- else
+ to_chat(user, "You start digging \the [src].")
+ if(do_after(user, digTool.digspeed * hardness, target = src) && src)
+ to_chat(user, "You finished digging.")
+ deconstruct(TRUE)
+ else if(user.a_intent != I_HARM)
attack_hand(user)
- return
+ else
+ attacked_by(W, user)
+
+/obj/structure/mineral_door/proc/attacked_by(obj/item/I, mob/user)
+ if(I.damtype != STAMINA)
+ user.changeNext_move(CLICK_CD_MELEE)
+ user.do_attack_animation(src)
+ visible_message("[user] hits \the [src] with \the [I].")
+ if(damageSound)
+ playsound(loc, damageSound, 100, 1)
+ else
+ playsound(loc, I.hitsound, 100, 1)
+ hardness -= I.force / 100
+ CheckHardness()
/obj/structure/mineral_door/proc/CheckHardness()
if(hardness <= 0)
- Dismantle(1)
+ deconstruct(FALSE)
-/obj/structure/mineral_door/proc/Dismantle(devastated = 0)
- if(!devastated)
- if(mineralType == "metal")
- var/ore = /obj/item/stack/sheet/metal
- for(var/i = 1, i <= oreAmount, i++)
- new ore(get_turf(src))
+/obj/structure/mineral_door/proc/deconstruct(disassembled = TRUE)
+ var/turf/T = get_turf(src)
+ if(sheetType)
+ if(disassembled)
+ new sheetType(T, sheetAmount)
else
- var/ore = text2path("/obj/item/stack/sheet/mineral/[mineralType]")
- for(var/i = 1, i <= oreAmount, i++)
- new ore(get_turf(src))
- else
- if(mineralType == "metal")
- var/ore = /obj/item/stack/sheet/metal
- for(var/i = 3, i <= oreAmount, i++)
- new ore(get_turf(src))
- else
- var/ore = text2path("/obj/item/stack/sheet/mineral/[mineralType]")
- for(var/i = 3, i <= oreAmount, i++)
- new ore(get_turf(src))
+ new sheetType(T, max(sheetAmount - 2, 1))
qdel(src)
/obj/structure/mineral_door/ex_act(severity = 1)
switch(severity)
if(1)
- Dismantle(1)
+ deconstruct(FALSE)
if(2)
if(prob(20))
- Dismantle(1)
+ deconstruct(FALSE)
else
hardness--
CheckHardness()
if(3)
hardness -= 0.1
CheckHardness()
- return
/obj/structure/mineral_door/iron
- mineralType = "metal"
hardness = 3
/obj/structure/mineral_door/silver
- mineralType = "silver"
+ name = "silver door"
+ icon_state = "silver"
+ sheetType = /obj/item/stack/sheet/mineral/silver
hardness = 3
/obj/structure/mineral_door/gold
- mineralType = "gold"
+ name = "gold door"
+ icon_state = "gold"
+ sheetType = /obj/item/stack/sheet/mineral/gold
/obj/structure/mineral_door/uranium
- mineralType = "uranium"
+ name = "uranium door"
+ icon_state = "uranium"
+ sheetType = /obj/item/stack/sheet/mineral/uranium
hardness = 3
light_range = 2
/obj/structure/mineral_door/sandstone
- mineralType = "sandstone"
+ name = "sandstone door"
+ icon_state = "sandstone"
+ sheetType = /obj/item/stack/sheet/mineral/sandstone
hardness = 0.5
/obj/structure/mineral_door/transparent
opacity = 0
- Close()
- ..()
- set_opacity(0)
+/obj/structure/mineral_door/transparent/Close()
+ ..()
+ set_opacity(0)
/obj/structure/mineral_door/transparent/plasma
- mineralType = "plasma"
+ name = "plasma door"
+ icon_state = "plasma"
+ sheetType = /obj/item/stack/sheet/mineral/plasma
- attackby(obj/item/weapon/W as obj, mob/user as mob)
- if(is_hot(W))
- message_admins("Plasma mineral door ignited by [key_name_admin(user)] in ([x],[y],[z] - JMP)",0,1)
- log_game("Plasma mineral door ignited by [key_name(user)] in ([x],[y],[z])")
- TemperatureAct(100)
- ..()
+/obj/structure/mineral_door/transparent/plasma/attackby(obj/item/weapon/W, mob/user)
+ if(is_hot(W))
+ message_admins("Plasma mineral door ignited by [key_name_admin(user)] in ([x], [y], [z] - JMP)", 0, 1)
+ log_game("Plasma mineral door ignited by [key_name(user)] in ([x], [y], [z])")
+ TemperatureAct(100)
+ else
+ return ..()
- temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
- if(exposed_temperature > 300)
- TemperatureAct(exposed_temperature)
+/obj/structure/mineral_door/transparent/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+ if(exposed_temperature > 300)
+ TemperatureAct(exposed_temperature)
- proc/TemperatureAct(temperature)
- atmos_spawn_air(SPAWN_HEAT | SPAWN_TOXINS, 500)
- hardness = 0
- CheckHardness()
+/obj/structure/mineral_door/transparent/plasma/proc/TemperatureAct(temperature)
+ atmos_spawn_air(SPAWN_HEAT | SPAWN_TOXINS, 500)
+ deconstruct(FALSE)
/obj/structure/mineral_door/transparent/diamond
- mineralType = "diamond"
+ name = "diamond door"
+ icon_state = "diamond"
+ sheetType = /obj/item/stack/sheet/mineral/diamond
hardness = 10
/obj/structure/mineral_door/wood
- mineralType = "wood"
+ name = "wood door"
+ icon_state = "wood"
+ openSound = 'sound/effects/doorcreaky.ogg'
+ closeSound = 'sound/effects/doorcreaky.ogg'
+ sheetType = /obj/item/stack/sheet/wood
hardness = 1
burn_state = FLAMMABLE
burntime = 30
- Open()
- isSwitchingStates = 1
- playsound(loc, 'sound/effects/doorcreaky.ogg', 100, 1)
- flick("[mineralType]opening",src)
- sleep(10)
- density = 0
- set_opacity(0)
- state = 1
- update_icon()
- isSwitchingStates = 0
-
- Close()
- isSwitchingStates = 1
- playsound(loc, 'sound/effects/doorcreaky.ogg', 100, 1)
- flick("[mineralType]closing",src)
- sleep(10)
- density = 1
- set_opacity(1)
- state = 0
- update_icon()
- isSwitchingStates = 0
-
- Dismantle(devastated = 0)
- if(!devastated)
- for(var/i = 1, i <= oreAmount, i++)
- new/obj/item/stack/sheet/wood(get_turf(src))
- qdel(src)
-
/obj/structure/mineral_door/resin
- mineralType = "resin"
+ name = "resin door"
+ icon_state = "resin"
hardness = 1.5
- var/close_delay = 100
+ close_delay = 100
+ openSound = 'sound/effects/attackblob.ogg'
+ closeSound = 'sound/effects/attackblob.ogg'
+ damageSound = 'sound/effects/attackblob.ogg'
+ sheetType = null
- TryToSwitchState(atom/user)
- if(isalien(user))
- return ..()
-
- Open()
- isSwitchingStates = 1
- playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
- flick("[mineralType]opening",src)
- sleep(10)
- density = 0
- set_opacity(0)
- state = 1
- update_icon()
- isSwitchingStates = 0
-
- spawn(close_delay)
- if(!isSwitchingStates && state == 1)
- Close()
-
- Close()
- isSwitchingStates = 1
- playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
- flick("[mineralType]closing",src)
- sleep(10)
- density = 1
- set_opacity(1)
- state = 0
- update_icon()
- isSwitchingStates = 0
-
- Dismantle(devastated = 0)
- qdel(src)
-
- CheckHardness()
- playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
- ..()
+/obj/structure/mineral_door/resin/TryToSwitchState(atom/user)
+ if(isalien(user))
+ return ..()
diff --git a/code/game/objects/structures/misc.dm b/code/game/objects/structures/misc.dm
index 1958cead39c..910981974d0 100644
--- a/code/game/objects/structures/misc.dm
+++ b/code/game/objects/structures/misc.dm
@@ -72,4 +72,52 @@
user.forceMove(get_turf(src))
log_admin("[key_name(user)] was incarnated by a respawner machine.")
message_admins("[key_name_admin(user)] was incarnated by a respawner machine.")
- user.incarnate_ghost()
\ No newline at end of file
+ user.incarnate_ghost()
+
+/obj/structure/ghost_beacon
+ name = "ethereal beacon"
+ desc = "A structure that draws ethereal attention when active. Use an empty hand to activate."
+ icon = 'icons/obj/lavaland/artefacts.dmi'
+ icon_state = "anomaly_crystal"
+ anchored = 1
+ density = 1
+ var/active = FALSE
+ var/ghost_alert_delay = 30 SECONDS
+ var/last_ghost_alert
+ var/alert_title = "Ethereal Beacon Active!"
+ var/atom/attack_atom
+
+
+/obj/structure/ghost_beacon/initialize()
+ . = ..()
+ last_ghost_alert = world.time
+ attack_atom = src
+ if(active)
+ processing_objects.Add(src)
+
+/obj/structure/ghost_beacon/Destroy()
+ if(active)
+ processing_objects.Remove(src)
+ attack_atom = null
+ return ..()
+
+/obj/structure/ghost_beacon/attack_ghost(mob/dead/observer/user)
+ if(user.can_advanced_admin_interact())
+ attack_hand(user)
+ else if(attack_atom != src)
+ attack_atom.attack_ghost(user)
+
+/obj/structure/ghost_beacon/attack_hand(mob/user)
+ if(!is_admin(user))
+ return
+ to_chat(user, "You [active ? "disable" : "enable"] \the [src].")
+ if(active)
+ processing_objects.Remove(src)
+ else
+ processing_objects.Add(src)
+ active = !active
+
+/obj/structure/ghost_beacon/process()
+ if(last_ghost_alert + ghost_alert_delay < world.time)
+ notify_ghosts("[src] active in [get_area(src)].", 'sound/effects/ghost2.ogg', title = alert_title, source = attack_atom, action = (attack_atom == src ? NOTIFY_JUMP : NOTIFY_ATTACK))
+ last_ghost_alert = world.time
diff --git a/code/game/objects/structures/mop_bucket.dm b/code/game/objects/structures/mop_bucket.dm
index 49175dfa9e3..3a1ee8490db 100644
--- a/code/game/objects/structures/mop_bucket.dm
+++ b/code/game/objects/structures/mop_bucket.dm
@@ -8,6 +8,7 @@
var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite
/obj/structure/mopbucket/New()
+ ..()
create_reagents(100)
janitorial_equipment += src
@@ -27,10 +28,10 @@
if(istype(W, /obj/item/weapon/mop))
if(src.reagents.total_volume >= 2)
src.reagents.trans_to(W, 2)
- to_chat(user, "\blue You wet the mop")
+ to_chat(user, "You wet the mop")
playsound(src.loc, 'sound/effects/slosh.ogg', 25, 1)
if(src.reagents.total_volume < 1)
- to_chat(user, "\blue Out of water!")
+ to_chat(user, "Out of water!")
return
/obj/structure/mopbucket/ex_act(severity)
diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm
index be81c338c08..39a7ac21301 100644
--- a/code/game/objects/structures/morgue.dm
+++ b/code/game/objects/structures/morgue.dm
@@ -27,6 +27,7 @@
"The tray contains a body that might be responsive."
)
anchored = 1.0
+ var/open_sound = 'sound/items/Deconstruct.ogg'
/obj/structure/morgue/initialize()
. = ..()
@@ -100,11 +101,11 @@
for(var/atom/movable/A as mob|obj in connected.loc)
if(!( A.anchored ))
A.forceMove(src)
- playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(loc, open_sound, 50, 1)
qdel(connected)
connected = null
else
- playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(loc, open_sound, 50, 1)
connected = new /obj/structure/m_tray( loc )
step(connected, dir)
connected.layer = OBJ_LAYER
@@ -159,9 +160,7 @@
return
/obj/structure/morgue/Destroy()
- if(connected)
- qdel(connected)
- connected = null
+ QDEL_NULL(connected)
return ..()
/obj/structure/morgue/container_resist(var/mob/living/L)
@@ -217,7 +216,7 @@
if(user != O)
for(var/mob/B in viewers(user, 3))
if((B.client && !( B.blinded )))
- to_chat(B, text("\red [] stuffs [] into []!", user, O, src))
+ to_chat(B, text("[] stuffs [] into []!", user, O, src))
return
/obj/structure/m_tray/Destroy()
@@ -258,6 +257,7 @@
var/cremating = 0
var/id = 1
var/locked = 0
+ var/open_sound = 'sound/items/Deconstruct.ogg'
/obj/structure/crematorium/proc/update()
if(connected)
@@ -299,17 +299,17 @@
/obj/structure/crematorium/attack_hand(mob/user as mob)
if(cremating)
- to_chat(usr, "\red It's locked.")
+ to_chat(usr, "It's locked.")
return
if((connected) && (locked == 0))
for(var/atom/movable/A as mob|obj in connected.loc)
if(!( A.anchored ))
A.forceMove(src)
- playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(loc, open_sound, 50, 1)
qdel(connected)
connected = null
else if(locked == 0)
- playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(loc, open_sound, 50, 1)
connected = new /obj/structure/c_tray( loc )
step(connected, SOUTH)
connected.layer = OBJ_LAYER
@@ -403,9 +403,7 @@
return
/obj/structure/crematorium/Destroy()
- if(connected)
- qdel(connected)
- connected = null
+ QDEL_NULL(connected)
return ..()
/obj/structure/crematorium/container_resist(var/mob/living/L)
@@ -460,7 +458,7 @@
if(user != O)
for(var/mob/B in viewers(user, 3))
if((B.client && !( B.blinded )))
- to_chat(B, text("\red [] stuffs [] into []!", user, O, src))
+ to_chat(B, text("[] stuffs [] into []!", user, O, src))
//Foreach goto(99)
return
@@ -469,7 +467,7 @@
connected.connected = null
connected = null
return ..()
-
+
// Crematorium switch
/obj/machinery/crema_switch
desc = "Burn baby burn!"
@@ -482,7 +480,7 @@
var/area/area = null
var/otherarea = null
var/id = 1
-
+
/obj/machinery/crema_switch/attack_ghost(mob/user)
if(user.can_advanced_admin_interact())
return attack_hand(user)
diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm
index 9b4059f1d1d..db917ca5588 100644
--- a/code/game/objects/structures/musician.dm
+++ b/code/game/objects/structures/musician.dm
@@ -281,8 +281,7 @@
icon_state = "piano"
/obj/structure/piano/Destroy()
- qdel(song)
- song = null
+ QDEL_NULL(song)
return ..()
/obj/structure/piano/initialize()
@@ -307,18 +306,18 @@
/obj/structure/piano/attackby(obj/item/O as obj, mob/user as mob, params)
if(istype(O, /obj/item/weapon/wrench))
if(!anchored && !isinspace())
- playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(src.loc, O.usesound, 50, 1)
to_chat(user, " You begin to tighten \the [src] to the floor...")
- if(do_after(user, 20, target = src))
+ if(do_after(user, 20 * O.toolspeed, target = src))
user.visible_message( \
"[user] tightens \the [src]'s casters.", \
" You have tightened \the [src]'s casters. Now it can be played again.", \
"You hear ratchet.")
anchored = 1
else if(anchored)
- playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(src.loc, O.usesound, 50, 1)
to_chat(user, " You begin to loosen \the [src]'s casters...")
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * O.toolspeed, target = src))
user.visible_message( \
"[user] loosens \the [src]'s casters.", \
" You have loosened \the [src]. Now it can be pulled somewhere else.", \
diff --git a/code/game/objects/structures/statue.dm b/code/game/objects/structures/statue.dm
deleted file mode 100644
index 094ca2d5774..00000000000
--- a/code/game/objects/structures/statue.dm
+++ /dev/null
@@ -1,32 +0,0 @@
-/obj/structure/snowman
- name = "snowman"
- desc = "Seems someone made a snowman here."
- icon = 'icons/obj/stationobjs.dmi'
- icon_state = "snowman"
- anchored = 1
- density = 1
-
-/obj/structure/kidanstatue
- name = "Obsidian Kidan warrior statue"
- desc = "A beautifully carved and menacing statue of a Kidan warrior made out of obsidian. It looks very heavy."
- icon = 'icons/obj/decorations.dmi'
- icon_state = "kidanstatue"
- anchored = 1
- density = 1
-
-/obj/structure/chickenstatue
- name = "Bronze Chickenman Statue"
- desc = "An antique and oriental-looking statue of a Chickenman made of bronze."
- icon = 'icons/obj/decorations.dmi'
- icon_state = "chickenstatue"
- anchored = 1
- density = 1
-
-
-/obj/structure/clownstatue
- name = "Bananium Clown Statue"
- desc = "A golden statue made of bananium, commemorating the coronation of King Squiggles the Eighth."
- icon = 'icons/obj/decorations.dmi'
- icon_state = "clownstatue"
- anchored = 1
- density = 1
\ No newline at end of file
diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm
new file mode 100644
index 00000000000..6e1ba7eb742
--- /dev/null
+++ b/code/game/objects/structures/statues.dm
@@ -0,0 +1,372 @@
+/obj/structure/statue
+ name = "statue"
+ desc = "Placeholder. Yell at Firecage if you SOMEHOW see this."
+ icon = 'icons/obj/statue.dmi'
+ icon_state = ""
+ density = 1
+ anchored = 0
+ var/hardness = 1
+ var/oreAmount = 5
+ var/material_drop_type = /obj/item/stack/sheet/metal
+
+/obj/structure/statue/attackby(obj/item/weapon/W, mob/living/user, params)
+ add_fingerprint(user)
+ user.changeNext_move(CLICK_CD_MELEE)
+ if(iswrench(W))
+ if(anchored)
+ playsound(loc, W.usesound, 100, 1)
+ user.visible_message("[user] is loosening the [name]'s bolts.", \
+ "You are loosening the [name]'s bolts...")
+ if(do_after(user, 40 * W.toolspeed, target = src))
+ if(!loc || !anchored)
+ return
+ user.visible_message("[user] loosened the [name]'s bolts!", \
+ "You loosen the [name]'s bolts!")
+ anchored = 0
+ else
+ if(!isfloorturf(loc))
+ user.visible_message("A floor must be present to secure the [name]!")
+ return
+ playsound(loc, W.usesound, 100, 1)
+ user.visible_message("[user] is securing the [name]'s bolts...", \
+ "You are securing the [name]'s bolts...")
+ if(do_after(user, 40 * W.toolspeed, target = src))
+ if(!loc || anchored)
+ return
+ user.visible_message("[user] has secured the [name]'s bolts.", \
+ "You have secured the [name]'s bolts.")
+ anchored = 1
+
+ else if(istype(W, /obj/item/weapon/gun/energy/plasmacutter))
+ playsound(src, W.usesound, 100, 1)
+ user.visible_message("[user] is slicing apart the [name]...", \
+ "You are slicing apart the [name]...")
+ if(do_after(user, 40 * W.toolspeed, target = src))
+ if(!loc)
+ return
+ user.visible_message("[user] slices apart the [name].", \
+ "You slice apart the [name].")
+ Dismantle(TRUE)
+
+ else if(istype(W, /obj/item/weapon/pickaxe/drill/jackhammer))
+ var/obj/item/weapon/pickaxe/drill/jackhammer/D = W
+ if(!loc)
+ return
+ user.visible_message("[user] destroys the [name]!", \
+ "You destroy the [name].")
+ D.playDigSound()
+ qdel(src)
+
+ else if(iswelder(W) && !anchored)
+ var/obj/item/weapon/weldingtool/WT = W
+ if(WT.remove_fuel(0, user))
+ playsound(loc, W.usesound, 40, 1)
+ user.visible_message("[user] is slicing apart the [name].", \
+ "You are slicing apart the [name]...")
+ if(do_after(user, 40 * W.toolspeed, target = src))
+ if(!loc)
+ return
+ playsound(loc, W.usesound, 50, 1)
+ user.visible_message("[user] slices apart the [name].", \
+ "You slice apart the [name]!")
+ Dismantle(TRUE)
+ else
+ hardness -= W.force/100
+ ..()
+ CheckHardness()
+ return ..()
+
+/obj/structure/statue/attack_hand(mob/living/user)
+ user.changeNext_move(CLICK_CD_MELEE)
+ add_fingerprint(user)
+ user.visible_message("[user] rubs some dust off from the [name]'s surface.", \
+ "You rub some dust off from the [name]'s surface.")
+
+/obj/structure/statue/CanAtmosPass()
+ return !density
+
+/obj/structure/statue/bullet_act(obj/item/projectile/Proj)
+ hardness -= Proj.damage
+ ..()
+ CheckHardness()
+
+/obj/structure/statue/proc/CheckHardness()
+ if(hardness <= 0)
+ Dismantle(TRUE)
+
+/obj/structure/statue/proc/Dismantle(disassembled = TRUE)
+ if(material_drop_type)
+ var/drop_amt = oreAmount
+ if(!disassembled)
+ drop_amt -= 2
+ if(drop_amt > 0)
+ new material_drop_type(get_turf(src), drop_amt)
+ qdel(src)
+
+/obj/structure/statue/ex_act(severity = 1)
+ switch(severity)
+ if(1)
+ Dismantle(TRUE)
+ if(2)
+ if(prob(20))
+ Dismantle(TRUE)
+ else
+ hardness--
+ CheckHardness()
+ if(3)
+ hardness -= 0.1
+ CheckHardness()
+
+/obj/structure/statue/uranium
+ hardness = 3
+ light_range = 2
+ material_drop_type = /obj/item/stack/sheet/mineral/uranium
+ var/last_event = 0
+ var/active = null
+
+/obj/structure/statue/uranium/nuke
+ name = "statue of a nuclear fission explosive"
+ desc = "This is a grand statue of a Nuclear Explosive. It has a sickening green colour."
+ icon_state = "nuke"
+
+/obj/structure/statue/uranium/eng
+ name = "statue of an engineer"
+ desc = "This statue has a sickening green colour."
+ icon_state = "eng"
+
+/obj/structure/statue/uranium/attackby(obj/item/weapon/W, mob/user, params)
+ radiate()
+ ..()
+
+/obj/structure/statue/uranium/Bumped(atom/user)
+ radiate()
+ ..()
+
+/obj/structure/statue/uranium/attack_hand(mob/user)
+ radiate()
+ ..()
+
+/obj/structure/statue/uranium/proc/radiate()
+ if(!active)
+ if(world.time > last_event+15)
+ active = 1
+ for(var/mob/living/L in range(3,src))
+ L.apply_effect(12,IRRADIATE,0)
+ last_event = world.time
+ active = null
+
+/obj/structure/statue/plasma
+ hardness = 2
+ material_drop_type = /obj/item/stack/sheet/mineral/plasma
+ desc = "This statue is suitably made from plasma."
+
+/obj/structure/statue/plasma/scientist
+ name = "statue of a scientist"
+ icon_state = "sci"
+
+/obj/structure/statue/plasma/xeno
+ name = "statue of a xenomorph"
+ icon_state = "xeno"
+
+/obj/structure/statue/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+ if(exposed_temperature > 300)
+ PlasmaBurn(exposed_temperature)
+
+/obj/structure/statue/plasma/bullet_act(obj/item/projectile/Proj)
+ var/burn = FALSE
+ if(istype(Proj,/obj/item/projectile/beam))
+ PlasmaBurn(2500)
+ burn = TRUE
+ else if(istype(Proj,/obj/item/projectile/ion))
+ PlasmaBurn(500)
+ burn = TRUE
+ if(burn)
+ if(Proj.firer)
+ message_admins("Plasma statue ignited by [key_name_admin(Proj.firer)](?) (FLW) in ([x],[y],[z] - JMP)",0,1)
+ log_game("Plasma statue ignited by [key_name(Proj.firer)] in ([x],[y],[z])")
+ else
+ message_admins("Plasma statue ignited by [Proj]. No known firer.(?) (FLW) in ([x],[y],[z] - JMP)",0,1)
+ log_game("Plasma statue ignited by [Proj] in ([x],[y],[z]). No known firer.")
+ ..()
+
+/obj/structure/statue/plasma/attackby(obj/item/weapon/W, mob/user, params)
+ if(is_hot(W) > 300)//If the temperature of the object is over 300, then ignite
+ message_admins("Plasma statue ignited by [key_name_admin(user)](?) (FLW) in ([x],[y],[z] - JMP)",0,1)
+ log_game("Plasma statue ignited by [key_name(user)] in ([x],[y],[z])")
+ ignite(is_hot(W))
+ return
+ ..()
+
+/obj/structure/statue/plasma/proc/PlasmaBurn()
+ atmos_spawn_air(SPAWN_HEAT | SPAWN_TOXINS, 160)
+ Dismantle(FALSE)
+
+/obj/structure/statue/plasma/proc/ignite(exposed_temperature)
+ if(exposed_temperature > 300)
+ PlasmaBurn()
+
+/obj/structure/statue/gold
+ hardness = 3
+ material_drop_type = /obj/item/stack/sheet/mineral/gold
+ desc = "This is a highly valuable statue made from gold."
+
+/obj/structure/statue/gold/hos
+ name = "statue of the head of security"
+ icon_state = "hos"
+
+/obj/structure/statue/gold/hop
+ name = "statue of the head of personnel"
+ icon_state = "hop"
+
+/obj/structure/statue/gold/cmo
+ name = "statue of the chief medical officer"
+ icon_state = "cmo"
+
+/obj/structure/statue/gold/ce
+ name = "statue of the chief engineer"
+ icon_state = "ce"
+
+/obj/structure/statue/gold/rd
+ name = "statue of the research director"
+ icon_state = "rd"
+
+/obj/structure/statue/silver
+ hardness = 3
+ material_drop_type = /obj/item/stack/sheet/mineral/silver
+ desc = "This is a valuable statue made from silver."
+
+/obj/structure/statue/silver/md
+ name = "statue of a medical doctor"
+ icon_state = "md"
+
+/obj/structure/statue/silver/janitor
+ name = "statue of a janitor"
+ icon_state = "jani"
+
+/obj/structure/statue/silver/sec
+ name = "statue of a security officer"
+ icon_state = "sec"
+
+/obj/structure/statue/silver/secborg
+ name = "statue of a security cyborg"
+ icon_state = "secborg"
+
+/obj/structure/statue/silver/medborg
+ name = "statue of a medical cyborg"
+ icon_state = "medborg"
+
+/obj/structure/statue/diamond
+ hardness = 10
+ material_drop_type = /obj/item/stack/sheet/mineral/diamond
+ desc = "This is a very expensive diamond statue"
+
+/obj/structure/statue/diamond/captain
+ name = "statue of THE captain."
+ icon_state = "cap"
+
+/obj/structure/statue/diamond/ai1
+ name = "statue of the AI hologram."
+ icon_state = "ai1"
+
+/obj/structure/statue/diamond/ai2
+ name = "statue of the AI core."
+ icon_state = "ai2"
+
+/obj/structure/statue/bananium
+ hardness = 3
+ material_drop_type = /obj/item/stack/sheet/mineral/bananium
+ desc = "A bananium statue with a small engraving:'HOOOOOOONK'."
+ var/spam_flag = 0
+
+/obj/structure/statue/bananium/clown
+ name = "statue of a clown"
+ icon_state = "clown"
+
+/obj/structure/statue/bananium/Bumped(atom/user)
+ honk()
+ ..()
+
+/obj/structure/statue/bananium/attackby(obj/item/weapon/W, mob/user, params)
+ honk()
+ ..()
+
+/obj/structure/statue/bananium/attack_hand(mob/user)
+ honk()
+ ..()
+
+/obj/structure/statue/bananium/proc/honk()
+ if(!spam_flag)
+ spam_flag = 1
+ playsound(loc, 'sound/items/bikehorn.ogg', 50, 1)
+ spawn(20)
+ spam_flag = 0
+
+/obj/structure/statue/sandstone
+ hardness = 0.5
+ material_drop_type = /obj/item/stack/sheet/mineral/sandstone
+
+/obj/structure/statue/sandstone/assistant
+ name = "statue of an assistant"
+ desc = "A cheap statue of sandstone for a greyshirt."
+ icon_state = "assist"
+
+/obj/structure/statue/sandstone/venus //call me when we add marble i guess
+ name = "statue of a pure maiden"
+ desc = "An ancient marble statue. The subject is depicted with a floor-length braid and is wielding a toolbox. By Jove, it's easily the most gorgeous depiction of a woman you've ever seen. The artist must truly be a master of his craft. Shame about the broken arm, though."
+ icon = 'icons/obj/statuelarge.dmi'
+ icon_state = "venus"
+
+/*
+/obj/structure/statue/snow
+ hardness = 0.5
+ material_drop_type = /obj/item/stack/sheet/mineral/snow
+
+/obj/structure/statue/snow/snowman
+ name = "snowman"
+ desc = "Several lumps of snow put together to form a snowman."
+ icon_state = "snowman"
+*/
+
+/obj/structure/statue/tranquillite
+ hardness = 0.5
+ material_drop_type = /obj/item/stack/sheet/mineral/tranquillite
+ desc = "..."
+
+/obj/structure/statue/tranquillite/mime
+ name = "statue of a mime"
+ icon_state = "mime"
+
+/obj/structure/statue/tranquillite/mime/AltClick(mob/user)//has 4 dirs
+ if(user.incapacitated())
+ to_chat(user, "You can't do that right now!")
+ return
+ if(!Adjacent(user))
+ return
+ if(anchored)
+ to_chat(user, "It is fastened to the floor!")
+ return
+ setDir(turn(dir, 90))
+////////////////////////////////
+/obj/structure/snowman
+ name = "snowman"
+ desc = "Seems someone made a snowman here."
+ icon = 'icons/obj/stationobjs.dmi'
+ icon_state = "snowman"
+ anchored = 1
+ density = 1
+
+/obj/structure/kidanstatue
+ name = "Obsidian Kidan warrior statue"
+ desc = "A beautifully carved and menacing statue of a Kidan warrior made out of obsidian. It looks very heavy."
+ icon = 'icons/obj/decorations.dmi'
+ icon_state = "kidanstatue"
+ anchored = 1
+ density = 1
+
+/obj/structure/chickenstatue
+ name = "Bronze Chickenman Statue"
+ desc = "An antique and oriental-looking statue of a Chickenman made of bronze."
+ icon = 'icons/obj/decorations.dmi'
+ icon_state = "chickenstatue"
+ anchored = 1
+ density = 1
diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
index c5a3b2f15ba..1835a1bb31a 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
@@ -15,6 +15,7 @@
buckle_lying = 1
burn_state = FLAMMABLE
burntime = 30
+ buildstackamount = 2
var/movable = 0 // For mobility checks
/obj/structure/stool/bed/MouseDrop(atom/over_object)
@@ -24,23 +25,38 @@
name = "psych bed"
desc = "For prime comfort during psychiatric evaluations."
icon_state = "psychbed"
+ buildstackamount = 5
can_buckle = 1
buckle_lying = 1
+/obj/structure/stool/bed/dogbed
+ name = "dog bed"
+ icon_state = "dogbed"
+ desc = "A comfy-looking dog bed. You can even strap your pet in, in case the gravity turns off."
+ anchored = 0
+ buildstackamount = 10
+ buildstacktype = /obj/item/stack/sheet/wood
+
+/obj/structure/stool/bed/dogbed/ian
+ name = "Ian's bed"
+ desc = "Ian's bed! Looks comfy."
+ anchored = 1
+
/obj/structure/stool/bed/alien
name = "resting contraption"
- desc = "This looks similar to contraptions from earth. Could aliens be stealing our technology?"
+ desc = "This looks similar to contraptions from Earth. Could aliens be stealing our technology?"
icon_state = "abed"
/obj/structure/stool/bed/proc/handle_rotation()
return
-/obj/structure/stool/bed/attack_animal(var/mob/living/simple_animal/M)//No more buckling hostile mobs to chairs to render them immobile forever
- if(M.environment_smash)
- new /obj/item/stack/sheet/metal(src.loc)
+/obj/structure/stool/bed/attack_animal(mob/living/simple_animal/user)
+ if(user.environment_smash)
+ user.do_attack_animation(src)
+ visible_message("[user] smashes [src] apart!")
+ new buildstacktype(loc, buildstackamount)
qdel(src)
-
/*
* Roller beds
*/
@@ -56,7 +72,7 @@
if(buckled_mob)
user_unbuckle_mob(user)
else
- user.visible_message("[user] collapses \the [src.name].", "You collapse \the [src.name].")
+ user.visible_message("[user] collapses \the [name].", "You collapse \the [name].")
new/obj/item/roller(get_turf(src))
qdel(src)
return
@@ -72,7 +88,6 @@
M.pixel_x = M.get_standard_pixel_x_offset(M.lying)
M.pixel_y = M.get_standard_pixel_y_offset(M.lying)
-
/obj/item/roller
name = "roller bed"
desc = "A collapsed roller bed that can be carried around."
@@ -80,7 +95,6 @@
icon_state = "folded"
w_class = 4 // Can't be put in backpacks.
-
/obj/item/roller/attack_self(mob/user)
var/obj/structure/stool/bed/roller/R = new /obj/structure/stool/bed/roller(user.loc)
R.add_fingerprint(user)
@@ -90,8 +104,8 @@
if(istype(W, /obj/item/roller_holder))
var/obj/item/roller_holder/RH = W
if(!RH.held)
- user.visible_message("[user] collects \the [src.name].", "You collect \the [src.name].")
- src.forceMove(RH)
+ user.visible_message("[user] collects \the [name].", "You collect \the [name].")
+ forceMove(RH)
RH.held = src
/obj/structure/stool/bed/roller/MouseDrop(over_object, src_location, over_location)
@@ -101,13 +115,11 @@
return
if(buckled_mob)
return 0
- usr.visible_message("[usr] collapses \the [src.name].", "You collapse \the [src.name].")
+ usr.visible_message("[usr] collapses \the [name].", "You collapse \the [name].")
new/obj/item/roller(get_turf(src))
qdel(src)
return
-
-
/obj/item/roller_holder
name = "roller bed rack"
desc = "A rack for carrying a collapsed roller bed."
diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
index e2e287052ff..2b8cdd9e3ba 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
@@ -4,6 +4,7 @@
icon_state = "chair"
buckle_lying = 0 //you sit in a chair, not lay
burn_state = FIRE_PROOF
+ buildstackamount = 1
var/propelled = 0 // Check for fire-extinguisher-driven chairs
@@ -32,7 +33,7 @@
return
user.drop_item()
var/obj/structure/stool/bed/chair/e_chair/E = new /obj/structure/stool/bed/chair/e_chair(src.loc)
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, W.usesound, 50, 1)
E.dir = dir
E.part = SK
SK.loc = E
@@ -60,19 +61,16 @@
set src in oview(1)
if(config.ghost_interaction)
- src.dir = turn(src.dir, 90)
+ setDir(turn(dir, 90))
handle_rotation()
return
- else
- if(!usr || !isturf(usr.loc))
- return
- if(usr.stat || usr.restrained())
- return
- src.dir = turn(src.dir, 90)
- handle_rotation()
+ if(usr.incapacitated())
return
+ setDir(turn(dir, 90))
+ handle_rotation()
+
/obj/structure/stool/bed/chair/AltClick(mob/user)
if(user.incapacitated())
to_chat(user, "You can't do that right now!")
@@ -85,6 +83,8 @@
/obj/structure/stool/bed/chair/wood
burn_state = FLAMMABLE
burntime = 20
+ buildstackamount = 3
+ buildstacktype = /obj/item/stack/sheet/wood
// TODO: Special ash subtype that looks like charred chair legs
/obj/structure/stool/bed/chair/wood/narsie_act()
@@ -100,16 +100,6 @@
name = "wooden chair"
desc = "Old is never too old to not be in fashion."
-/obj/structure/stool/bed/chair/wood/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
- if(istype(W, /obj/item/weapon/wrench))
- playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
- new /obj/item/stack/sheet/wood(get_turf(src))
- new /obj/item/stack/sheet/wood(get_turf(src))
- new /obj/item/stack/sheet/wood(get_turf(src))
- qdel(src)
- else
- ..()
-
/obj/structure/stool/bed/chair/comfy
name = "comfy chair"
desc = "It looks comfy."
@@ -117,6 +107,7 @@
color = rgb(255,255,255)
burn_state = FLAMMABLE
burntime = 30
+ buildstackamount = 2
var/image/armrest = null
/obj/structure/stool/bed/chair/comfy/New()
@@ -161,15 +152,7 @@
/obj/structure/stool/bed/chair/office
anchored = 0
movable = 1
-
-/obj/structure/stool/bed/chair/comfy/attackby(obj/item/weapon/W, mob/user, params)
- if(iswrench(W))
- playsound(loc, 'sound/items/Ratchet.ogg', 50, 1)
- new /obj/item/stack/sheet/metal(get_turf(src))
- new /obj/item/stack/sheet/metal(get_turf(src))
- qdel(src)
- else
- ..()
+ buildstackamount = 5
/obj/structure/stool/bed/chair/office/Bump(atom/A)
..()
@@ -199,11 +182,13 @@
/obj/structure/stool/bed/chair/barber
icon_state = "barber_chair"
+ buildstackamount = 1
/obj/structure/stool/bed/chair/sofa
name = "old ratty sofa"
icon_state = "sofamiddle"
anchored = 1
+ buildstackamount = 1
/obj/structure/stool/bed/chair/sofa/left
icon_state = "sofaend_left"
diff --git a/code/game/objects/structures/stool_bed_chair_nest/stools.dm b/code/game/objects/structures/stool_bed_chair_nest/stools.dm
index da69c025bb8..6de3c88981d 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/stools.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/stools.dm
@@ -4,6 +4,8 @@
icon = 'icons/obj/objects.dmi'
icon_state = "stool"
anchored = 1.0
+ var/buildstackamount = 1
+ var/buildstacktype = /obj/item/stack/sheet/metal
/obj/structure/stool/ex_act(severity)
switch(severity)
@@ -12,27 +14,26 @@
return
if(2.0)
if(prob(70))
- new /obj/item/stack/sheet/metal(src.loc)
+ new buildstacktype(loc, buildstackamount)
qdel(src)
return
if(3.0)
if(prob(50))
- new /obj/item/stack/sheet/metal(src.loc)
+ new buildstacktype(loc, buildstackamount)
qdel(src)
return
return
/obj/structure/stool/blob_act()
if(prob(75))
- new /obj/item/stack/sheet/metal(src.loc)
+ new buildstacktype(loc, buildstackamount)
qdel(src)
/obj/structure/stool/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/weapon/wrench))
- playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
- new /obj/item/stack/sheet/metal(src.loc)
+ playsound(loc, W.usesound, 50, 1)
+ new buildstacktype(loc, buildstackamount)
qdel(src)
- return
/obj/structure/stool/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params, skip_fucking_stool_shit = 0)
if(skip_fucking_stool_shit)
@@ -42,7 +43,7 @@
if(H==usr && !H.restrained() && !H.stat && in_range(src, over_object))
var/obj/item/weapon/stool/S = new/obj/item/weapon/stool()
S.origin = src
- src.loc = S
+ loc = S
H.put_in_hands(S)
H.visible_message("[H] grabs [src] from the floor!", "You grab [src] from the floor!")
diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
index 54540ab008b..b32f47520e4 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
@@ -1,6 +1,7 @@
/obj/structure/stool/bed/chair/wheelchair
name = "wheelchair"
desc = "You sit in this. Either by will or force."
+ icon = 'icons/obj/objects.dmi'
icon_state = "wheelchair"
anchored = 0
movable = 1
@@ -9,7 +10,7 @@
/obj/structure/stool/bed/chair/wheelchair/handle_rotation()
overlays = null
- var/image/O = image(icon = 'icons/obj/objects.dmi', icon_state = "w_overlay", layer = FLY_LAYER, dir = src.dir)
+ var/image/O = image(icon = icon, icon_state = "[icon_state]_overlay", layer = FLY_LAYER, dir = src.dir)
overlays += O
if(buckled_mob)
buckled_mob.dir = dir
@@ -152,10 +153,3 @@
else
. = 1
-
-/obj/structure/stool/bed/chair/wheelchair/bike/handle_rotation()
- overlays = null
- var/image/O = image(icon = 'icons/vehicles/motorcycle.dmi', icon_state = "motorcycle_overlay_4d", layer = FLY_LAYER, dir = src.dir)
- overlays += O
- if(buckled_mob)
- buckled_mob.dir = dir
\ No newline at end of file
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index ae9e6b41d05..76dc6a507a3 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -126,8 +126,8 @@
/obj/structure/table/attack_tk() // no telehulk sorry
return
-/obj/structure/table/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if(air_group || (height==0)) return 1
+/obj/structure/table/CanPass(atom/movable/mover, turf/target, height=0)
+ if(height==0) return 1
if(istype(mover,/obj/item/projectile))
return (check_cover(mover,target))
if(ismob(mover))
@@ -227,9 +227,9 @@
if(istype(W, /obj/item/weapon/wrench))
user.visible_message("[user] is disassembling \a [src].", "You start disassembling \the [src].")
- playsound(loc, 'sound/items/Ratchet.ogg', 50, 1)
- if(do_after(user, 50, target = src))
- playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(loc, W.usesound, 50, 1)
+ if(do_after(user, 50 * W.toolspeed, target = src))
+ playsound(loc, W.usesound, 50, 1)
destroy()
return
@@ -240,10 +240,10 @@
var/datum/effect/system/spark_spread/spark_system = new /datum/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, W.usesound, 50, 1)
playsound(src.loc, "sparks", 50, 1)
for(var/mob/O in viewers(user, 4))
- O.show_message("\blue The [src] was sliced apart by [user]!", 1, "\red You hear [src] coming apart.", 2)
+ O.show_message("The [src] was sliced apart by [user]!", 1, "You hear [src] coming apart.", 2)
destroy()
return
@@ -421,10 +421,10 @@
var/obj/item/stack/sheet/glass/G = I
if(G.amount >= 2)
to_chat(user, "You start to add the glass to \the [src].")
- if(do_after(user, 10, target = src))
+ if(do_after(user, 10 * G.toolspeed, target = src))
G.use(2)
to_chat(user, "You add the glass to \the [src].")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src), G.usesound, 50, 1)
new /obj/structure/table/glass(loc)
qdel(src)
else
@@ -433,9 +433,9 @@
if(iswrench(I))
to_chat(user, "You start to deconstruct \the [src].")
- playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
- if(do_after(user, 10, target = src))
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 75, 1)
+ playsound(src.loc, I.usesound, 75, 1)
+ if(do_after(user, 10 * I.toolspeed, target = src))
+ playsound(src.loc, I.usesound, 75, 1)
to_chat(user, "You dismantle \the [src].")
new /obj/item/stack/sheet/metal(loc)
new /obj/item/stack/sheet/metal(loc)
@@ -494,18 +494,18 @@
var/obj/item/weapon/weldingtool/WT = W
if(WT.remove_fuel(0, user))
if(src.status == 2)
- to_chat(user, "\blue Now weakening the reinforced table")
- playsound(src.loc, 'sound/items/Welder.ogg', 50, 1)
- if(do_after(user, 50, target = src))
+ to_chat(user, "Now weakening the reinforced table")
+ playsound(src.loc, WT.usesound, 50, 1)
+ if(do_after(user, 50 * WT.toolspeed, target = src))
if(!src || !WT.isOn()) return
- to_chat(user, "\blue Table weakened")
+ to_chat(user, "Table weakened")
src.status = 1
else
- to_chat(user, "\blue Now strengthening the reinforced table")
- playsound(src.loc, 'sound/items/Welder.ogg', 50, 1)
- if(do_after(user, 50, target = src))
+ to_chat(user, "Now strengthening the reinforced table")
+ playsound(src.loc, WT.usesound, 50, 1)
+ if(do_after(user, 50 * WT.toolspeed, target = src))
if(!src || !WT.isOn()) return
- to_chat(user, "\blue Table strengthened")
+ to_chat(user, "Table strengthened")
src.status = 2
return
return
@@ -557,8 +557,8 @@
qdel(src)
return
-/obj/structure/rack/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if(air_group || (height==0)) return 1
+/obj/structure/rack/CanPass(atom/movable/mover, turf/target, height=0)
+ if(height==0) return 1
if(src.density == 0) //Because broken racks -Agouri |TODO: SPRITE!|
return 1
if(istype(mover) && mover.checkpass(PASSTABLE))
@@ -586,7 +586,7 @@
/obj/structure/rack/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/weapon/wrench))
new /obj/item/weapon/rack_parts( src.loc )
- playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(src.loc, W.usesound, 50, 1)
qdel(src)
return
if(isrobot(user))
diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm
index 8d0962857f5..fb176ce9dba 100644
--- a/code/game/objects/structures/tank_dispenser.dm
+++ b/code/game/objects/structures/tank_dispenser.dm
@@ -10,18 +10,16 @@
var/list/oxytanks = list() //sorry for the similar var names
var/list/platanks = list()
-
/obj/structure/dispenser/oxygen
plasmatanks = 0
/obj/structure/dispenser/plasma
oxygentanks = 0
-
/obj/structure/dispenser/New()
+ ..()
update_icon()
-
/obj/structure/dispenser/update_icon()
overlays.Cut()
switch(oxygentanks)
@@ -31,40 +29,51 @@
if(1 to 4) overlays += "plasma-[plasmatanks]"
if(5 to INFINITY) overlays += "plasma-5"
+/obj/structure/dispenser/attack_hand(mob/user)
+ if(..())
+ return 1
+ add_fingerprint(user)
+ ui_interact(user)
-/obj/structure/dispenser/attack_hand(mob/user as mob)
+/obj/structure/dispenser/attack_ghost(mob/user)
+ ui_interact(user)
+
+/obj/structure/dispenser/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state)
user.set_machine(src)
- var/dat = "[src]
"
- dat += "Oxygen tanks: [oxygentanks] - [oxygentanks ? "Dispense" : "empty"] "
- dat += "Plasma tanks: [plasmatanks] - [plasmatanks ? "Dispense" : "empty"]"
- user << browse(dat, "window=dispenser")
- onclose(user, "dispenser")
- return
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "tank_dispenser.tmpl", name, 275, 100, state = state)
+ ui.open()
+/obj/structure/dispenser/ui_data(user)
+ var/list/data = list()
+ data["o_tanks"] = oxygentanks
+ data["p_tanks"] = plasmatanks
+ return data
-/obj/structure/dispenser/attackby(obj/item/I as obj, mob/user as mob, params)
+/obj/structure/dispenser/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/tank/oxygen) || istype(I, /obj/item/weapon/tank/air) || istype(I, /obj/item/weapon/tank/anesthetic))
if(oxygentanks < 10)
user.drop_item()
- I.loc = src
+ I.forceMove(src)
oxytanks.Add(I)
oxygentanks++
+ update_icon()
to_chat(user, "You put [I] in [src].")
else
to_chat(user, "[src] is full.")
- updateUsrDialog()
- return
+ nanomanager.update_uis(src)
if(istype(I, /obj/item/weapon/tank/plasma))
if(plasmatanks < 10)
user.drop_item()
- I.loc = src
+ I.forceMove(src)
platanks.Add(I)
plasmatanks++
+ update_icon()
to_chat(user, "You put [I] in [src].")
else
to_chat(user, "[src] is full.")
- updateUsrDialog()
- return
+ nanomanager.update_uis(src)
if(istype(I, /obj/item/weapon/wrench))
if(anchored)
to_chat(user, "You lean down and unwrench [src].")
@@ -72,11 +81,11 @@
else
to_chat(user, "You wrench [src] into place.")
anchored = 1
- return
/obj/structure/dispenser/Topic(href, href_list)
- if(usr.stat || usr.restrained())
- return
+ if(..())
+ return 1
+
if(Adjacent(usr))
usr.set_machine(src)
if(href_list["oxygen"])
@@ -105,7 +114,7 @@
update_icon()
add_fingerprint(usr)
updateUsrDialog()
+ nanomanager.update_uis(src)
else
- usr << browse(null, "window=dispenser")
- return
- return
\ No newline at end of file
+ nanomanager.close_user_uis(usr,src)
+ return 1
diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm
index 504b2abfa80..a51f58e5ec6 100644
--- a/code/game/objects/structures/target_stake.dm
+++ b/code/game/objects/structures/target_stake.dm
@@ -8,45 +8,48 @@
flags = CONDUCT
var/obj/item/target/pinned_target // the current pinned target
- Move()
- ..()
- // Move the pinned target along with the stake
- if(pinned_target in view(3, src))
- pinned_target.loc = loc
+/obj/structure/target_stake/Destroy()
+ QDEL_NULL(pinned_target)
+ return ..()
- else // Sanity check: if the pinned target can't be found in immediate view
- pinned_target = null
- density = 1
+/obj/structure/target_stake/Move()
+ ..()
+ // Move the pinned target along with the stake
+ if(pinned_target in view(3, src))
+ pinned_target.loc = loc
- attackby(obj/item/W as obj, mob/user as mob, params)
- // Putting objects on the stake. Most importantly, targets
- if(pinned_target)
- return // get rid of that pinned target first!
+ else // Sanity check: if the pinned target can't be found in immediate view
+ pinned_target = null
+ density = 1
- if(istype(W, /obj/item/target))
- density = 0
- W.density = 1
- user.drop_item(src)
- W.loc = loc
- W.layer = 3.1
- pinned_target = W
- to_chat(user, "You slide the target into the stake.")
- return
+/obj/structure/target_stake/attackby(obj/item/W, mob/user, params)
+ // Putting objects on the stake. Most importantly, targets
+ if(pinned_target)
+ return // get rid of that pinned target first!
- attack_hand(mob/user as mob)
- // taking pinned targets off!
- if(pinned_target)
- density = 1
- pinned_target.density = 0
- pinned_target.layer = OBJ_LAYER
+ if(istype(W, /obj/item/target))
+ density = 0
+ W.density = 1
+ user.drop_item(src)
+ W.loc = loc
+ W.layer = 3.1
+ pinned_target = W
+ to_chat(user, "You slide the target into the stake.")
- pinned_target.loc = user.loc
- if(ishuman(user))
- if(!user.get_active_hand())
- user.put_in_hands(pinned_target)
- to_chat(user, "You take the target out of the stake.")
- else
- pinned_target.loc = get_turf(user)
+/obj/structure/target_stake/attack_hand(mob/user)
+ // taking pinned targets off!
+ if(pinned_target)
+ density = 1
+ pinned_target.density = 0
+ pinned_target.layer = OBJ_LAYER
+
+ pinned_target.loc = user.loc
+ if(ishuman(user))
+ if(!user.get_active_hand())
+ user.put_in_hands(pinned_target)
to_chat(user, "You take the target out of the stake.")
+ else
+ pinned_target.loc = get_turf(user)
+ to_chat(user, "You take the target out of the stake.")
- pinned_target = null
\ No newline at end of file
+ pinned_target = null
\ No newline at end of file
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index bbbecf6695d..fa59fdc3cd1 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -14,9 +14,13 @@
/obj/structure/toilet/New()
+ ..()
open = round(rand(0, 1))
update_icon()
+/obj/structure/toilet/Destroy()
+ swirlie = null
+ return ..()
/obj/structure/toilet/attack_hand(mob/living/user)
if(swirlie)
@@ -52,7 +56,7 @@
if(istype(I, /obj/item/weapon/crowbar))
to_chat(user, "You start to [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"]...")
playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 50, 1)
- if(do_after(user, 30, target = src))
+ if(do_after(user, 30 * I.toolspeed, target = src))
user.visible_message("[user] [cistern ? "replaces the lid on the cistern" : "lifts the lid off the cistern"]!", "You [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"]!", "You hear grinding porcelain.")
cistern = !cistern
update_icon()
diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm
index 4e41daef289..0c273e7f1fa 100644
--- a/code/game/objects/structures/windoor_assembly.dm
+++ b/code/game/objects/structures/windoor_assembly.dm
@@ -34,6 +34,7 @@ obj/structure/windoor_assembly/New(dir=NORTH)
obj/structure/windoor_assembly/Destroy()
density = 0
+ QDEL_NULL(electronics)
air_update_turf(1)
return ..()
@@ -45,11 +46,10 @@ obj/structure/windoor_assembly/Destroy()
/obj/structure/windoor_assembly/update_icon()
icon_state = "[facing]_[secure ? "secure_" : ""]windoor_assembly[state]"
-/obj/structure/windoor_assembly/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+/obj/structure/windoor_assembly/CanPass(atom/movable/mover, turf/target, height=0)
if(istype(mover) && mover.checkpass(PASSGLASS))
return 1
if(get_dir(loc, target) == dir) //Make sure looking at appropriate border
- if(air_group) return 0
return !density
else
return 1
@@ -78,9 +78,9 @@ obj/structure/windoor_assembly/Destroy()
var/obj/item/weapon/weldingtool/WT = W
if(WT.remove_fuel(0,user))
user.visible_message("[user] dissassembles the windoor assembly.", "You start to dissassemble the windoor assembly.")
- playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(src.loc, WT.usesound, 50, 1)
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * WT.toolspeed, target = src))
if(!src || !WT.isOn()) return
to_chat(user, "You dissasembled the windoor assembly!")
var/obj/item/stack/sheet/rglass/RG = new (get_turf(src), 5)
@@ -98,10 +98,10 @@ obj/structure/windoor_assembly/Destroy()
if(WD.dir == src.dir)
to_chat(user, "There is already a windoor in that location.")
return
- playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
+ playsound(src.loc, W.usesound, 100, 1)
user.visible_message("[user] secures the windoor assembly to the floor.", "You start to secure the windoor assembly to the floor.")
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * W.toolspeed, target = src))
if(!src || src.anchored)
return
for(var/obj/machinery/door/window/WD in src.loc)
@@ -117,10 +117,10 @@ obj/structure/windoor_assembly/Destroy()
//Unwrenching an unsecure assembly un-anchors it. Step 4 undone
else if(istype(W, /obj/item/weapon/wrench) && anchored)
- playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
+ playsound(loc, W.usesound, 100, 1)
user.visible_message("[user] unsecures the windoor assembly to the floor.", "You start to unsecure the windoor assembly to the floor.")
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * W.toolspeed, target = src))
if(!src || !src.anchored)
return
to_chat(user, "You've unsecured the windoor assembly!")
@@ -138,9 +138,10 @@ obj/structure/windoor_assembly/Destroy()
return
to_chat(user, "You start to reinforce the windoor with plasteel.")
- if(do_after(user,40, target = src))
+ if(do_after(user, 40 * P.toolspeed, target = src))
if(!src || secure)
return
+ playsound(loc, P.usesound, 100, 1)
P.use(2)
to_chat(user, "You reinforce the windoor.")
@@ -154,12 +155,13 @@ obj/structure/windoor_assembly/Destroy()
else if(istype(W, /obj/item/stack/cable_coil) && anchored)
user.visible_message("[user] wires the windoor assembly.", "You start to wire the windoor assembly.")
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * W.toolspeed, target = src))
if(!src || !src.anchored || src.state != "01")
return
var/obj/item/stack/cable_coil/CC = W
CC.use(1)
to_chat(user, "You wire the windoor!")
+ playsound(loc, CC.usesound, 100, 1)
src.state = "02"
if(src.secure)
src.name = "secure wired windoor assembly"
@@ -172,10 +174,10 @@ obj/structure/windoor_assembly/Destroy()
//Removing wire from the assembly. Step 5 undone.
if(istype(W, /obj/item/weapon/wirecutters))
- playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
+ playsound(src.loc, W.usesound, 100, 1)
user.visible_message("[user] cuts the wires from the airlock assembly.", "You start to cut the wires from airlock assembly.")
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * W.toolspeed, target = src))
if(!src || src.state != "02")
return
@@ -189,12 +191,12 @@ obj/structure/windoor_assembly/Destroy()
//Adding airlock electronics for access. Step 6 complete.
else if(istype(W, /obj/item/weapon/airlock_electronics))
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1)
+ playsound(src.loc, W.usesound, 100, 1)
user.visible_message("[user] installs the electronics into the airlock assembly.", "You start to install electronics into the airlock assembly.")
user.drop_item()
W.loc = src
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * W.toolspeed, target = src))
if(!src || src.electronics)
W.loc = src.loc
return
@@ -209,10 +211,10 @@ obj/structure/windoor_assembly/Destroy()
if(!electronics)
return
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1)
+ playsound(src.loc, W.usesound, 100, 1)
user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to uninstall electronics from the airlock assembly.")
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * W.toolspeed, target = src))
if(!src || !electronics)
return
to_chat(user, "You've removed the airlock electronics!")
@@ -239,10 +241,10 @@ obj/structure/windoor_assembly/Destroy()
to_chat(usr, "The assembly is missing electronics.")
return
usr << browse(null, "window=windoor_access")
- playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1)
+ playsound(src.loc, W.usesound, 100, 1)
user.visible_message("[user] pries the windoor into the frame.", "You start prying the windoor into the frame.")
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * W.toolspeed, target = src))
if(src.loc && src.electronics)
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 22331e4f484..c74e2b47861 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -90,7 +90,7 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f
return !density
return 1
-/obj/structure/window/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+/obj/structure/window/CanPass(atom/movable/mover, turf/target, height=0)
if(istype(mover) && mover.checkpass(PASSGLASS))
return 1
if(dir == SOUTHWEST || dir == SOUTHEAST || dir == NORTHWEST || dir == NORTHEAST)
@@ -108,21 +108,22 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f
return 1
-/obj/structure/window/hitby(AM as mob|obj)
- ..()
- var/tforce = 0
- if(isobj(AM))
- var/obj/item/I = AM
- tforce = I.throwforce
- if(reinf) tforce *= 0.25
- playsound(loc, 'sound/effects/Glasshit.ogg', 100, 1)
- health = max(0, health - tforce)
- if(health <= 7 && !reinf)
- anchored = 0
- update_nearby_icons()
- step(src, get_dir(AM, src))
- if(health <= 0)
- destroy()
+/obj/structure/window/hitby(atom/movable/AM)
+ if(!CanPass(AM, get_step(src, AM.dir))) //So thrown objects that cross a tile with non-full windows will no longer hit the window even if it isn't visually obstructing the path.
+ ..()
+ var/tforce = 0
+ if(isobj(AM))
+ var/obj/item/I = AM
+ tforce = I.throwforce
+ if(reinf) tforce *= 0.25
+ playsound(loc, 'sound/effects/Glasshit.ogg', 100, 1)
+ health = max(0, health - tforce)
+ if(health <= 7 && !reinf)
+ anchored = 0
+ update_nearby_icons()
+ step(src, get_dir(AM, src))
+ if(health <= 0)
+ destroy()
/obj/structure/window/attack_hand(mob/user as mob)
@@ -133,8 +134,8 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f
else if(user.a_intent == I_HARM)
user.changeNext_move(CLICK_CD_MELEE)
playsound(get_turf(src), 'sound/effects/glassknock.ogg', 80, 1)
- user.visible_message("\red [user.name] bangs against the [src.name]!", \
- "\red You bang against the [src.name]!", \
+ user.visible_message("[user.name] bangs against the [src.name]!", \
+ "You bang against the [src.name]!", \
"You hear a banging sound.")
else
user.changeNext_move(CLICK_CD_MELEE)
@@ -212,24 +213,24 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f
if(istype(W, /obj/item/weapon/screwdriver))
if(reinf && state >= 1)
state = 3 - state
- playsound(loc, 'sound/items/Screwdriver.ogg', 75, 1)
+ playsound(loc, W.usesound, 75, 1)
to_chat(user, (state == 1 ? "You have unfastened the window from the frame." : "You have fastened the window to the frame."))
else if(reinf && state == 0)
anchored = !anchored
update_nearby_icons()
- playsound(loc, 'sound/items/Screwdriver.ogg', 75, 1)
+ playsound(loc, W.usesound, 75, 1)
to_chat(user, (anchored ? "You have fastened the frame to the floor." : "You have unfastened the frame from the floor."))
else if(!reinf)
anchored = !anchored
update_nearby_icons()
- playsound(loc, 'sound/items/Screwdriver.ogg', 75, 1)
+ playsound(loc, W.usesound, 75, 1)
to_chat(user, (anchored ? "You have fastened the window to the floor." : "You have unfastened the window."))
else if(istype(W, /obj/item/weapon/crowbar) && reinf && state <= 1)
state = 1 - state
- playsound(loc, 'sound/items/Crowbar.ogg', 75, 1)
+ playsound(loc, W.usesound, 75, 1)
to_chat(user, (state ? "You have pried the window into the frame." : "You have pried the window out of the frame."))
else if(istype(W, /obj/item/weapon/wrench) && !anchored && health > 7) //Disassemble deconstructed window into parts
- playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(src.loc, W.usesound, 50, 1)
for(var/i=0;iThe game hasn't started yet!")
return
if(ticker.current_state == 1)
- to_chat(usr, "\red The round hasn't started yet!")
+ to_chat(usr, "The round hasn't started yet!")
return
if(send_emergency_team)
- to_chat(usr, "\red Central Command has already dispatched an emergency response team!")
+ to_chat(usr, "Central Command has already dispatched an emergency response team!")
return
if(alert("Do you want to dispatch an Emergency Response Team?",,"Yes","No") != "Yes")
@@ -43,7 +43,7 @@ var/ert_request_answered = 0
return
if(send_emergency_team)
- to_chat(usr, "\red Central Command has already dispatched an emergency response team!")
+ to_chat(usr, "Central Command has already dispatched an emergency response team!")
return
var/ert_type = pick_ert_type()
@@ -160,6 +160,8 @@ var/ert_request_answered = 0
M.set_species("Human",1)
M.dna.ready_dna(M)
+ M.reagents.add_reagent("mutadone", 1) //No fat/blind/colourblind/epileptic/whatever ERT.
+ M.overeatduration = 0
var/hair_c = pick("#8B4513","#000000","#FF4500","#FFD700") // Brown, black, red, blonde
var/eye_c = pick("#000000","#8B4513","1E90FF") // Black, brown, blue
@@ -204,6 +206,11 @@ var/ert_request_answered = 0
var/medical_slots = 3
var/security_slots = 3
+ var/command_outfit
+ var/engineering_outfit
+ var/medical_outfit
+ var/security_outfit
+
/datum/response_team/proc/get_slot_list()
var/list/slots_available = list()
if(command_slots)
@@ -230,83 +237,20 @@ var/ert_request_answered = 0
return 0
/datum/response_team/proc/equip_officer(var/officer_type, var/mob/living/carbon/human/M)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset/ert/alt(src), slot_l_ear)
-
- var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(M)
- L.imp_in = M
- L.implanted = 1
- M.sec_hud_set_implants()
-
switch(officer_type)
if("Engineer")
engineer_slots -= 1
- M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/engineer(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/ert/engineer(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/responseteam(M), slot_in_backpack)
-
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full/multitool(M), slot_belt)
-
- var/obj/item/weapon/card/id/W = new(src)
- W.assignment = "Emergency Response Team Member"
- W.registered_name = M.real_name
- W.name = "[M.real_name]'s ID Card (Emergency Response Team Engineer)"
- W.icon_state = "ERT_engineering"
- W.access = get_centcom_access(W.assignment)
- M.equip_to_slot_or_del(W, slot_wear_id)
-
- var/obj/item/device/pda/heads/pda = new(src)
- pda.owner = M.real_name
- pda.ownjob = "Emergency Response Team Member"
- pda.name = "PDA-[M.real_name] ([pda.ownjob])"
- pda.icon_state = "pda-engineer"
- M.equip_to_slot_or_del(pda, slot_wear_pda)
+ M.equipOutfit(engineering_outfit)
M.job = "ERT Engineering"
-
if("Security")
security_slots -= 1
- M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/security(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/ert/security(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/responseteam(M), slot_in_backpack)
-
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/security/response_team(M), slot_belt)
-
- var/obj/item/weapon/card/id/W = new(src)
- W.assignment = "Emergency Response Team Member"
- W.registered_name = M.real_name
- W.name = "[M.real_name]'s ID Card (Emergency Response Team Officer)"
- W.icon_state = "ERT_security"
- W.access = get_centcom_access(W.assignment)
- M.equip_to_slot_or_del(W, slot_wear_id)
-
- var/obj/item/device/pda/heads/pda = new(src)
- pda.owner = M.real_name
- pda.ownjob = "Emergency Response Team Member"
- pda.name = "PDA-[M.real_name] ([pda.ownjob])"
- pda.icon_state = "pda-security"
- M.equip_to_slot_or_del(pda, slot_wear_pda)
+ M.equipOutfit(security_outfit)
M.job = "ERT Security"
if("Medic")
medical_slots -= 1
- M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/ert/medical(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/responseteam(M), slot_in_backpack)
-
- var/obj/item/weapon/card/id/W = new(src)
- W.assignment = "Emergency Response Team Member"
- W.registered_name = M.real_name
- W.name = "[M.real_name]'s ID Card (Emergency Response Team Medic)"
- W.icon_state = "ERT_medical"
- W.access = get_centcom_access(W.assignment)
- M.equip_to_slot_or_del(W, slot_wear_id)
-
- var/obj/item/device/pda/heads/pda = new(src)
- pda.owner = M.real_name
- pda.ownjob = "Emergency Response Team Member"
- pda.name = "PDA-[M.real_name] ([pda.ownjob])"
- pda.icon_state = "pda-medical"
- M.equip_to_slot_or_del(pda, slot_wear_pda)
+ M.equipOutfit(medical_outfit)
M.job = "ERT Medical"
if("Commander")
@@ -317,23 +261,7 @@ var/ert_request_answered = 0
M.name = M.real_name
M.age = rand(35,45)
- M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/ert/commander(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/responseteam(M), slot_in_backpack)
-
- var/obj/item/weapon/card/id/W = new(src)
- W.assignment = "Emergency Response Team Leader"
- W.registered_name = M.real_name
- W.name = "[M.real_name]'s ID Card (Emergency Response Team Leader)"
- W.icon_state = "ERT_leader"
- W.access = get_centcom_access(W.assignment)
- M.equip_to_slot_or_del(W, slot_wear_id)
-
- var/obj/item/device/pda/heads/pda = new(src)
- pda.owner = M.real_name
- pda.ownjob = "Emergency Response Team Leader"
- pda.name = "PDA-[M.real_name] ([pda.ownjob])"
- M.equip_to_slot_or_del(pda, slot_wear_pda)
+ M.equipOutfit(command_outfit)
M.job = "ERT Commander"
/datum/response_team/proc/cannot_send_team()
@@ -345,242 +273,344 @@ var/ert_request_answered = 0
// -- AMBER TEAM --
/datum/response_team/amber
+ engineering_outfit = /datum/outfit/job/centcom/response_team/engineer/amber
+ security_outfit = /datum/outfit/job/centcom/response_team/security/amber
+ medical_outfit = /datum/outfit/job/centcom/response_team/medic/amber
+ command_outfit = /datum/outfit/job/centcom/response_team/commander/amber
/datum/response_team/amber/announce_team()
event_announcement.Announce("Attention, [station_name()]. We are sending a code AMBER light Emergency Response Team. Standby.", "ERT En-Route")
-/datum/response_team/amber/equip_officer(var/officer_type, var/mob/living/carbon/human/M)
- ..()
-
- switch(officer_type)
- if("Engineer")
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/yellow(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/ert/engineer(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen/engi(M), slot_s_store)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/meson(M), slot_glasses)
-
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/ert/engineer(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/stack/sheet/glass(M, amount=50), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/stack/sheet/metal(M, amount=50), slot_in_backpack)
-
- M.equip_to_slot_or_del(new /obj/item/device/t_scanner(M), slot_l_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/melee/classic_baton/telescopic(M), slot_r_store)
-
- if("Security")
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/black(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest/ert/security(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun/advtaser(M), slot_s_store)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/security/sunglasses(M), slot_glasses)
-
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/ert/security(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/zipties(M), slot_in_backpack)
-
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/laser(M), slot_r_hand)
-
- if("Medic")
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/latex(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest/ert/medical(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/health(M), slot_glasses)
-
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/medical/response_team(M), slot_belt)
-
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/ert/medical(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/surgical(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/o2(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/brute(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/adv(M), slot_in_backpack)
-
- M.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/hypospray/CMO(M), slot_l_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/melee/classic_baton/telescopic(M), slot_r_store)
-
- if("Commander")
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/black(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest/ert/command(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_glasses)
-
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_belt)
-
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/ert/command(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/restraints/handcuffs(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/lockbox/loyalty(M), slot_in_backpack)
-
- M.equip_to_slot_or_del(new /obj/item/weapon/pinpointer(M), slot_l_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/melee/classic_baton/telescopic(M), slot_r_store)
-
// -- RED TEAM --
/datum/response_team/red
+ engineering_outfit = /datum/outfit/job/centcom/response_team/engineer/red
+ security_outfit = /datum/outfit/job/centcom/response_team/security/red
+ medical_outfit = /datum/outfit/job/centcom/response_team/medic/red
+ command_outfit = /datum/outfit/job/centcom/response_team/commander/red
/datum/response_team/red/announce_team()
event_announcement.Announce("Attention, [station_name()]. We are sending a code RED Emergency Response Team. Standby.", "ERT En-Route")
-/datum/response_team/red/equip_officer(var/officer_type, var/mob/living/carbon/human/M)
- ..()
-
- switch(officer_type)
- if("Engineer")
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/yellow(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/ert/engineer(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen/engi(M), slot_s_store)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/meson(M), slot_glasses)
-
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/ert/engineer(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas(M), slot_in_backpack)
- var/obj/item/weapon/rcd/R = new /obj/item/weapon/rcd(src)
- R.matter = 100
- M.equip_to_slot_or_del(R, slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/rcd_ammo(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/rcd_ammo(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/rcd_ammo(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_in_backpack)
-
- M.equip_to_slot_or_del(new /obj/item/device/t_scanner/extended_range(M), slot_l_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/melee/classic_baton/telescopic(M), slot_r_store)
-
- if("Security")
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/black(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/ert/security(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun/advtaser(M), slot_s_store)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/security/sunglasses(M), slot_glasses)
-
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/ert/security(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/handcuffs(M), slot_in_backpack)
- if(prob(50))
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/teargas(M), slot_in_backpack)
- else
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/flashbangs(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/ionrifle/carbine(M), slot_in_backpack)
-
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/lasercannon(M), slot_r_hand)
-
- if("Medic")
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/latex/nitrile(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/ert/medical(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/health/health_advanced(M), slot_glasses)
-
- M.equip_to_slot_or_del(new /obj/item/weapon/defibrillator/compact/loaded(M), slot_belt)
-
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/ert/medical(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/surgical(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/o2(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/toxin(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/adv(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/surgery(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_in_backpack)
-
- M.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/hypospray/CMO(M), slot_l_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/melee/classic_baton/telescopic(M), slot_r_store)
-
- if("Commander")
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/ert/commander(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/security/sunglasses(M), slot_glasses)
-
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun/nuclear(M), slot_belt)
-
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/ert/commander(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/restraints/handcuffs(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/lockbox/loyalty(M), slot_in_backpack)
-
-
- M.equip_to_slot_or_del(new /obj/item/weapon/pinpointer(M), slot_l_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/melee/classic_baton/telescopic(M), slot_r_store)
-
// -- GAMMA TEAM --
/datum/response_team/gamma
+ engineering_outfit = /datum/outfit/job/centcom/response_team/engineer/gamma
+ security_outfit = /datum/outfit/job/centcom/response_team/security/gamma
+ medical_outfit = /datum/outfit/job/centcom/response_team/medic/gamma
+ command_outfit = /datum/outfit/job/centcom/response_team/commander/gamma
/datum/response_team/gamma/announce_team()
event_announcement.Announce("Attention, [station_name()]. We are sending a code GAMMA elite Emergency Response Team. Standby.", "ERT En-Route")
-/datum/response_team/gamma/equip_officer(var/officer_type, var/mob/living/carbon/human/M)
- ..()
+/datum/outfit/job/centcom/response_team
+ name = "Response team"
+ var/rt_assignment = "Emergency Response Team Member"
+ var/rt_job = "This is a bug"
+ allow_backbag_choice = FALSE
+ allow_loadout = FALSE
+ pda = /obj/item/device/pda/heads/ert
+ id = /obj/item/weapon/card/id/ert
+ l_ear = /obj/item/device/radio/headset/ert/alt
- switch(officer_type)
- if("Engineer")
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/advance(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/yellow(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/ert/engineer(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen/double/full(M), slot_s_store)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/meson/night(M), slot_glasses)
+ implants = list(/obj/item/weapon/implant/mindshield)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/ert/engineer(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/rcd/combat, slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/rcd_ammo/large(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/rcd_ammo/large(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/rcd_ammo/large(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/pistol(M), slot_in_backpack)
+/datum/outfit/job/centcom/response_team/pre_equip()
+ . = ..()
+ backpack_contents.Insert(1, /obj/item/weapon/storage/box/responseteam)
+ backpack_contents[/obj/item/weapon/storage/box/responseteam] = 1
- M.equip_to_slot_or_del(new /obj/item/device/t_scanner/extended_range(M), slot_l_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/melee/classic_baton/telescopic(M), slot_r_store)
+/datum/outfit/job/centcom/response_team/imprint_idcard(mob/living/carbon/human/H)
+ var/obj/item/weapon/card/id/W = H.wear_id
+ if(!istype(W))
+ return
+ W.assignment = rt_assignment
+ W.rank = W.assignment
+ W.age = H.age
+ W.sex = capitalize(H.gender)
+ W.registered_name = H.real_name
+ W.name = "[H.real_name]'s ID Card ([rt_job])"
+ W.access = get_centcom_access(W.assignment)
+ W.photo = get_id_photo(H)
- if("Security")
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat/swat(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/ert/security(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun/nuclear(M), slot_s_store)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/security/night(M), slot_glasses)
+/datum/outfit/job/centcom/response_team/imprint_pda(mob/living/carbon/human/H)
+ var/obj/item/device/pda/PDA = H.wear_pda
+ if(istype(PDA))
+ PDA.owner = H.real_name
+ PDA.ownjob = rt_assignment
+ PDA.ownrank = rt_assignment
+ PDA.name = "PDA-[H.real_name] ([PDA.ownjob])"
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/ert/security(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/handcuffs(M), slot_in_backpack)
- if(prob(50))
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/teargas(M), slot_in_backpack)
- else
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/flashbangs(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/ionrifle/carbine(M), slot_in_backpack)
+/datum/outfit/job/centcom/response_team/commander
+ name = "RT Commander"
+ rt_assignment = "Emergency Response Team Leader"
+ rt_job = "Emergency Response Team Leader"
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/carbine(M), slot_r_hand)
+ uniform = /obj/item/clothing/under/rank/centcom_officer
+ back = /obj/item/weapon/storage/backpack/ert/commander
- if("Medic")
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat/swat(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/ert/medical(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/health/night(M), slot_glasses)
+ id = /obj/item/weapon/card/id/ert/commander
- M.equip_to_slot_or_del(new /obj/item/weapon/defibrillator/compact/loaded(M), slot_belt)
+ l_pocket = /obj/item/weapon/pinpointer
+ r_pocket = /obj/item/weapon/melee/classic_baton/telescopic
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/ert/medical(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/surgery(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/pistol(M), slot_in_backpack)
+/datum/outfit/job/centcom/response_team/commander/amber
+ name = "RT Commander (Amber)"
+ shoes = /obj/item/clothing/shoes/combat
+ gloves = /obj/item/clothing/gloves/color/black
+ suit = /obj/item/clothing/suit/armor/vest/ert/command
+ glasses = /obj/item/clothing/glasses/sunglasses
- M.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/hypospray/combat/nanites(src), slot_l_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/melee/classic_baton/telescopic(M), slot_r_store)
+ belt = /obj/item/weapon/gun/energy/gun
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/medbeam(M), slot_r_hand)
+ backpack_contents = list(
+ /obj/item/clothing/head/helmet/ert/command = 1,
+ /obj/item/clothing/mask/gas/sechailer = 1,
+ /obj/item/weapon/restraints/handcuffs = 1,
+ /obj/item/weapon/storage/lockbox/mindshield = 1
+ )
- if("Commander")
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat/swat(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/ert/commander(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/security/night(M), slot_glasses)
+/datum/outfit/job/centcom/response_team/commander/red
+ name = "RT Commander (Red)"
+ shoes = /obj/item/clothing/shoes/combat
+ gloves = /obj/item/clothing/gloves/combat
+ suit = /obj/item/clothing/suit/space/hardsuit/ert/commander
+ glasses = /obj/item/clothing/glasses/hud/security/sunglasses
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun/nuclear(M), slot_belt)
+ belt = /obj/item/weapon/gun/energy/gun/nuclear
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/ert/commander(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/restraints/handcuffs(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/lockbox/loyalty(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/pistol(M), slot_in_backpack)
+ backpack_contents = list(
+ /obj/item/clothing/head/helmet/space/hardsuit/ert/commander = 1,
+ /obj/item/clothing/mask/gas/sechailer/swat = 1,
+ /obj/item/weapon/restraints/handcuffs = 1,
+ /obj/item/weapon/storage/lockbox/mindshield = 1
+ )
- M.equip_to_slot_or_del(new /obj/item/weapon/pinpointer(M), slot_l_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/melee/classic_baton/telescopic(M), slot_r_store)
+/datum/outfit/job/centcom/response_team/commander/gamma
+ name = "RT Commander (Gamma)"
+ shoes = /obj/item/clothing/shoes/combat/swat
+ gloves = /obj/item/clothing/gloves/combat
+ suit = /obj/item/clothing/suit/space/hardsuit/ert/commander
+ glasses = /obj/item/clothing/glasses/hud/security/night
+ belt = /obj/item/weapon/gun/energy/gun/nuclear
+
+ backpack_contents = list(
+ /obj/item/clothing/head/helmet/space/hardsuit/ert/commander = 1,
+ /obj/item/clothing/mask/gas/sechailer/swat = 1,
+ /obj/item/weapon/restraints/handcuffs = 1,
+ /obj/item/weapon/storage/lockbox/mindshield = 1,
+ /obj/item/weapon/gun/energy/pulse/pistol = 1
+ )
+
+/datum/outfit/job/centcom/response_team/security
+ name = "RT Security"
+ rt_job = "Emergency Response Team Officer"
+ uniform = /obj/item/clothing/under/rank/security
+ back = /obj/item/weapon/storage/backpack/ert/security
+ belt = /obj/item/weapon/storage/belt/security/response_team
+ pda = /obj/item/device/pda/heads/ert/security
+ id = /obj/item/weapon/card/id/ert/security
+ var/has_grenades = FALSE
+
+/datum/outfit/job/centcom/response_team/security/pre_equip()
+ . = ..()
+ if(has_grenades)
+ var/grenadebox = /obj/item/weapon/storage/box/flashbangs
+ if(prob(50))
+ grenadebox = /obj/item/weapon/storage/box/teargas
+ backpack_contents.Insert(1, grenadebox)
+ backpack_contents[grenadebox] = 1
+
+/datum/outfit/job/centcom/response_team/security/amber
+ name = "RT Security (Amber)"
+ shoes = /obj/item/clothing/shoes/combat
+ gloves = /obj/item/clothing/gloves/color/black
+ suit = /obj/item/clothing/suit/armor/vest/ert/security
+ suit_store = /obj/item/weapon/gun/energy/gun/advtaser
+ glasses = /obj/item/clothing/glasses/hud/security/sunglasses
+
+ r_hand = /obj/item/weapon/gun/energy/laser
+
+ backpack_contents = list(
+ /obj/item/clothing/head/helmet/ert/security = 1,
+ /obj/item/clothing/mask/gas/sechailer = 1,
+ /obj/item/weapon/storage/box/zipties = 1
+ )
+
+/datum/outfit/job/centcom/response_team/security/red
+ name = "RT Security (Red)"
+ has_grenades = TRUE
+
+ shoes = /obj/item/clothing/shoes/combat
+ gloves = /obj/item/clothing/gloves/color/black
+ suit = /obj/item/clothing/suit/space/hardsuit/ert/security
+ suit_store = /obj/item/weapon/gun/energy/gun/advtaser
+ glasses = /obj/item/clothing/glasses/hud/security/sunglasses
+
+ r_hand = /obj/item/weapon/gun/energy/lasercannon
+
+ backpack_contents = list(
+ /obj/item/clothing/head/helmet/space/hardsuit/ert/security = 1,
+ /obj/item/clothing/mask/gas/sechailer = 1,
+ /obj/item/weapon/storage/box/handcuffs = 1,
+ /obj/item/weapon/gun/energy/ionrifle/carbine = 1
+ )
+
+/datum/outfit/job/centcom/response_team/security/gamma
+ name = "RT Security (Gamma)"
+ has_grenades = TRUE
+ shoes = /obj/item/clothing/shoes/combat/swat
+ gloves = /obj/item/clothing/gloves/combat
+ suit = /obj/item/clothing/suit/space/hardsuit/ert/security
+ suit_store = /obj/item/weapon/gun/energy/gun/nuclear
+ glasses = /obj/item/clothing/glasses/hud/security/night
+
+ r_hand = /obj/item/weapon/gun/energy/pulse/carbine
+
+ backpack_contents = list(
+ /obj/item/clothing/head/helmet/space/hardsuit/ert/security = 1,
+ /obj/item/clothing/mask/gas/sechailer/swat = 1,
+ /obj/item/weapon/storage/box/handcuffs = 1,
+ /obj/item/weapon/gun/energy/ionrifle/carbine = 1
+ )
+
+/datum/outfit/job/centcom/response_team/engineer
+ name = "RT Engineer"
+ rt_job = "Emergency Response Team Engineer"
+ back = /obj/item/weapon/storage/backpack/ert/engineer
+ uniform = /obj/item/clothing/under/rank/engineer
+
+ belt = /obj/item/weapon/storage/belt/utility/full/multitool
+ pda = /obj/item/device/pda/heads/ert/engineering
+ id = /obj/item/weapon/card/id/ert/engineering
+
+/datum/outfit/job/centcom/response_team/engineer/amber
+ name = "RT Engineer (Amber)"
+ shoes = /obj/item/clothing/shoes/magboots
+ gloves = /obj/item/clothing/gloves/color/yellow
+ suit = /obj/item/clothing/suit/space/hardsuit/ert/engineer
+ suit_store = /obj/item/weapon/tank/emergency_oxygen/engi
+ glasses = /obj/item/clothing/glasses/meson
+
+ l_pocket = /obj/item/device/t_scanner
+ r_pocket = /obj/item/weapon/melee/classic_baton/telescopic
+
+ backpack_contents = list(
+ /obj/item/clothing/head/helmet/space/hardsuit/ert/engineer = 1,
+ /obj/item/clothing/mask/gas = 1,
+ /obj/item/stack/sheet/glass/fifty = 1,
+ /obj/item/stack/sheet/metal/fifty = 1
+ )
+
+/datum/outfit/job/centcom/response_team/engineer/red
+ name = "RT Engineer (Red)"
+ shoes = /obj/item/clothing/shoes/magboots
+ gloves = /obj/item/clothing/gloves/color/yellow
+ suit = /obj/item/clothing/suit/space/hardsuit/ert/engineer
+ suit_store = /obj/item/weapon/tank/emergency_oxygen/engi
+ glasses = /obj/item/clothing/glasses/meson
+
+ l_pocket = /obj/item/device/t_scanner/extended_range
+ r_pocket = /obj/item/weapon/melee/classic_baton/telescopic
+
+ backpack_contents = list(
+ /obj/item/clothing/head/helmet/space/hardsuit/ert/engineer = 1,
+ /obj/item/clothing/mask/gas = 1,
+ /obj/item/weapon/rcd/preloaded = 1,
+ /obj/item/weapon/rcd_ammo = 3,
+ /obj/item/weapon/gun/energy/gun = 1
+ )
+
+/datum/outfit/job/centcom/response_team/engineer/gamma
+ name = "RT Engineer (Gamma)"
+ shoes = /obj/item/clothing/shoes/magboots/advance
+ gloves = /obj/item/clothing/gloves/color/yellow
+ suit = /obj/item/clothing/suit/space/hardsuit/ert/engineer
+ suit_store = /obj/item/weapon/tank/emergency_oxygen/double/full
+ glasses = /obj/item/clothing/glasses/meson/night
+
+ l_pocket = /obj/item/device/t_scanner/extended_range
+ r_pocket = /obj/item/weapon/melee/classic_baton/telescopic
+
+ backpack_contents = list(
+ /obj/item/clothing/head/helmet/space/hardsuit/ert/engineer = 1,
+ /obj/item/clothing/mask/gas/sechailer/swat = 1,
+ /obj/item/weapon/rcd/combat = 1,
+ /obj/item/weapon/rcd_ammo/large = 3,
+ /obj/item/weapon/gun/energy/pulse/pistol = 1
+ )
+
+/datum/outfit/job/centcom/response_team/medic
+ name = "RT Medic"
+ rt_job = "Emergency Response Team Medic"
+ uniform = /obj/item/clothing/under/rank/medical
+ back = /obj/item/weapon/storage/backpack/ert/medical
+ pda = /obj/item/device/pda/heads/ert/medical
+ id = /obj/item/weapon/card/id/ert/medic
+
+ l_pocket = /obj/item/weapon/reagent_containers/hypospray/CMO
+ r_pocket = /obj/item/weapon/melee/classic_baton/telescopic
+
+/datum/outfit/job/centcom/response_team/medic/amber
+ name = "RT Medic (Amber)"
+
+ shoes = /obj/item/clothing/shoes/white
+ gloves = /obj/item/clothing/gloves/color/latex
+ suit = /obj/item/clothing/suit/armor/vest/ert/medical
+ glasses = /obj/item/clothing/glasses/hud/health
+
+ belt = /obj/item/weapon/storage/belt/medical/response_team
+
+ l_pocket = /obj/item/weapon/reagent_containers/hypospray/CMO
+ r_pocket = /obj/item/weapon/melee/classic_baton/telescopic
+
+ backpack_contents = list(
+ /obj/item/clothing/head/helmet/ert/medical = 1,
+ /obj/item/clothing/mask/surgical = 1,
+ /obj/item/weapon/storage/firstaid/o2 = 1,
+ /obj/item/weapon/storage/firstaid/brute = 1,
+ /obj/item/weapon/storage/firstaid/adv = 1,
+ )
+
+/datum/outfit/job/centcom/response_team/medic/red
+ name = "RT Medic (Red)"
+ shoes = /obj/item/clothing/shoes/white
+ gloves = /obj/item/clothing/gloves/color/latex/nitrile
+ suit = /obj/item/clothing/suit/space/hardsuit/ert/medical
+ glasses = /obj/item/clothing/glasses/hud/health/health_advanced
+
+ belt = /obj/item/weapon/defibrillator/compact/loaded
+
+
+ backpack_contents = list(
+ /obj/item/clothing/head/helmet/space/hardsuit/ert/medical = 1,
+ /obj/item/clothing/mask/surgical = 1,
+ /obj/item/weapon/storage/firstaid/o2 = 1,
+ /obj/item/weapon/storage/firstaid/toxin = 1,
+ /obj/item/weapon/storage/firstaid/adv = 1,
+ /obj/item/weapon/storage/firstaid/surgery = 1,
+ /obj/item/weapon/gun/energy/gun = 1
+ )
+
+/datum/outfit/job/centcom/response_team/medic/gamma
+ name = "RT Medic (Gamma)"
+ shoes = /obj/item/clothing/shoes/combat/swat
+ gloves = /obj/item/clothing/gloves/combat
+ suit = /obj/item/clothing/suit/space/hardsuit/ert/medical
+ glasses = /obj/item/clothing/glasses/hud/health/night
+
+ belt = /obj/item/weapon/defibrillator/compact/loaded
+
+ l_pocket = /obj/item/weapon/reagent_containers/hypospray/combat/nanites
+
+ r_hand = /obj/item/weapon/gun/medbeam
+ backpack_contents = list(
+ /obj/item/clothing/head/helmet/space/hardsuit/ert/medical = 1,
+ /obj/item/clothing/mask/gas/sechailer/swat = 1,
+ /obj/item/weapon/storage/firstaid/surgery = 1,
+ /obj/item/weapon/gun/energy/pulse/pistol = 1
+ )
/obj/item/device/radio/centcom
name = "centcomm bounced radio"
diff --git a/code/game/shuttle_engines.dm b/code/game/shuttle_engines.dm
index 820103eb2d4..3072fd2a264 100644
--- a/code/game/shuttle_engines.dm
+++ b/code/game/shuttle_engines.dm
@@ -16,8 +16,8 @@
opacity = 0
anchored = 1
- CanPass(atom/movable/mover, turf/target, height, air_group)
- if(!height || air_group) return 0
+ CanPass(atom/movable/mover, turf/target, height)
+ if(!height) return 0
else return ..()
CanAtmosPass(turf/T)
diff --git a/code/game/smoothwall.dm b/code/game/smoothwall.dm
index 48d150dfb85..20dea8de7b0 100644
--- a/code/game/smoothwall.dm
+++ b/code/game/smoothwall.dm
@@ -83,7 +83,7 @@
// JESUS WHY
for(var/direction in cardinal)
- for(var/obj/effect/glowshroom/shroom in get_step(src,direction))
+ for(var/obj/structure/glowshroom/shroom in get_step(src,direction))
if(!shroom.floor) //shrooms drop to the floor
shroom.floor = 1
shroom.icon_state = "glowshroomf"
diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm
index b8a6635225a..0476df52ceb 100644
--- a/code/game/turfs/simulated/floor.dm
+++ b/code/game/turfs/simulated/floor.dm
@@ -41,13 +41,11 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
builtin_tile = new floor_tile
/turf/simulated/floor/Destroy()
- if(builtin_tile)
- qdel(builtin_tile)
- builtin_tile = null
+ QDEL_NULL(builtin_tile)
return ..()
-//turf/simulated/floor/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+//turf/simulated/floor/CanPass(atom/movable/mover, turf/target, height=0)
// if((istype(mover, /obj/machinery/vehicle) && !(src.burnt)))
// if(!( locate(/obj/machinery/mass_driver, src) ))
// return 0
@@ -138,24 +136,11 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
return 1
if(..())
return 1
- if(intact && istype(C, /obj/item/weapon/crowbar))
- if(broken || burnt)
- broken = 0
- burnt = 0
- to_chat(user, "You remove the broken plating.")
- else
- if(istype(src, /turf/simulated/floor/wood))
- to_chat(user, "You forcefully pry off the planks, destroying them in the process.")
- else if(!builtin_tile)
- to_chat(user, "You are unable to pry up \the [src] with a crowbar.")
- return 1
- else
- to_chat(user, "You remove \the [builtin_tile.singular_name].")
- builtin_tile.loc = src
- builtin_tile = null //deassociate tile, it no longer belongs to this turf
- make_plating()
- playsound(src, 'sound/items/Crowbar.ogg', 80, 1)
+ if(intact && iscrowbar(C))
+ pry_tile(C, user)
return 1
+ if(intact && istype(C, /obj/item/stack/tile))
+ try_replace_tile(C, user, params)
if(istype(C, /obj/item/pipe))
var/obj/item/pipe/P = C
if(P.pipe_type != -1) // ANY PIPE
@@ -181,6 +166,37 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
return 1
return 0
+/turf/simulated/floor/proc/try_replace_tile(obj/item/stack/tile/T, mob/user, params)
+ if(T.turf_type == type)
+ return
+ var/obj/item/weapon/crowbar/CB
+ if(iscrowbar(user.get_inactive_hand()))
+ CB = user.get_inactive_hand()
+ if(!CB)
+ return
+ var/turf/simulated/floor/plating/P = pry_tile(CB, user, TRUE)
+ if(!istype(P))
+ return
+ P.attackby(T, user, params)
+
+/turf/simulated/floor/proc/pry_tile(obj/item/C, mob/user, silent = FALSE)
+ playsound(src, C.usesound, 80, 1)
+ return remove_tile(user, silent)
+
+/turf/simulated/floor/proc/remove_tile(mob/user, silent = FALSE, make_tile = TRUE)
+ if(broken || burnt)
+ broken = 0
+ burnt = 0
+ if(user && !silent)
+ to_chat(user, "You remove the broken plating.")
+ else
+ if(user && !silent)
+ to_chat(user, "You remove the floor tile.")
+ if(builtin_tile && make_tile)
+ builtin_tile.forceMove(src)
+ builtin_tile = null
+ return make_plating()
+
/turf/simulated/floor/singularity_pull(S, current_size)
if(current_size == STAGE_THREE)
if(prob(30))
diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm
index b09ef2c168e..94dc68b51f2 100644
--- a/code/game/turfs/simulated/floor/fancy_floor.dm
+++ b/code/game/turfs/simulated/floor/fancy_floor.dm
@@ -11,15 +11,48 @@
/turf/simulated/floor/wood/attackby(obj/item/C, mob/user, params)
if(..())
return
- if(istype(C, /obj/item/weapon/screwdriver))
- if(broken || burnt)
- return
- to_chat(user, "You unscrew the planks.")
- new floor_tile(src)
- make_plating()
- playsound(src, 'sound/items/Screwdriver.ogg', 80, 1)
+ if(isscrewdriver(C))
+ pry_tile(C, user)
return
+/turf/simulated/floor/wood/try_replace_tile(obj/item/stack/tile/T, mob/user, params)
+ if(T.turf_type == type)
+ return
+ var/obj/item/weapon/tool
+ if(isscrewdriver(user.get_inactive_hand()))
+ tool = user.get_inactive_hand()
+ if(!tool && iscrowbar(user.get_inactive_hand()))
+ tool = user.get_inactive_hand()
+ if(!tool)
+ return
+ var/turf/simulated/floor/plating/P = pry_tile(tool, user, TRUE)
+ if(!istype(P))
+ return
+ P.attackby(T, user, params)
+
+/turf/simulated/floor/wood/pry_tile(obj/item/C, mob/user, silent = FALSE)
+ var/is_screwdriver = isscrewdriver(C)
+ playsound(src, C.usesound, 80, 1)
+ return remove_tile(user, silent, make_tile = is_screwdriver)
+
+/turf/simulated/floor/wood/remove_tile(mob/user, silent = FALSE, make_tile = TRUE)
+ if(broken || burnt)
+ broken = 0
+ burnt = 0
+ if(user && !silent)
+ to_chat(user, "You remove the broken planks.")
+ else
+ if(make_tile)
+ if(user && !silent)
+ to_chat(user, "You unscrew the planks.")
+ if(builtin_tile)
+ builtin_tile.forceMove(src)
+ builtin_tile = null
+ else
+ if(user && !silent)
+ to_chat(user, "You forcefully pry off the planks, destroying them in the process.")
+ return make_plating()
+
/turf/simulated/floor/grass
name = "grass patch"
icon_state = "grass1"
@@ -45,7 +78,7 @@
to_chat(user, "You shovel the grass.")
playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1)
make_plating()
-
+
// NEEDS TO BE UPDATED
/turf/simulated/floor/basalt //By your powers combined, I am captain planet
name = "volcanic floor"
@@ -54,7 +87,7 @@
oxygen = 14
nitrogen = 23
temperature = 300
-
+
/turf/simulated/floor/basalt/attackby(obj/item/W, mob/user, params)
if(..())
return
diff --git a/code/game/turfs/simulated/floor/mineral.dm b/code/game/turfs/simulated/floor/mineral.dm
index 5af7cf30673..eb15d3f9e63 100644
--- a/code/game/turfs/simulated/floor/mineral.dm
+++ b/code/game/turfs/simulated/floor/mineral.dm
@@ -58,6 +58,11 @@
floor_tile = /obj/item/stack/tile/mineral/gold
icons = list("gold","gold_dam")
+/turf/simulated/floor/mineral/gold/fancy
+ icon_state = "goldfancy"
+ floor_tile = /obj/item/stack/tile/mineral/gold/fancy
+ icons = list("goldfancy","goldfancy_dam")
+
//SILVER
/turf/simulated/floor/mineral/silver
name = "silver floor"
@@ -65,6 +70,11 @@
floor_tile = /obj/item/stack/tile/mineral/silver
icons = list("silver","silver_dam")
+/turf/simulated/floor/mineral/silver/fancy
+ icon_state = "silverfancy"
+ floor_tile = /obj/item/stack/tile/mineral/silver/fancy
+ icons = list("silverfancy","silverfancy_dam")
+
//BANANIUM
/turf/simulated/floor/mineral/bananium
name = "bananium floor"
diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm
index e9770536b73..c5dc58f4f26 100644
--- a/code/game/turfs/simulated/floor/plating.dm
+++ b/code/game/turfs/simulated/floor/plating.dm
@@ -35,10 +35,10 @@
return 1
else
to_chat(user, "You begin reinforcing the floor...")
- if(do_after(user, 30, target = src))
+ if(do_after(user, 30 * C.toolspeed, target = src))
if(R.get_amount() >= 2 && !istype(src, /turf/simulated/floor/engine))
ChangeTurf(/turf/simulated/floor/engine)
- playsound(src, 'sound/items/Deconstruct.ogg', 80, 1)
+ playsound(src, C.usesound, 80, 1)
R.use(2)
to_chat(user, "You reinforce the floor.")
return 1
@@ -59,7 +59,7 @@
if( welder.isOn() && (broken || burnt) )
if(welder.remove_fuel(0,user))
to_chat(user, "You fix some dents on the broken plating.")
- playsound(src, 'sound/items/Welder.ogg', 80, 1)
+ playsound(src, welder.usesound, 80, 1)
icon_state = icon_plating
burnt = 0
broken = 0
@@ -99,8 +99,8 @@
return
if(istype(C, /obj/item/weapon/wrench))
to_chat(user, "You begin removing rods...")
- playsound(src, 'sound/items/Ratchet.ogg', 80, 1)
- if(do_after(user, 30, target = src))
+ playsound(src, C.usesound, 80, 1)
+ if(do_after(user, 30 * C.toolspeed, target = src))
if(!istype(src, /turf/simulated/floor/engine))
return
new /obj/item/stack/rods(src, 2)
@@ -236,7 +236,7 @@
if(istype(T, /turf/simulated/floor/plating/airless/catwalk))
var/turf/simulated/floor/plating/airless/catwalk/CW=T
CW.update_icon(0)
- playsound(src, 'sound/items/Screwdriver.ogg', 80, 1)
+ playsound(src, C.usesound, 80, 1)
/turf/simulated/floor/plating/metalfoam
name = "foamed metal plating"
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index cb7cd8be813..c9b4695357e 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -225,7 +225,7 @@
take_damage(rand(25, 75))
return
- to_chat(M, "\blue You push the wall but nothing happens!")
+ to_chat(M, "You push the wall but nothing happens!")
return
/turf/simulated/wall/attack_hand(mob/user as mob)
@@ -272,7 +272,7 @@
var/obj/item/weapon/weldingtool/WT = W
if(WT.remove_fuel(0,user))
to_chat(user, "You burn away the fungi with \the [WT].")
- playsound(src, 'sound/items/Welder.ogg', 10, 1)
+ playsound(src, WT.usesound, 10, 1)
for(var/obj/effect/overlay/wall_rot/WR in src)
qdel(WR)
rotting = 0
@@ -300,7 +300,7 @@
EB.spark_system.start()
to_chat(user, "You slash \the [src] with \the [EB]; the thermite ignites!")
playsound(src, "sparks", 50, 1)
- playsound(src, 'sound/weapons/blade1.ogg', 50, 1)
+ playsound(src, EB.usesound, 50, 1)
thermitemelt(user)
return
@@ -317,16 +317,16 @@
if(WT.remove_fuel(0,user))
if(response == "Repair")
to_chat(user, "You start repairing the damage to [src].")
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
- if(do_after(user, max(5, damage / 5), target = src) && WT && WT.isOn())
+ playsound(src, WT.usesound, 100, 1)
+ if(do_after(user, max(5, damage / 5) * WT.toolspeed, target = src) && WT && WT.isOn())
to_chat(user, "You finish repairing the damage to [src].")
take_damage(-damage)
else if(response == "Dismantle")
to_chat(user, "You begin slicing through the outer plating.")
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, WT.usesound, 100, 1)
- if(do_after(user, 100, target = src) && WT && WT.isOn())
+ if(do_after(user, 100 * WT.toolspeed, target = src) && WT && WT.isOn())
to_chat(user, "You remove the outer plating.")
dismantle_wall()
@@ -341,9 +341,9 @@
else if(istype(W, /obj/item/weapon/gun/energy/plasmacutter))
to_chat(user, "You begin slicing through the outer plating.")
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, W.usesound, 100, 1)
- if(do_after(user, istype(sheet_type, /obj/item/stack/sheet/mineral/diamond) ? 120 : 60, target = src))
+ if(do_after(user, istype(sheet_type, /obj/item/stack/sheet/mineral/diamond) ? 120 * W.toolspeed : 60 * W.toolspeed, target = src))
to_chat(user, "You remove the outer plating.")
dismantle_wall()
visible_message("[user] slices apart \the [src]!","You hear metal being sliced apart.")
@@ -353,7 +353,7 @@
to_chat(user, "You begin to drill though the wall.")
- if(do_after(user, istype(sheet_type, /obj/item/stack/sheet/mineral/diamond) ? 120 : 60, target = src))
+ if(do_after(user, istype(sheet_type, /obj/item/stack/sheet/mineral/diamond) ? 480 * W.toolspeed : 240 * W.toolspeed, target = src)) // Diamond pickaxe has 0.25 toolspeed, so 120/60
to_chat(user, "Your drill tears though the last of the reinforced plating.")
dismantle_wall()
visible_message("[user] drills through \the [src]!","You hear the grinding of metal.")
@@ -362,8 +362,8 @@
to_chat(user, "You begin to disintegrates the wall.")
- if(do_after(user, istype(sheet_type, /obj/item/stack/sheet/mineral/diamond) ? 60 : 30, target = src))
- to_chat(user, "Your jackhammer disintegrate the reinforced plating.")
+ if(do_after(user, istype(sheet_type, /obj/item/stack/sheet/mineral/diamond) ? 600 * W.toolspeed : 300 * W.toolspeed, target = src)) // Jackhammer has 0.1 toolspeed, so 60/30
+ to_chat(user, "Your sonic jackhammer disintegrate the reinforced plating.")
dismantle_wall()
visible_message("[user] disintegrates \the [src]!","You hear the grinding of metal.")
@@ -374,10 +374,10 @@
to_chat(user, "You stab \the [EB] into the wall and begin to slice it apart.")
playsound(src, "sparks", 50, 1)
- if(do_after(user, istype(sheet_type, /obj/item/stack/sheet/mineral/diamond) ? 140 : 70, target = src))
+ if(do_after(user, istype(sheet_type, /obj/item/stack/sheet/mineral/diamond) ? 140 * EB.toolspeed : 70 * EB.toolspeed, target = src))
EB.spark_system.start()
playsound(src, "sparks", 50, 1)
- playsound(src, 'sound/weapons/blade1.ogg', 50, 1)
+ playsound(src, EB.usesound, 50, 1)
dismantle_wall(1)
visible_message("[user] slices apart \the [src]!","You hear metal being sliced apart and sparks flying.")
@@ -398,12 +398,12 @@
playsound(get_turf(src), 'sound/weapons/circsawhit.ogg', 50, 1)
user.visible_message( \
"[user] starts drilling a hole in \the [src].", \
- "\blue You start drilling a hole in \the [src].", \
+ "You start drilling a hole in \the [src].", \
"You hear ratchet.")
- if(do_after(user, 80, target = src))
+ if(do_after(user, 80 * W.toolspeed, target = src))
user.visible_message( \
"[user] drills a hole in \the [src] and pushes \a [P] into the void", \
- "\blue You have finished drilling in \the [src] and push the [P] into the void.", \
+ "You have finished drilling in \the [src] and push the [P] into the void.", \
"You hear ratchet.")
user.drop_item()
diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm
index 49cfa1ace0f..cc4d1a05a27 100644
--- a/code/game/turfs/simulated/walls_reinforced.dm
+++ b/code/game/turfs/simulated/walls_reinforced.dm
@@ -28,7 +28,7 @@
var/obj/item/weapon/weldingtool/WT = W
if( WT.remove_fuel(0,user) )
to_chat(user, "You burn away the fungi with \the [WT].")
- playsound(src, 'sound/items/Welder.ogg', 10, 1)
+ playsound(src, WT.usesound, 10, 1)
for(var/obj/effect/overlay/wall_rot/WR in src)
qdel(WR)
rotting = 0
@@ -56,7 +56,7 @@
EB.spark_system.start()
to_chat(user, "You slash \the [src] with \the [EB]; the thermite ignites!")
playsound(src, "sparks", 50, 1)
- playsound(src, 'sound/weapons/blade1.ogg', 50, 1)
+ playsound(src, EB.usesound, 50, 1)
thermitemelt(user)
return
@@ -69,8 +69,8 @@
var/obj/item/weapon/weldingtool/WT = W
if(WT.remove_fuel(0,user))
to_chat(user, "You start repairing the damage to [src].")
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
- if(do_after(user, max(5, damage / 5), target = src) && WT && WT.isOn())
+ playsound(src, WT.usesound, 100, 1)
+ if(do_after(user, max(5, damage / 5) * WT.toolspeed, target = src) && WT && WT.isOn())
to_chat(user, "You finish repairing the damage to [src].")
take_damage(-damage)
return
@@ -83,7 +83,7 @@
switch(d_state)
if(0)
if(istype(W, /obj/item/weapon/wirecutters))
- playsound(src, 'sound/items/Wirecutter.ogg', 100, 1)
+ playsound(src, W.usesound, 100, 1)
d_state = 1
update_icon()
new /obj/item/stack/rods(src)
@@ -93,9 +93,9 @@
if(1)
if(istype(W, /obj/item/weapon/screwdriver))
to_chat(user, "You begin removing the support lines.")
- playsound(src, 'sound/items/Screwdriver.ogg', 100, 1)
+ playsound(src, W.usesound, 100, 1)
- if(do_after(user, 40, target = src) && d_state == 1)
+ if(do_after(user, 40 * W.toolspeed, target = src) && d_state == 1)
d_state = 2
update_icon()
to_chat(user, "You remove the support lines.")
@@ -117,9 +117,9 @@
var/obj/item/weapon/weldingtool/WT = W
if(WT.remove_fuel(0,user))
to_chat(user, "You begin slicing through the metal cover.")
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, WT.usesound, 100, 1)
- if(do_after(user, 60, target = src) && d_state == 2)
+ if(do_after(user, 60 * WT.toolspeed, target = src) && d_state == 2)
d_state = 3
update_icon()
to_chat(user, "You press firmly on the cover, dislodging it.")
@@ -130,9 +130,9 @@
if(istype(W, /obj/item/weapon/gun/energy/plasmacutter))
to_chat(user, "You begin slicing through the metal cover.")
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, W.usesound, 100, 1)
- if(do_after(user, 40, target = src) && d_state == 2)
+ if(do_after(user, 40 * W.toolspeed, target = src) && d_state == 2)
d_state = 3
update_icon()
to_chat(user, "You press firmly on the cover, dislodging it.")
@@ -141,9 +141,9 @@
if(3)
if(istype(W, /obj/item/weapon/crowbar))
to_chat(user, "You struggle to pry off the cover.")
- playsound(src, 'sound/items/Crowbar.ogg', 100, 1)
+ playsound(src, W.usesound, 100, 1)
- if(do_after(user, 100, target = src) && d_state == 3)
+ if(do_after(user, 100 * W.toolspeed, target = src) && d_state == 3)
d_state = 4
update_icon()
to_chat(user, "You pry off the cover.")
@@ -152,9 +152,9 @@
if(4)
if(istype(W, /obj/item/weapon/wrench))
to_chat(user, "You start loosening the anchoring bolts which secure the support rods to their frame.")
- playsound(src, 'sound/items/Ratchet.ogg', 100, 1)
+ playsound(src, W.usesound, 100, 1)
- if(do_after(user, 40, target = src) && d_state == 4)
+ if(do_after(user, 40 * W.toolspeed, target = src) && d_state == 4)
d_state = 5
update_icon()
to_chat(user, "You remove the bolts anchoring the support rods.")
@@ -165,9 +165,9 @@
var/obj/item/weapon/weldingtool/WT = W
if(WT.remove_fuel(0,user))
to_chat(user, "You begin slicing through the support rods.")
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, WT.usesound, 100, 1)
- if(do_after(user, 100, target = src) && d_state == 5)
+ if(do_after(user, 100 * WT.toolspeed, target = src) && d_state == 5)
d_state = 6
update_icon()
new /obj/item/stack/rods(src)
@@ -178,9 +178,9 @@
if(istype(W, /obj/item/weapon/gun/energy/plasmacutter))
to_chat(user, "You begin slicing through the support rods.")
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, W.usesound, 100, 1)
- if(do_after(user, 70, target = src) && d_state == 5)
+ if(do_after(user, 70 * W.toolspeed, target = src) && d_state == 5)
d_state = 6
update_icon()
new /obj/item/stack/rods( src )
@@ -190,9 +190,9 @@
if(6)
if(istype(W, /obj/item/weapon/crowbar))
to_chat(user, "You struggle to pry off the outer sheath.")
- playsound(src, 'sound/items/Crowbar.ogg', 100, 1)
+ playsound(src, W.usesound, 100, 1)
- if(do_after(user, 100, target = src) && d_state == 6)
+ if(do_after(user, 100 * W.toolspeed, target = src) && d_state == 6)
to_chat(user, "You pry off the outer sheath.")
dismantle_wall()
return
@@ -203,14 +203,14 @@
if(istype(W, /obj/item/weapon/pickaxe/drill/diamonddrill))
to_chat(user, "You begin to drill though the wall.")
- if(do_after(user, 200, target = src))
+ if(do_after(user, 800 * W.toolspeed, target = src)) // Diamond drill has 0.25 toolspeed, so 200
to_chat(user, "Your drill tears through the last of the reinforced plating.")
dismantle_wall()
if(istype(W,/obj/item/weapon/pickaxe/drill/jackhammer))
to_chat(user, "You begin to disintegrate the wall.")
- if(do_after(user, 100, target = src))
+ if(do_after(user, 1000 * W.toolspeed, target = src)) // Jackhammer has 0.1 toolspeed, so 100
to_chat(user, "Your sonic jackhammer disintegrates the reinforced plating.")
dismantle_wall()
@@ -220,7 +220,7 @@
to_chat(user, "You begin patching-up the wall with \a [MS].")
- if(do_after(user, max(20 * d_state, 100), target = src) && d_state)
+ if(do_after(user, max(20 * d_state, 100) * MS.toolspeed, target = src) && d_state)
if(!MS.use(1))
to_chat(user, "You don't have enough metal for that!")
return
@@ -238,7 +238,7 @@
return
to_chat(user, "You begin adding an additional layer of coating to the wall with \a [MS].")
- if(do_after(user, 40, target = src) && !d_state)
+ if(do_after(user, 40 * MS.toolspeed, target = src) && !d_state)
if(!MS.use(2))
to_chat(user, "You don't have enough plasteel for that!")
return
@@ -267,12 +267,12 @@
playsound(get_turf(src), 'sound/weapons/circsawhit.ogg', 50, 1)
user.visible_message( \
"[user] starts drilling a hole in \the [src].", \
- "\blue You start drilling a hole in \the [src]. This is going to take a while.", \
+ "You start drilling a hole in \the [src]. This is going to take a while.", \
"You hear ratchet.")
- if(do_after(user, 160, target = src))
+ if(do_after(user, 160 * V.toolspeed, target = src))
user.visible_message( \
"[user] drills a hole in \the [src] and pushes \a [P] into the void", \
- "\blue You have finished drilling in \the [src] and push the [P] into the void.", \
+ "You have finished drilling in \the [src] and push the [P] into the void.", \
"You hear ratchet.")
user.drop_item()
@@ -313,4 +313,3 @@
else
smooth = SMOOTH_TRUE
icon_state = ""
-
diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm
index da667768341..90454f9952b 100644
--- a/code/game/turfs/space/space.dm
+++ b/code/game/turfs/space/space.dm
@@ -31,6 +31,8 @@
..()
var/datum/space_level/S = space_manager.get_zlev(z)
S.remove_from_transit(src)
+ if(light_sources) // Turn off starlight, if present
+ set_light(0)
/turf/space/AfterChange(ignore_air, keep_cabling = FALSE)
..()
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 69b0df22ae3..a5e4190d6ea 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -386,15 +386,25 @@
if(ticker)
cameranet.updateVisibility(src)
-/turf/attackby(obj/item/C, mob/user, params)
- if(can_lay_cable() && istype(C, /obj/item/stack/cable_coil))
- var/obj/item/stack/cable_coil/coil = C
- for(var/obj/structure/cable/LC in src)
- if((LC.d1==0)||(LC.d2==0))
- LC.attackby(C,user)
- return
- coil.place_turf(src, user)
- return 1
+/turf/attackby(obj/item/I, mob/user, params)
+ if(can_lay_cable())
+ if(istype(I, /obj/item/stack/cable_coil))
+ var/obj/item/stack/cable_coil/C = I
+ for(var/obj/structure/cable/LC in src)
+ if(LC.d1 == 0 || LC.d2==0)
+ LC.attackby(C,user)
+ return
+ C.place_turf(src, user)
+ return 1
+ else if(istype(I, /obj/item/weapon/twohanded/rcl))
+ var/obj/item/weapon/twohanded/rcl/R = I
+ if(R.loaded)
+ for(var/obj/structure/cable/LC in src)
+ if(LC.d1 == 0 || LC.d2==0)
+ LC.attackby(R, user)
+ return
+ R.loaded.place_turf(src, user)
+ R.is_empty(user)
return 0
diff --git a/code/game/turfs/unsimulated/beach.dm b/code/game/turfs/unsimulated/beach.dm
index 970467c2ced..262727e97ee 100644
--- a/code/game/turfs/unsimulated/beach.dm
+++ b/code/game/turfs/unsimulated/beach.dm
@@ -59,8 +59,7 @@
water_overlay = new(src)
/turf/unsimulated/beach/water/drop/Destroy()
- qdel(water_overlay)
- water_overlay = null
+ QDEL_NULL(water_overlay)
return ..()
/obj/effect/effect/beach_drop_overlay
diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm
index 896bd2b850d..481fc73631a 100644
--- a/code/game/verbs/suicide.dm
+++ b/code/game/verbs/suicide.dm
@@ -166,7 +166,7 @@
card.removePersonality()
var/turf/T = get_turf_or_move(card.loc)
for(var/mob/M in viewers(T))
- M.show_message("\blue [src] flashes a message across its screen, \"Wiping core files. Please acquire a new personality to continue using pAI device functions.\"", 3, "\blue [src] bleeps electronically.", 2)
+ M.show_message("[src] flashes a message across its screen, \"Wiping core files. Please acquire a new personality to continue using pAI device functions.\"", 3, "[src] bleeps electronically.", 2)
death(0, 1)
else
to_chat(src, "Aborting suicide attempt.")
diff --git a/code/game/verbs/who.dm b/code/game/verbs/who.dm
index 4e822710cd0..dd8123b2876 100644
--- a/code/game/verbs/who.dm
+++ b/code/game/verbs/who.dm
@@ -77,9 +77,9 @@
for(var/client/C in admins)
if(check_rights(R_ADMIN, 0, C.mob))
- if(C.holder.fakekey && !check_rights(R_ADMIN, 0)) //Mentors/Mods can't see stealthmins
+ if(C.holder.fakekey && !check_rights(R_ADMIN, 0)) //Mentors can't see stealthmins
continue
-
+
if(C.holder.big_brother && !check_rights(R_PERMISSIONS, 0)) // normal admins can't see BB
continue
@@ -126,5 +126,5 @@
modmsg += "\t[C] is a [C.holder.rank]\n"
num_mods_online++
- msg = "Current Admins ([num_admins_online]):\n" + msg + "\nCurrent Mods/Mentors ([num_mods_online]):\n" + modmsg
+ msg = "Current Admins ([num_admins_online]):\n" + msg + "\nCurrent Mentors ([num_mods_online]):\n" + modmsg
to_chat(src, msg)
diff --git a/code/modules/VR/vr_avatar.dm b/code/modules/VR/vr_avatar.dm
new file mode 100644
index 00000000000..510871fb40a
--- /dev/null
+++ b/code/modules/VR/vr_avatar.dm
@@ -0,0 +1,87 @@
+
+
+/mob/living/carbon/human/virtual_reality
+ var/mob/living/carbon/human/real_me //The human controlling us, can be any human (including virtual ones... inception...)
+ var/datum/action/quit_vr/quit_action
+ var/datum/action/back_to_lobby/back_to_lobby
+ var/datum/action/detach_from_avatar/detach_from_avatar
+
+/mob/living/carbon/human/virtual_reality/New()
+ quit_action = new()
+ quit_action.Grant(src)
+ back_to_lobby = new()
+ back_to_lobby.Grant(src)
+ detach_from_avatar = new()
+ detach_from_avatar.Grant(src)
+ ..()
+
+/mob/living/carbon/human/virtual_reality/death()
+ return_to_lobby()
+ return ..()
+
+/mob/living/carbon/human/virtual_reality/Destroy()
+ return_to_lobby()
+ return ..()
+
+/mob/living/carbon/human/virtual_reality/ghost()
+ set category = "OOC"
+ set name = "Ghost"
+ set desc = "Relinquish your life and enter the land of the dead."
+ var/mob/living/carbon/human/H = real_me
+ revert_to_reality(FALSE)
+ if(H)
+ H.ghost()
+ qdel(src)
+
+/mob/living/carbon/human/virtual_reality/proc/revert_to_reality(remove = 0)
+ if(real_me && mind)
+ mind.transfer_to(real_me)
+ real_me.EyeBlind(2)
+ real_me.Confused(2)
+ if(remove)
+ qdel(src)
+ else
+ return src
+
+/mob/living/carbon/human/virtual_reality/proc/return_to_lobby()
+ if(real_me && mind)
+ var/mob/living/carbon/human/virtual_reality/new_vr
+ new_vr = spawn_vr_avatar(src, "Lobby")
+ var/obj/item/clothing/glasses/vr_goggles/g = new_vr.real_me.glasses
+ g.vr_human = new_vr
+ qdel(src)
+
+/datum/action/quit_vr
+ name = "Quit Virtual Reality"
+
+/datum/action/quit_vr/Trigger()
+ if(..())
+ if(istype(owner, /mob/living/carbon/human/virtual_reality))
+ var/mob/living/carbon/human/virtual_reality/vr = owner
+ vr.revert_to_reality(1)
+ else
+ Remove(owner)
+
+/datum/action/back_to_lobby
+ name = "Return To Lobby"
+
+/datum/action/back_to_lobby/Trigger()
+ if(..())
+ if(istype(owner, /mob/living/carbon/human/virtual_reality))
+ var/mob/living/carbon/human/virtual_reality/vr = owner
+ vr.return_to_lobby()
+ else
+ Remove(owner)
+
+/datum/action/detach_from_avatar
+ name = "Detach From Avatar"
+
+/datum/action/detach_from_avatar/Trigger()
+ if(..())
+ if(istype(owner, /mob/living/carbon/human/virtual_reality))
+ var/mob/living/carbon/human/virtual_reality/vr = owner
+ var/obj/item/clothing/glasses/vr_goggles/g = vr.real_me.glasses
+ g.vr_human = vr
+ vr.revert_to_reality(0)
+ else
+ Remove(owner)
diff --git a/code/modules/VR/vr_goggles.dm b/code/modules/VR/vr_goggles.dm
new file mode 100644
index 00000000000..c2a185b0ffa
--- /dev/null
+++ b/code/modules/VR/vr_goggles.dm
@@ -0,0 +1,41 @@
+//Glorified teleporter that puts you in a new human body.
+// it's """VR"""
+
+/obj/item/clothing/glasses/vr_goggles
+ desc = "A long time ago, people used these glasses to makes images from screens threedimensional."
+ name = "3D glasses"
+ icon_state = "3d"
+ item_state = "3d"
+ prescription_upgradable = 0
+ species_fit = list("Vox")
+ sprite_sheets = list(
+ "Vox" = 'icons/mob/species/vox/eyes.dmi'
+ )
+
+ var/you_die_in_the_game_you_die_for_real = FALSE
+ var/mob/living/carbon/human/virtual_reality/vr_human
+
+
+/obj/item/clothing/glasses/vr_goggles/Destroy()
+ ..()
+ vr_human.revert_to_reality(1)
+ cleanup_vr_avatar()
+
+/obj/item/clothing/glasses/vr_goggles/dropped()
+ ..()
+ if(vr_human)
+ vr_human.revert_to_reality(0)
+
+/obj/item/clothing/glasses/vr_goggles/proc/cleanup_vr_avatar()
+ if(vr_human)
+ vr_human = null
+
+/obj/item/clothing/glasses/vr_goggles/equipped()
+ ..()
+ var/mob/living/carbon/human/H = loc
+ spawn(1)
+ if(H.glasses == src)
+ if(vr_human == null)
+ vr_human = spawn_vr_avatar(H, "Lobby")
+ else
+ control_remote(H, vr_human)
\ No newline at end of file
diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm
index 577d5d5de46..f04f36a7bcc 100644
--- a/code/modules/admin/DB ban/functions.dm
+++ b/code/modules/admin/DB ban/functions.dm
@@ -127,7 +127,7 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration =
var/sql = "INSERT INTO [format_table_name("ban")] (`id`,`bantime`,`serverip`,`bantype`,`reason`,`job`,`duration`,`rounds`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`,`edits`,`unbanned`,`unbanned_datetime`,`unbanned_ckey`,`unbanned_computerid`,`unbanned_ip`) VALUES (null, Now(), '[serverip]', '[bantype_str]', '[reason]', '[job]', [(duration)?"[duration]":"0"], [(rounds)?"[rounds]":"0"], Now() + INTERVAL [(duration>0) ? duration : 0] MINUTE, '[ckey]', '[computerid]', '[ip]', '[a_ckey]', '[a_computerid]', '[a_ip]', '[who]', '[adminwho]', '', null, null, null, null, null)"
var/DBQuery/query_insert = dbcon.NewQuery(sql)
query_insert.Execute()
- to_chat(usr, "\blue Ban saved to database.")
+ to_chat(usr, "Ban saved to database.")
message_admins("[key_name_admin(usr)] has added a [bantype_str] for [ckey] [(job)?"([job])":""] [(duration > 0)?"([duration] minutes)":""] with the reason: \"[reason]\" to the ban database.",1)
if(announceinirc)
@@ -201,17 +201,17 @@ datum/admins/proc/DB_ban_unban(var/ckey, var/bantype, var/job = "")
ban_number++;
if(ban_number == 0)
- to_chat(usr, "\red Database update failed due to no bans fitting the search criteria. If this is not a legacy ban you should contact the database admin.")
+ to_chat(usr, "Database update failed due to no bans fitting the search criteria. If this is not a legacy ban you should contact the database admin.")
return
if(ban_number > 1)
- to_chat(usr, "\red Database update failed due to multiple bans fitting the search criteria. Note down the ckey, job and current time and contact the database admin.")
+ to_chat(usr, "Database update failed due to multiple bans fitting the search criteria. Note down the ckey, job and current time and contact the database admin.")
return
if(istext(ban_id))
ban_id = text2num(ban_id)
if(!isnum(ban_id))
- to_chat(usr, "\red Database update failed due to a ban ID mismatch. Contact the database admin.")
+ to_chat(usr, "Database update failed due to a ban ID mismatch. Contact the database admin.")
return
DB_ban_unban_by_id(ban_id)
@@ -302,11 +302,11 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
ban_number++;
if(ban_number == 0)
- to_chat(usr, "\red Database update failed due to a ban id not being present in the database.")
+ to_chat(usr, "Database update failed due to a ban id not being present in the database.")
return
if(ban_number > 1)
- to_chat(usr, "\red Database update failed due to multiple bans having the same ID. Contact the database admin.")
+ to_chat(usr, "Database update failed due to multiple bans having the same ID. Contact the database admin.")
return
if(!src.owner || !istype(src.owner, /client))
@@ -343,7 +343,7 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
establish_db_connection()
if(!dbcon.IsConnected())
- to_chat(usr, "\red Failed to establish database connection")
+ to_chat(usr, "Failed to establish database connection")
return
var/output = "
"
diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm
index 3d7b11390eb..6c8d642510a 100644
--- a/code/modules/admin/IsBanned.dm
+++ b/code/modules/admin/IsBanned.dm
@@ -15,7 +15,7 @@ world/IsBanned(key,address,computer_id)
//Guest Checking
if(!guests_allowed && IsGuestKey(key))
log_access("Failed Login: [key] [computer_id] [address] - Guests not allowed")
- // message_admins("\blue Failed Login: [key] - Guests not allowed")
+ // message_admins("Failed Login: [key] - Guests not allowed")
return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a BYOND account.")
//check if the IP address is a known Tor node
diff --git a/code/modules/admin/NewBan.dm b/code/modules/admin/NewBan.dm
index 9ba4ca4eeee..2e8fa4ba04b 100644
--- a/code/modules/admin/NewBan.dm
+++ b/code/modules/admin/NewBan.dm
@@ -172,7 +172,6 @@ var/savefile/Banlist
/datum/admins/proc/unbanpanel()
var/count = 0
var/dat
- //var/dat = "Unban Player: \blue(U) = Unban , (E) = Edit Ban\green (Total
"
Banlist.cd = "/base"
for(var/A in Banlist.dir)
count++
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index cb00562be9c..6853baf0755 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -844,8 +844,8 @@ var/global/nologevent = 0
to_chat(world, "Guests may no longer enter the game.")
else
to_chat(world, "Guests may now enter the game.")
- log_admin("[key_name(usr)] toggled guests game entering [guests_allowed?"":"dis"]allowed.")
- message_admins("\blue [key_name_admin(usr)] toggled guests game entering [guests_allowed?"":"dis"]allowed.", 1)
+ log_admin("[key_name(usr)] toggled guests game entering [guests_allowed ? "" : "dis"]allowed.")
+ message_admins("[key_name_admin(usr)] toggled guests game entering [guests_allowed ? "" : "dis"]allowed.", 1)
feedback_add_details("admin_verb","TGU") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/output_ai_laws()
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index a029e529856..0d479dcd2dd 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -2,6 +2,7 @@
var/list/admin_verbs_default = list(
/client/proc/deadmin_self, /*destroys our own admin datum so we can play as a regular player*/
/client/proc/hide_verbs, /*hides all our adminverbs*/
+ /client/proc/toggleadminhelpsound, /*toggles whether we hear bwoinks*/
/client/proc/cmd_mentor_check_new_players,
/client/proc/cmd_mentor_check_player_exp /* shows players by playtime */
)
@@ -88,7 +89,8 @@ var/list/admin_verbs_sounds = list(
/client/proc/play_local_sound,
/client/proc/play_sound,
/client/proc/play_server_sound,
- /client/proc/play_intercomm_sound
+ /client/proc/play_intercomm_sound,
+ /client/proc/stop_global_admin_sounds
)
var/list/admin_verbs_event = list(
/client/proc/object_talk,
@@ -155,7 +157,7 @@ var/list/admin_verbs_debug = list(
/client/proc/enable_debug_verbs,
/client/proc/toggledebuglogs,
/client/proc/qdel_toggle,
- /client/proc/gc_dump_hdl,
+ /client/proc/cmd_display_del_log,
/client/proc/debugNatureMapGenerator,
/client/proc/check_bomb_impacts,
/client/proc/test_movable_UI,
@@ -552,7 +554,7 @@ var/list/admin_verbs_snpc = list(
var/turf/epicenter = mob.loc
var/list/choices = list("Small Bomb", "Medium Bomb", "Big Bomb", "Custom Bomb")
- var/choice = input("What size explosion would you like to produce?") in choices
+ var/choice = input("What size explosion would you like to produce?") as null|anything in choices
switch(choice)
if(null)
return 0
@@ -631,7 +633,7 @@ var/list/admin_verbs_snpc = list(
for(var/mob/V in hearers(O))
V.show_message(message, 2)
log_admin("[key_name(usr)] made [O] at [O.x], [O.y], [O.z] make a sound")
- message_admins("\blue [key_name_admin(usr)] made [O] at [O.x], [O.y], [O.z] make a sound")
+ message_admins("[key_name_admin(usr)] made [O] at [O.x], [O.y], [O.z] make a sound")
feedback_add_details("admin_verb","MS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/togglebuildmodeself()
@@ -679,7 +681,7 @@ var/list/admin_verbs_snpc = list(
to_chat(usr, "Disabled air processing.")
feedback_add_details("admin_verb","KA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] used 'kill air'.")
- message_admins("\blue [key_name_admin(usr)] used 'kill air'.", 1)
+ message_admins("[key_name_admin(usr)] used 'kill air'.", 1)
/client/proc/deadmin_self()
set name = "De-admin self"
@@ -988,12 +990,12 @@ var/list/admin_verbs_snpc = list(
verbs -= admin_verbs_snpc
verbs += /client/proc/show_snpc_verbs
to_chat(src, "SNPC verbs have been toggled off.")
-
+
/client/proc/toggle_advanced_interaction()
set name = "Toggle Advanced Admin Interaction"
set category = "Admin"
set desc = "Allows you to interact with atoms such as buttons and doors, on top of regular machinery interaction."
-
+
if(!check_rights(R_ADMIN))
return
diff --git a/code/modules/admin/permissionverbs/permissionedit.dm b/code/modules/admin/permissionverbs/permissionedit.dm
index f1232cd4e78..ccacefc219b 100644
--- a/code/modules/admin/permissionverbs/permissionedit.dm
+++ b/code/modules/admin/permissionverbs/permissionedit.dm
@@ -63,7 +63,7 @@
establish_db_connection()
if(!dbcon.IsConnected())
- to_chat(usr, "\red Failed to establish database connection")
+ to_chat(usr, "Failed to establish database connection")
return
if(!adm_ckey || !new_rank)
@@ -91,14 +91,14 @@
insert_query.Execute()
var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.[format_table_name("admin_log")] (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added new admin [adm_ckey] to rank [new_rank]');")
log_query.Execute()
- to_chat(usr, "\blue New admin added.")
+ to_chat(usr, "New admin added.")
else
if(!isnull(admin_id) && isnum(admin_id))
var/DBQuery/insert_query = dbcon.NewQuery("UPDATE [format_table_name("admin")] SET rank = '[new_rank]' WHERE id = [admin_id]")
insert_query.Execute()
var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.[format_table_name("admin_log")] (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Edited the rank of [adm_ckey] to [new_rank]');")
log_query.Execute()
- to_chat(usr, "\blue Admin rank changed.")
+ to_chat(usr, "Admin rank changed.")
/datum/admins/proc/log_admin_permission_modification(var/adm_ckey, var/new_permission)
if(config.admin_legacy_system)
@@ -112,7 +112,7 @@
establish_db_connection()
if(!dbcon.IsConnected())
- to_chat(usr, "\red Failed to establish database connection")
+ to_chat(usr, "Failed to establish database connection")
return
if(!adm_ckey || !new_permission)
@@ -146,13 +146,13 @@
insert_query.Execute()
var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.[format_table_name("admin_log")] (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Removed permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]');")
log_query.Execute()
- to_chat(usr, "\blue Permission removed.")
+ to_chat(usr, "Permission removed.")
else //This admin doesn't have this permission, so we are adding it.
var/DBQuery/insert_query = dbcon.NewQuery("UPDATE [format_table_name("admin")] SET flags = '[admin_rights | new_permission]' WHERE id = [admin_id]")
insert_query.Execute()
var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.[format_table_name("admin_log")] (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]')")
log_query.Execute()
- to_chat(usr, "\blue Permission added.")
+ to_chat(usr, "Permission added.")
/datum/admins/proc/updateranktodb(ckey,newrank)
establish_db_connection()
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index 1f76781b90d..0be92ce25af 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -536,7 +536,8 @@
for(var/mob/living/simple_animal/hostile/poison/terror_spider/S in ts_spiderlist)
if(S.ckey)
spider_minds += S.mind
- dat += check_role_table("Terror Spiders", spider_minds)
+ if(spider_minds.len)
+ dat += check_role_table("Terror Spiders", spider_minds)
if(ticker.mode.ert.len)
dat += check_role_table("ERT", ticker.mode.ert)
diff --git a/code/modules/admin/sql_notes.dm b/code/modules/admin/sql_notes.dm
index 338993af58c..7b237db72e5 100644
--- a/code/modules/admin/sql_notes.dm
+++ b/code/modules/admin/sql_notes.dm
@@ -8,7 +8,7 @@
var/new_ckey = ckey(input(usr,"Who would you like to add a note for?","Enter a ckey",null) as text|null)
if(!new_ckey)
return
- new_ckey = sanitizeSQL(new_ckey)
+ new_ckey = ckey(new_ckey)
var/DBQuery/query_find_ckey = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey = '[new_ckey]'")
if(!query_find_ckey.Execute())
var/err = query_find_ckey.ErrorMsg()
@@ -19,7 +19,7 @@
return
else
target_ckey = new_ckey
- var/target_sql_ckey = sanitizeSQL(target_ckey)
+ var/target_sql_ckey = ckey(target_ckey)
if(!notetext)
notetext = input(usr,"Write your note","Add Note") as message|null
if(!notetext)
@@ -31,6 +31,8 @@
adminckey = usr.ckey
if(!adminckey)
return
+ else if(usr && (usr.ckey == ckey(adminckey))) // Don't ckeyize special note sources
+ adminckey = ckey(adminckey)
var/admin_sql_ckey = sanitizeSQL(adminckey)
if(!server)
if(config && config.server_name)
@@ -86,7 +88,7 @@
return
note_id = text2num(note_id)
var/target_ckey
- var/sql_ckey = sanitizeSQL(usr.ckey)
+ var/sql_ckey = usr.ckey
var/DBQuery/query_find_note_edit = dbcon.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id = [note_id]")
if(!query_find_note_edit.Execute())
var/err = query_find_note_edit.ErrorMsg()
@@ -128,7 +130,7 @@
if(!linkless)
output = navbar
if(target_ckey)
- var/target_sql_ckey = sanitizeSQL(target_ckey)
+ var/target_sql_ckey = ckey(target_ckey)
var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT id, timestamp, notetext, adminckey, last_editor, server FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]' ORDER BY timestamp")
if(!query_get_notes.Execute())
var/err = query_get_notes.ErrorMsg()
@@ -179,7 +181,7 @@
usr << browse(output, "window=show_notes;size=900x500")
/proc/show_player_info_irc(var/key as text)
- var/target_sql_ckey = sanitizeSQL(key)
+ var/target_sql_ckey = ckey(key)
var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT timestamp, notetext, adminckey, server FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]' ORDER BY timestamp")
if(!query_get_notes.Execute())
var/err = query_get_notes.ErrorMsg()
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index ef3199b3484..605c4acd1f3 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -34,35 +34,35 @@
if("1")
log_admin("[key_name(usr)] has spawned a traitor.")
if(!src.makeTraitors())
- to_chat(usr, "\red Unfortunately there weren't enough candidates available.")
+ to_chat(usr, "Unfortunately there weren't enough candidates available.")
if("2")
log_admin("[key_name(usr)] has spawned a changeling.")
if(!src.makeChanglings())
- to_chat(usr, "\red Unfortunately there weren't enough candidates available.")
+ to_chat(usr, "Unfortunately there weren't enough candidates available.")
if("3")
log_admin("[key_name(usr)] has spawned revolutionaries.")
if(!src.makeRevs())
- to_chat(usr, "\red Unfortunately there weren't enough candidates available.")
+ to_chat(usr, "Unfortunately there weren't enough candidates available.")
if("4")
log_admin("[key_name(usr)] has spawned a cultists.")
if(!src.makeCult())
- to_chat(usr, "\red Unfortunately there weren't enough candidates available.")
+ to_chat(usr, "Unfortunately there weren't enough candidates available.")
if("5")
log_admin("[key_name(usr)] has spawned a wizard.")
if(!src.makeWizard())
- to_chat(usr, "\red Unfortunately there weren't enough candidates available.")
+ to_chat(usr, "Unfortunately there weren't enough candidates available.")
if("6")
log_admin("[key_name(usr)] has spawned vampires.")
if(!src.makeVampires())
- to_chat(usr, "\red Unfortunately there weren't enough candidates available.")
+ to_chat(usr, "Unfortunately there weren't enough candidates available.")
if("7")
log_admin("[key_name(usr)] has spawned vox raiders.")
if(!src.makeVoxRaiders())
- to_chat(usr, "\red Unfortunately there weren't enough candidates available.")
+ to_chat(usr, "Unfortunately there weren't enough candidates available.")
if("8")
log_admin("[key_name(usr)] has spawned an abductor team.")
if(!src.makeAbductorTeam())
- to_chat(usr, "\red Unfortunately there weren't enough candidates available.")
+ to_chat(usr, "Unfortunately there weren't enough candidates available.")
else if(href_list["dbsearchckey"] || href_list["dbsearchadmin"] || href_list["dbsearchip"] || href_list["dbsearchcid"] || href_list["dbsearchbantype"])
var/adminckey = href_list["dbsearchadmin"]
@@ -298,7 +298,7 @@
ticker.delay_end = !ticker.delay_end
log_admin("[key_name(usr)] [ticker.delay_end ? "delayed the round end" : "has made the round end normally"].")
- message_admins("\blue [key_name_admin(usr)] [ticker.delay_end ? "delayed the round end" : "has made the round end normally"].", 1)
+ message_admins("[key_name_admin(usr)] [ticker.delay_end ? "delayed the round end" : "has made the round end normally"].", 1)
href_list["secretsadmin"] = "check_antagonist"
else if(href_list["simplemake"])
@@ -315,7 +315,7 @@
if("Yes") delmob = 1
log_admin("[key_name(usr)] has used rudimentary transformation on [key_name(M)]. Transforming to [href_list["simplemake"]]; deletemob=[delmob]")
- message_admins("\blue [key_name_admin(usr)] has used rudimentary transformation on [key_name_admin(M)]. Transforming to [href_list["simplemake"]]; deletemob=[delmob]", 1)
+ message_admins("[key_name_admin(usr)] has used rudimentary transformation on [key_name_admin(M)]. Transforming to [href_list["simplemake"]]; deletemob=[delmob]", 1)
switch(href_list["simplemake"])
if("observer") M.change_mob_type( /mob/dead/observer , null, null, delmob, 1 )
@@ -398,7 +398,7 @@
log_admin("[key_name(usr)] edited [banned_key]'s ban. Reason: [reason] Duration: [duration]")
ban_unban_log_save("[key_name(usr)] edited [banned_key]'s ban. Reason: [reason] Duration: [duration]")
- message_admins("\blue [key_name_admin(usr)] edited [banned_key]'s ban. Reason: [reason] Duration: [duration]", 1)
+ message_admins("[key_name_admin(usr)] edited [banned_key]'s ban. Reason: [reason] Duration: [duration]", 1)
Banlist.cd = "/base/[banfolder]"
to_chat(Banlist["reason"], reason)
to_chat(Banlist["temp"], temp)
@@ -434,8 +434,8 @@
feedback_inc("ban_appearance_unban", 1)
DB_ban_unban(M.ckey, BANTYPE_APPEARANCE)
appearance_unban(M)
- message_admins("\blue [key_name_admin(usr)] removed [key_name_admin(M)]'s appearance ban", 1)
- to_chat(M, "\red[usr.client.ckey] has removed your appearance ban.")
+ message_admins("[key_name_admin(usr)] removed [key_name_admin(M)]'s appearance ban", 1)
+ to_chat(M, "[usr.client.ckey] has removed your appearance ban.")
else switch(alert("Appearance ban [M.ckey]?",,"Yes","No", "Cancel"))
if("Yes")
@@ -448,14 +448,14 @@
DB_ban_record(BANTYPE_APPEARANCE, M, -1, reason)
appearance_fullban(M, "[reason]; By [usr.ckey] on [time2text(world.realtime)]")
add_note(M.ckey, "Appearance banned - [reason]", null, usr.ckey, 0)
- message_admins("\blue [key_name_admin(usr)] appearance banned [key_name_admin(M)]", 1)
- to_chat(M, "\redYou have been appearance banned by [usr.client.ckey].")
+ message_admins("[key_name_admin(usr)] appearance banned [key_name_admin(M)]", 1)
+ to_chat(M, "You have been appearance banned by [usr.client.ckey].")
to_chat(M, "The reason is: [reason]")
- to_chat(M, "\red Appearance ban can be lifted only upon request.")
+ to_chat(M, "Appearance ban can be lifted only upon request.")
if(config.banappeals)
- to_chat(M, "\red To try to resolve this matter head to [config.banappeals]")
+ to_chat(M, "To try to resolve this matter head to [config.banappeals]")
else
- to_chat(M, "\red No ban appeals URL has been set.")
+ to_chat(M, "No ban appeals URL has been set.")
if("No")
return
@@ -790,7 +790,7 @@
switch(alert("Temporary Ban?",,"Yes","No", "Cancel"))
if("Yes")
if(config.ban_legacy_system)
- to_chat(usr, "\red Your server is using the legacy banning system, which does not support temporary job bans. Consider upgrading. Aborting ban.")
+ to_chat(usr, "Your server is using the legacy banning system, which does not support temporary job bans. Consider upgrading. Aborting ban.")
return
var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null
if(!mins)
@@ -812,10 +812,10 @@
else
msg += ", [job]"
add_note(M.ckey, "Banned from [msg] - [reason]", null, usr.ckey, 0)
- message_admins("\blue [key_name_admin(usr)] banned [key_name_admin(M)] from [msg] for [mins] minutes", 1)
- to_chat(M, "\redYou have been jobbanned by [usr.client.ckey] from: [msg].")
+ message_admins("[key_name_admin(usr)] banned [key_name_admin(M)] from [msg] for [mins] minutes", 1)
+ to_chat(M, "You have been jobbanned by [usr.client.ckey] from: [msg].")
to_chat(M, "The reason is: [reason]")
- to_chat(M, "\red This jobban will be lifted in [mins] minutes.")
+ to_chat(M, "This jobban will be lifted in [mins] minutes.")
href_list["jobban2"] = 1 // lets it fall through and refresh
return 1
if("No")
@@ -832,10 +832,10 @@
if(!msg) msg = job
else msg += ", [job]"
add_note(M.ckey, "Banned from [msg] - [reason]", null, usr.ckey, 0)
- message_admins("\blue [key_name_admin(usr)] banned [key_name_admin(M)] from [msg]", 1)
- to_chat(M, "\redYou have been jobbanned by [usr.client.ckey] from: [msg].")
+ message_admins("[key_name_admin(usr)] banned [key_name_admin(M)] from [msg]", 1)
+ to_chat(M, "You have been jobbanned by [usr.client.ckey] from: [msg].")
to_chat(M, "The reason is: [reason]")
- to_chat(M, "\red Jobban can be lifted only upon request.")
+ to_chat(M, "Jobban can be lifted only upon request.")
href_list["jobban2"] = 1 // lets it fall through and refresh
return 1
if("Cancel")
@@ -865,8 +865,8 @@
else
continue
if(msg)
- message_admins("\blue [key_name_admin(usr)] unbanned [key_name_admin(M)] from [msg]", 1)
- to_chat(M, "\redYou have been un-jobbanned by [usr.client.ckey] from [msg].")
+ message_admins("[key_name_admin(usr)] unbanned [key_name_admin(M)] from [msg]", 1)
+ to_chat(M, "You have been un-jobbanned by [usr.client.ckey] from [msg].")
href_list["jobban2"] = 1 // lets it fall through and refresh
return 1
return 0 //we didn't do anything!
@@ -876,9 +876,9 @@
if(ismob(M))
if(!check_if_greater_rights_than(M.client))
return
- to_chat(M, "\red You have been kicked from the server")
+ to_chat(M, "You have been kicked from the server")
log_admin("[key_name(usr)] booted [key_name(M)].")
- message_admins("\blue [key_name_admin(usr)] booted [key_name_admin(M)].", 1)
+ message_admins("[key_name_admin(usr)] booted [key_name_admin(M)].", 1)
//M.client = null
del(M.client)
@@ -933,7 +933,7 @@
if(t)
if((alert("Do you want to unjobban [t]?","Unjobban confirmation", "Yes", "No") == "Yes") && t) //No more misclicks! Unless you do it twice.
log_admin("[key_name(usr)] removed [t]")
- message_admins("\blue [key_name_admin(usr)] removed [t]", 1)
+ message_admins("[key_name_admin(usr)] removed [t]", 1)
jobban_remove(t)
href_list["ban"] = 1 // lets it fall through and refresh
var/t_split = splittext(t, " - ")
@@ -960,17 +960,17 @@
return
AddBan(M.ckey, M.computer_id, reason, usr.ckey, 1, mins)
ban_unban_log_save("[usr.client.ckey] has banned [M.ckey]. - Reason: [reason] - This will be removed in [mins] minutes.")
- to_chat(M, "\redYou have been banned by [usr.client.ckey].\nReason: [reason].")
- to_chat(M, "\red This is a temporary ban, it will be removed in [mins] minutes.")
+ to_chat(M, "You have been banned by [usr.client.ckey].\nReason: [reason].")
+ to_chat(M, "This is a temporary ban, it will be removed in [mins] minutes.")
feedback_inc("ban_tmp",1)
DB_ban_record(BANTYPE_TEMP, M, mins, reason)
feedback_inc("ban_tmp_mins",mins)
if(config.banappeals)
- to_chat(M, "\red To try to resolve this matter head to [config.banappeals]")
+ to_chat(M, "To try to resolve this matter head to [config.banappeals]")
else
- to_chat(M, "\red No ban appeals URL has been set.")
+ to_chat(M, "No ban appeals URL has been set.")
log_admin("[key_name(usr)] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.")
- message_admins("\blue [key_name_admin(usr)] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.")
+ message_admins("[key_name_admin(usr)] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.")
del(M.client)
//qdel(M) // See no reason why to delete mob. Important stuff can be lost. And ban can be lifted before round ends.
@@ -984,15 +984,15 @@
AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0, M.lastKnownIP)
if("No")
AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0)
- to_chat(M, "\redYou have been banned by [usr.client.ckey].\nReason: [reason].")
- to_chat(M, "\red This is a permanent ban.")
+ to_chat(M, "You have been banned by [usr.client.ckey].\nReason: [reason].")
+ to_chat(M, "This is a permanent ban.")
if(config.banappeals)
- to_chat(M, "\red To try to resolve this matter head to [config.banappeals]")
+ to_chat(M, "To try to resolve this matter head to [config.banappeals]")
else
- to_chat(M, "\red No ban appeals URL has been set.")
+ to_chat(M, "No ban appeals URL has been set.")
ban_unban_log_save("[usr.client.ckey] has permabanned [M.ckey]. - Reason: [reason] - This is a permanent ban.")
log_admin("[key_name(usr)] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.")
- message_admins("\blue[key_name_admin(usr)] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.")
+ message_admins("[key_name_admin(usr)] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.")
feedback_inc("ban_perma",1)
DB_ban_record(BANTYPE_PERMA, M, -1, reason)
@@ -1094,7 +1094,7 @@
return alert(usr, "The game has already started.", null, null, null, null)
master_mode = href_list["c_mode2"]
log_admin("[key_name(usr)] set the mode as [master_mode].")
- message_admins("\blue [key_name_admin(usr)] set the mode as [master_mode].", 1)
+ message_admins("[key_name_admin(usr)] set the mode as [master_mode].", 1)
to_chat(world, "The mode is now: [master_mode]")
Game() // updates the main game menu
world.save_mode(master_mode)
@@ -1109,7 +1109,7 @@
return alert(usr, "The game mode has to be secret!", null, null, null, null)
secret_force_mode = href_list["f_secret2"]
log_admin("[key_name(usr)] set the forced secret mode as [secret_force_mode].")
- message_admins("\blue [key_name_admin(usr)] set the forced secret mode as [secret_force_mode].", 1)
+ message_admins("[key_name_admin(usr)] set the forced secret mode as [secret_force_mode].", 1)
Game() // updates the main game menu
.(href, list("f_secret"=1))
@@ -1124,7 +1124,7 @@
return
log_admin("[key_name(usr)] attempting to monkeyize [key_name(H)]")
- message_admins("\blue [key_name_admin(usr)] attempting to monkeyize [key_name_admin(H)]", 1)
+ message_admins("[key_name_admin(usr)] attempting to monkeyize [key_name_admin(H)]", 1)
H.monkeyize()
@@ -1140,7 +1140,7 @@
return
log_admin("[key_name(usr)] attempting to corgize [key_name(H)]")
- message_admins("\blue [key_name_admin(usr)] attempting to corgize [key_name_admin(H)]", 1)
+ message_admins("[key_name_admin(usr)] attempting to corgize [key_name_admin(H)]", 1)
H.corgize()
else if(href_list["makePAI"])
@@ -1164,7 +1164,7 @@
name = painame
log_admin("[key_name(usr)] attempting to pAIze [key_name(H)]")
- message_admins("\blue [key_name_admin(usr)] attempting to pAIze [key_name_admin(H)]", 1)
+ message_admins("[key_name_admin(usr)] attempting to pAIze [key_name_admin(H)]", 1)
H.paize(name)
else if(href_list["forcespeech"])
@@ -1179,7 +1179,7 @@
M.say(speech)
speech = sanitize(speech) // Nah, we don't trust them
log_admin("[key_name(usr)] forced [key_name(M)] to say: [speech]")
- message_admins("\blue [key_name_admin(usr)] forced [key_name_admin(M)] to say: [speech]")
+ message_admins("[key_name_admin(usr)] forced [key_name_admin(M)] to say: [speech]")
else if(href_list["sendtoprison"])
if(!check_rights(R_ADMIN)) return
@@ -1223,9 +1223,9 @@
prisoner.equip_to_slot_or_del(new /obj/item/clothing/under/color/orange(prisoner), slot_w_uniform)
prisoner.equip_to_slot_or_del(new /obj/item/clothing/shoes/orange(prisoner), slot_shoes)
- to_chat(M, "\red You have been sent to the prison station!")
+ to_chat(M, "You have been sent to the prison station!")
log_admin("[key_name(usr)] sent [key_name(M)] to the prison station.")
- message_admins("\blue [key_name_admin(usr)] sent [key_name_admin(M)] to the prison station.", 1)
+ message_admins("[key_name_admin(usr)] sent [key_name_admin(M)] to the prison station.", 1)
else if(href_list["sendbacktolobby"])
if(!check_rights(R_ADMIN))
@@ -1278,7 +1278,7 @@
sleep(5)
M.loc = pick(tdome1)
spawn(50)
- to_chat(M, "\blue You have been sent to the Thunderdome.")
+ to_chat(M, "You have been sent to the Thunderdome.")
log_admin("[key_name(usr)] has sent [key_name(M)] to the thunderdome. (Team 1)")
message_admins("[key_name_admin(usr)] has sent [key_name_admin(M)] to the thunderdome. (Team 1)", 1)
@@ -1308,7 +1308,7 @@
sleep(5)
M.loc = pick(tdome2)
spawn(50)
- to_chat(M, "\blue You have been sent to the Thunderdome.")
+ to_chat(M, "You have been sent to the Thunderdome.")
log_admin("[key_name(usr)] has sent [key_name(M)] to the thunderdome. (Team 2)")
message_admins("[key_name_admin(usr)] has sent [key_name_admin(M)] to the thunderdome. (Team 2)", 1)
@@ -1330,7 +1330,7 @@
sleep(5)
M.loc = pick(tdomeadmin)
spawn(50)
- to_chat(M, "\blue You have been sent to the Thunderdome.")
+ to_chat(M, "You have been sent to the Thunderdome.")
log_admin("[key_name(usr)] has sent [key_name(M)] to the thunderdome. (Admin.)")
message_admins("[key_name_admin(usr)] has sent [key_name_admin(M)] to the thunderdome. (Admin.)", 1)
@@ -1364,7 +1364,7 @@
sleep(5)
M.loc = pick(tdomeobserve)
spawn(50)
- to_chat(M, "\blue You have been sent to the Thunderdome.")
+ to_chat(M, "You have been sent to the Thunderdome.")
log_admin("[key_name(usr)] has sent [key_name(M)] to the thunderdome. (Observer.)")
message_admins("[key_name_admin(usr)] has sent [key_name_admin(M)] to the thunderdome. (Observer.)", 1)
@@ -1386,7 +1386,7 @@
sleep(5)
M.loc = pick(aroomwarp)
spawn(50)
- to_chat(M, "\blue You have been sent to the Admin Room!.")
+ to_chat(M, "You have been sent to the Admin Room!.")
log_admin("[key_name(usr)] has sent [key_name(M)] to the Admin Room")
message_admins("[key_name_admin(usr)] has sent [key_name_admin(M)] to the Admin Room", 1)
@@ -1400,7 +1400,7 @@
return
L.revive()
- message_admins("\red Admin [key_name_admin(usr)] healed / revived [key_name_admin(L)]!", 1)
+ message_admins("Admin [key_name_admin(usr)] healed / revived [key_name_admin(L)]!", 1)
log_admin("[key_name(usr)] healed / revived [key_name(L)]")
else if(href_list["makeai"])
@@ -1414,7 +1414,7 @@
if(alert(usr, "Confirm make ai?",, "Yes", "No") != "Yes")
return
- message_admins("\red Admin [key_name_admin(usr)] AIized [key_name_admin(H)]!", 1)
+ message_admins("Admin [key_name_admin(usr)] AIized [key_name_admin(H)]!", 1)
log_admin("[key_name(usr)] AIized [key_name(H)]")
var/mob/living/silicon/ai/ai_character = H.AIize()
ai_character.moveToAILandmark()
@@ -1619,7 +1619,7 @@
log_admin("[key_name(H)] got their cookie, spawned by [key_name(src.owner)]")
message_admins("[key_name_admin(H)] got their cookie, spawned by [key_name_admin(src.owner)]")
feedback_inc("admin_cookies_spawned",1)
- to_chat(H, "\blue Your prayers have been answered!! You received the best cookie!")
+ to_chat(H, "Your prayers have been answered!! You received the best cookie!")
else if(href_list["BlueSpaceArtillery"])
if(!check_rights(R_ADMIN|R_EVENT)) return
@@ -1741,33 +1741,42 @@
btypes += "Heal Over Time"
btypes += "Permanent Regeneration"
btypes += "Super Powers"
- var/blessing = input(src.owner, "How would you like to bless [M]?", "Its good to be good...", "") as null|anything in btypes
+ var/blessing = input(owner, "How would you like to bless [M]?", "Its good to be good...", "") as null|anything in btypes
if(!(blessing in btypes))
return
+ var/logmsg = null
switch(blessing)
if("To Arrivals")
M.forceMove(pick(latejoin))
to_chat(M, "You are abruptly pulled through space!")
+ logmsg = "a teleport to arrivals."
if("Moderate Heal")
M.adjustBruteLoss(-25)
M.adjustFireLoss(-25)
M.adjustToxLoss(-25)
M.adjustOxyLoss(-25)
to_chat(M,"You feel invigorated!")
+ logmsg = "a moderate heal."
if("Heal Over Time")
H.reagents.add_reagent("salglu_solution", 30)
H.reagents.add_reagent("salbutamol", 20)
H.reagents.add_reagent("spaceacillin", 20)
+ logmsg = "a heal over time."
if("Permanent Regeneration")
H.dna.SetSEState(REGENERATEBLOCK, 1)
genemutcheck(H, REGENERATEBLOCK, null, MUTCHK_FORCED)
H.update_mutations()
+ logmsg = "permanent regeneration."
if("Super Powers")
var/list/default_genes = list(REGENERATEBLOCK, NOBREATHBLOCK, COLDBLOCK)
for(var/gene in default_genes)
H.dna.SetSEState(gene, 1)
genemutcheck(H, gene, null, MUTCHK_FORCED)
H.update_mutations()
+ logmsg = "superpowers."
+ if(logmsg)
+ log_admin("[key_name(owner)] answered [key_name(M)]'s prayer with a blessing: [logmsg]")
+ message_admins("[key_name_admin(owner)] answered [key_name_admin(M)]'s prayer with a blessing: [logmsg]")
else if(href_list["Smite"])
if(!check_rights(R_ADMIN))
return
@@ -1784,9 +1793,10 @@
ptypes += "Cluwne"
ptypes += "Mutagen Cookie"
ptypes += "Hellwater Cookie"
- var/punishment = input(src.owner, "How would you like to smite [M]?", "Its good to be baaaad...", "") as null|anything in ptypes
+ var/punishment = input(owner, "How would you like to smite [M]?", "Its good to be baaaad...", "") as null|anything in ptypes
if(!(punishment in ptypes))
return
+ var/logmsg = null
switch(punishment)
if("Lightning bolt")
M.electrocute_act(5, "Lightning Bolt", safety=1)
@@ -1794,20 +1804,25 @@
M.adjustFireLoss(75)
M.Weaken(5)
to_chat(M, "The gods have punished you for your sins!")
+ logmsg = "a lightning bolt."
if("Brain Damage")
H.adjustBrainLoss(75)
+ logmsg = "75 brain damage."
if("Fire Death")
to_chat(M,"You feel hotter than usual. Maybe you should lowe-wait, is that your hand melting?")
var/turf/simulated/T = get_turf(M)
new /obj/effect/hotspot(T)
M.adjustFireLoss(150)
+ logmsg = "a firey death."
if("Honk Tumor")
if(!H.get_int_organ(/obj/item/organ/internal/honktumor))
var/obj/item/organ/internal/organ = new /obj/item/organ/internal/honktumor
to_chat(H, "Life seems funnier, somehow.")
organ.insert(H)
+ logmsg = "a honk tumor."
if("Cluwne")
H.makeCluwne()
+ logmsg = "cluwned."
if("Mutagen Cookie")
var/obj/item/weapon/reagent_containers/food/snacks/cookie/evilcookie = new /obj/item/weapon/reagent_containers/food/snacks/cookie
evilcookie.reagents.add_reagent("mutagen", 10)
@@ -1815,6 +1830,7 @@
evilcookie.bitesize = 100
H.drop_l_hand()
H.equip_to_slot_or_del(evilcookie, slot_l_hand)
+ logmsg = "a mutagen cookie."
if("Hellwater Cookie")
var/obj/item/weapon/reagent_containers/food/snacks/cookie/evilcookie = new /obj/item/weapon/reagent_containers/food/snacks/cookie
evilcookie.reagents.add_reagent("hell_water", 25)
@@ -1822,8 +1838,13 @@
evilcookie.bitesize = 100
H.drop_l_hand()
H.equip_to_slot_or_del(evilcookie, slot_l_hand)
+ logmsg = "a hellwater cookie."
if("Gib")
+ logmsg = "gibbed."
M.gib(FALSE)
+ if(logmsg)
+ log_admin("[key_name(owner)] answered [key_name(M)]'s prayer with a smiting: [logmsg]")
+ message_admins("[key_name_admin(owner)] answered [key_name_admin(M)]'s prayer with a smiting: [logmsg]")
else if(href_list["FaxReplyTemplate"])
if(!check_rights(R_ADMIN))
return
@@ -1965,7 +1986,7 @@
usr << browse(data, "window=[B.name]")
else
- to_chat(usr, "\red The faxed item is not viewable. This is probably a bug, and should be reported on the tracker: [fax.type]")
+ to_chat(usr, "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))
@@ -2097,14 +2118,14 @@
if(destination != "All Departments")
if(!fax.receivefax(P))
- to_chat(src.owner, "\red Message transmission failed.")
+ to_chat(src.owner, "Message transmission failed.")
return
else
for(var/obj/machinery/photocopier/faxmachine/F in allfaxes)
if(is_station_level(F.z))
spawn(0)
if(!F.receivefax(P))
- to_chat(src.owner, "\red Message transmission to [F.department] failed.")
+ to_chat(src.owner, "Message transmission to [F.department] failed.")
var/datum/fax/admin/A = new /datum/fax/admin()
A.name = P.name
@@ -2119,7 +2140,7 @@
A.sent_by = usr
A.sent_at = world.time
- to_chat(src.owner, "\blue Message transmitted successfully.")
+ to_chat(src.owner, "Message transmitted successfully.")
if(notify == "Yes")
var/mob/living/carbon/human/H = sender
if(istype(H) && H.stat == CONSCIOUS && (istype(H.l_ear, /obj/item/device/radio/headset) || istype(H.r_ear, /obj/item/device/radio/headset)))
@@ -2419,30 +2440,30 @@
feedback_add_details("admin_secrets_fun_used","Grav")
if(gravity_is_on)
log_admin("[key_name(usr)] toggled gravity on.", 1)
- message_admins("\blue [key_name_admin(usr)] toggled gravity on.", 1)
+ message_admins("[key_name_admin(usr)] toggled gravity on.", 1)
event_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)
+ message_admins("[key_name_admin(usr)] toggled gravity off.", 1)
event_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("power")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","P")
log_admin("[key_name(usr)] made all areas powered", 1)
- message_admins("\blue [key_name_admin(usr)] made all areas powered", 1)
+ message_admins("[key_name_admin(usr)] made all areas powered", 1)
power_restore()
if("unpower")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","UP")
log_admin("[key_name(usr)] made all areas unpowered", 1)
- message_admins("\blue [key_name_admin(usr)] made all areas unpowered", 1)
+ message_admins("[key_name_admin(usr)] made all areas unpowered", 1)
power_failure()
if("quickpower")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","QP")
log_admin("[key_name(usr)] made all SMESs powered", 1)
- message_admins("\blue [key_name_admin(usr)] made all SMESs powered", 1)
+ message_admins("[key_name_admin(usr)] made all SMESs powered", 1)
power_restore_quick()
if("prisonwarp")
if(!ticker)
@@ -2450,7 +2471,7 @@
return
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","PW")
- message_admins("\blue [key_name_admin(usr)] teleported all players to the prison station.", 1)
+ message_admins("[key_name_admin(usr)] teleported all players to the prison station.", 1)
for(var/mob/living/carbon/human/H in mob_list)
var/turf/loc = find_loc(H)
var/security = 0
@@ -2517,7 +2538,7 @@
A.mind.objectives += new_objective
ticker.mode.greet_traitor(A.mind)
ticker.mode.finalize_traitor(A.mind)
- message_admins("\blue [key_name_admin(usr)] used everyone is a traitor secret. Objective is [objective]", 1)
+ message_admins("[key_name_admin(usr)] used everyone is a traitor secret. Objective is [objective]", 1)
log_admin("[key_name(usr)] used everyone is a traitor secret. Objective is [objective]")
if("togglebombcap")
@@ -2557,20 +2578,20 @@
var/Message = rand(1,4)
switch(Message)
if(1)
- M.show_message(text("\blue You shudder as if cold..."), 1)
+ M.show_message(text("You shudder as if cold..."), 1)
if(2)
- M.show_message(text("\blue You feel something gliding across your back..."), 1)
+ M.show_message(text("You feel something gliding across your back..."), 1)
if(3)
- M.show_message(text("\blue Your eyes twitch, you feel like something you can't see is here..."), 1)
+ M.show_message(text("Your eyes twitch, you feel like something you can't see is here..."), 1)
if(4)
- M.show_message(text("\blue You notice something moving out of the corner of your eye, but nothing is there..."), 1)
+ M.show_message(text("You notice something moving out of the corner of your eye, but nothing is there..."), 1)
for(var/obj/W in orange(5,M))
if(prob(25) && !W.anchored)
step_rand(W)
sleep(rand(100,1000))
for(var/mob/M in player_list)
if(M.stat != 2)
- M.show_message(text("\blue The chilling wind suddenly stops..."), 1)
+ M.show_message(text("The chilling wind suddenly stops..."), 1)
/* if("shockwave")
ok = 1
to_chat(world, "ALERT: STATION STRESS CRITICAL")
@@ -2754,22 +2775,22 @@
message_admins("[key_name_admin(usr)] tried starting a Thunderdome match, but no ghosts signed up.")
if("securitylevel0")
set_security_level(0)
- message_admins("\blue [key_name_admin(usr)] change security level to Green.", 1)
+ message_admins("[key_name_admin(usr)] change security level to Green.", 1)
if("securitylevel1")
set_security_level(1)
- message_admins("\blue [key_name_admin(usr)] change security level to Blue.", 1)
+ message_admins("[key_name_admin(usr)] change security level to Blue.", 1)
if("securitylevel2")
set_security_level(2)
- message_admins("\blue [key_name_admin(usr)] change security level to Red.", 1)
+ message_admins("[key_name_admin(usr)] change security level to Red.", 1)
if("securitylevel3")
set_security_level(3)
- message_admins("\blue [key_name_admin(usr)] change security level to Gamma.", 1)
+ message_admins("[key_name_admin(usr)] change security level to Gamma.", 1)
if("securitylevel4")
set_security_level(4)
- message_admins("\blue [key_name_admin(usr)] change security level to Epsilon.", 1)
+ message_admins("[key_name_admin(usr)] change security level to Epsilon.", 1)
if("securitylevel5")
set_security_level(5)
- message_admins("\blue [key_name_admin(usr)] change security level to Delta.", 1)
+ message_admins("[key_name_admin(usr)] change security level to Delta.", 1)
if("moveminingshuttle")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","ShM")
@@ -3132,7 +3153,7 @@
error_viewer.showTo(usr, locate(href_list["viewruntime_backto"]), href_list["viewruntime_linear"])
else
error_viewer.showTo(usr, null, href_list["viewruntime_linear"])
-
+
else if(href_list["add_station_goal"])
if(!check_rights(R_EVENT))
return
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index 972406bbdb3..bf6575b6659 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -109,13 +109,13 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
switch(selected_type)
if("Mentorhelp")
- msg = "[selected_type]: [key_name(src, 1, 1, selected_type)] (?) (PP) (VV) (SM) ([admin_jump_link(mob)]) (CA) (REJT) [ai_found ? " (CL)" : ""] (PP) (TAKE) :[msg]"
+ msg = "[selected_type]: [key_name(src, 1, 1, selected_type)] (?) (PP) (VV) (SM) ([admin_jump_link(mob)]) (CA) (REJT) [ai_found ? " (CL)" : ""] (TAKE) :[msg]"
for(var/client/X in mentorholders + modholders + adminholders)
if(X.prefs.sound & SOUND_ADMINHELP)
X << 'sound/effects/adminhelp.ogg'
to_chat(X, msg)
if("Adminhelp")
- msg = "[selected_type]: [key_name(src, 1, 1, selected_type)] (?) (PP) (VV) (SM) ([admin_jump_link(mob)]) (CA) (REJT) [ai_found ? " (CL)" : ""] (PP) (TAKE) :[msg]"
+ msg = "[selected_type]: [key_name(src, 1, 1, selected_type)] (?) (PP) (VV) (SM) ([admin_jump_link(mob)]) (CA) (REJT) [ai_found ? " (CL)" : ""] (TAKE) :[msg]"
for(var/client/X in modholders + adminholders)
if(X.prefs.sound & SOUND_ADMINHELP)
X << 'sound/effects/adminhelp.ogg'
diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm
index 5de3178e7ff..7e94010b3b4 100644
--- a/code/modules/admin/verbs/adminpm.dm
+++ b/code/modules/admin/verbs/adminpm.dm
@@ -162,8 +162,8 @@
C.ckey_last_pm = ckey*/
//play the recieving admin the adminhelp sound (if they have them enabled)
- //non-admins shouldn't be able to disable this
- if(C.prefs.sound & SOUND_ADMINHELP)
+ //non-admins always hear the sound, as they cannot toggle it
+ if((!C.holder) || (C.prefs.sound & SOUND_ADMINHELP))
C << 'sound/effects/adminhelp.ogg'
log_admin("PM: [key_name(src)]->[key_name(C)]: [msg]")
@@ -197,8 +197,8 @@
sanitize(msg)
if(length(msg) > 400) // TODO: if message length is over 400, divide it up into seperate messages, the message length restriction is based on IRC limitations. Probably easier to do this on the bots ends.
- to_chat(src, "\red Your message was not sent because it was more then 400 characters find your message below for ease of copy/pasting")
- to_chat(src, "\blue [msg]")
+ to_chat(src, "Your message was not sent because it was more then 400 characters find your message below for ease of copy/pasting")
+ to_chat(src, "[msg]")
return
send2adminirc("PlayerPM from [key_name(src)]: [html_decode(msg)]")
@@ -210,4 +210,4 @@
if(X == src)
continue
if(check_rights(R_ADMIN|R_MOD|R_MENTOR, 0, X.mob))
- to_chat(X, "PM: [key_name(src, X, 0)]->IRC-Admins: \blue [msg]")
+ to_chat(X, "PM: [key_name(src, X, 0)]->IRC-Admins:[msg]")
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index 59ea8992889..28a0532bf13 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -296,7 +296,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
M:Alienize()
feedback_add_details("admin_verb","MKAL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] made [key_name(M)] into an alien.")
- message_admins("\blue [key_name_admin(usr)] made [key_name(M)] into an alien.", 1)
+ message_admins("[key_name_admin(usr)] made [key_name(M)] into an alien.", 1)
else
alert("Invalid mob")
@@ -316,7 +316,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
M:slimeize()
feedback_add_details("admin_verb","MKMET") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] made [key_name(M)] into a slime.")
- message_admins("\blue [key_name_admin(usr)] made [key_name(M)] into a slime.", 1)
+ message_admins("[key_name_admin(usr)] made [key_name(M)] into a slime.", 1)
else
alert("Invalid mob")
@@ -336,7 +336,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(S)
S.create(M)
log_admin("[key_name(src)] has turned [M.key] into a Superhero.")
- message_admins("\blue [key_name_admin(usr)] made [key_name(M)] into a Superhero.", 1)
+ message_admins("[key_name_admin(usr)] made [key_name(M)] into a Superhero.", 1)
else
alert("Invalid mob")
@@ -424,7 +424,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
alert("Invalid mob")
feedback_add_details("admin_verb","GFA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(src)] has granted [M.key] full access.")
- message_admins("\blue [key_name_admin(usr)] has granted [M.key] full access.", 1)
+ message_admins("[key_name_admin(usr)] has granted [M.key] full access.", 1)
/client/proc/cmd_assume_direct_control(var/mob/M in mob_list)
set category = "Admin"
@@ -440,7 +440,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
else
var/mob/dead/observer/ghost = new/mob/dead/observer(M,1)
ghost.ckey = M.ckey
- message_admins("\blue [key_name_admin(usr)] assumed direct control of [M].", 1)
+ message_admins("[key_name_admin(usr)] assumed direct control of [M].", 1)
log_admin("[key_name(usr)] assumed direct control of [M].")
var/mob/adminmob = src.mob
M.ckey = src.ckey
@@ -574,67 +574,35 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
alert("Invalid mob")
return
- //log_admin("[key_name(src)] has alienized [M.key].")
- var/list/dresspacks = list(
+ var/list/choices = list(
"strip",
"as job...",
- "Engineer RIG",
- "CE RIG",
- "Mining RIG",
- "Syndi RIG",
- "Wizard RIG",
- "Medical RIG",
- "Atmos RIG",
- "standard space gear",
- "tournament standard red",
- "tournament standard green",
- "tournament gangster",
- "tournament chef",
- "tournament janitor",
- "pirate",
- "space pirate",
- "soviet tourist",
- "soviet soldier",
- "soviet admiral",
- "tunnel clown",
- "mime assassin",
- "survivor",
- "greytide",
- "greytide leader",
- "greytide xeno",
- "masked killer",
- "singuloth knight",
- "dark lord",
- "assassin",
- "spy",
- "vox",
- "death commando",
- "syndicate agent",
- "syndicate operative",
- "syndicate bomber",
- "syndicate strike team",
- "syndicate officer",
- "chrono legionnaire",
- "blue wizard",
- "red wizard",
- "marisa wizard",
- "emergency response team member",
- "emergency response team leader",
- "nt vip guest",
- "nt navy officer", // now in jobs list
- "nt navy captain",
- "nt special ops officer", // now in jobs list
- "nt special ops formal",
- )
+ "emergency response team member",
+ "emergency response team leader"
+ )
+
+ var/admin_outfits = subtypesof(/datum/outfit/admin)
+ for(var/type in admin_outfits)
+ var/datum/outfit/O = type
+ var/name = initial(O.name)
+ if(name != "Naked")
+ choices[initial(O.name)] = type
+
var/dostrip = 0
switch(alert("Strip [M] before dressing?", "Strip?", "Yes", "No", "Cancel"))
if("Yes")
dostrip = 1
if("Cancel")
return
- var/dresscode = input("Select dress for [M]", "Robust quick dress shop") as null|anything in dresspacks
+
+ var/dresscode = input("Select dress for [M]", "Robust quick dress shop") as null|anything in choices
if(isnull(dresscode))
return
+
+ var/datum/outfit/O
+ if(!(dresscode in list("strip", "as job...", "emergency response team member", "emergency response team leader")))
+ O = choices[dresscode]
+
var/datum/job/jobdatum
if(dresscode == "as job...")
var/jobname = input("Select job", "Robust quick dress shop") as null|anything in get_all_jobs()
@@ -648,6 +616,8 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(istype(I, /obj/item/organ))
continue
qdel(I)
+
+
switch(dresscode)
if("strip")
//do nothing
@@ -657,495 +627,6 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(jobdatum)
dresscode = "[jobdatum.title]"
jobdatum.equip(M)
- equip_special_id(M,jobdatum.get_access(),jobdatum.title, jobdatum.idtype)
-
- if("standard space gear")
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space(M), slot_head)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
- var /obj/item/weapon/tank/jetpack/J = new /obj/item/weapon/tank/jetpack/oxygen(M)
- M.equip_to_slot_or_del(J, slot_back)
- J.turn_on()
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/breath(M), slot_wear_mask)
- J.Topic(null, list("stat" = 1))
- equip_special_id(M,get_all_accesses(), "Space Explorer", /obj/item/weapon/card/id)
-
- if("Engineer RIG", "CE RIG", "Mining RIG", "Syndi RIG", "Wizard RIG", "Medical RIG", "Atmos RIG")
- if(dresscode=="Engineer RIG")
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig(M), slot_head)
- else if(dresscode=="CE RIG")
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/elite(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/elite(M), slot_head)
- else if(dresscode=="Mining RIG")
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/mining(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/mining(M), slot_head)
- else if(dresscode=="Syndi RIG")
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/syndi(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/syndi(M), slot_head)
- else if(dresscode=="Wizard RIG")
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/wizard(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/wizard(M), slot_head)
- else if(dresscode=="Medical RIG")
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/medical(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/medical(M), slot_head)
- else if(dresscode=="Atmos RIG")
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/atmos(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/atmos(M), slot_head)
- var /obj/item/weapon/tank/jetpack/J = new /obj/item/weapon/tank/jetpack/oxygen(M)
- M.equip_to_slot_or_del(J, slot_back)
- J.turn_on()
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/breath(M), slot_wear_mask)
- equip_special_id(M,get_all_accesses(), "RIG Tester", /obj/item/weapon/card/id)
- J.Topic(null, list("stat" = 1))
-
- if("tournament standard red", "tournament standard green") //we think stunning weapon is too overpowered to use it on tournaments. --rastaf0
- if(dresscode=="tournament standard red")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/color/red(M), slot_w_uniform)
- else
- M.equip_to_slot_or_del(new /obj/item/clothing/under/color/green(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/thunderdome(M), slot_head)
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/destroyer(M), slot_r_hand)
- M.equip_to_slot_or_del(new /obj/item/weapon/kitchen/knife(M), slot_l_hand)
- M.equip_to_slot_or_del(new /obj/item/weapon/grenade/smokebomb(M), slot_r_store)
-
- if("tournament gangster") //gangster are supposed to fight each other. --rastaf0
- M.equip_to_slot_or_del(new /obj/item/clothing/under/det(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/det_suit(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(M), slot_glasses)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/det_hat(M), slot_head)
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/automatic/proto(M), slot_r_hand)
- M.equip_to_slot_or_del(new /obj/item/ammo_box/a357(M), slot_l_store)
-
- if("tournament chef") //Steven Seagal FTW
- M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/chef(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/chef(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/chefhat(M), slot_head)
- M.equip_to_slot_or_del(new /obj/item/weapon/kitchen/rollingpin(M), slot_r_hand)
- M.equip_to_slot_or_del(new /obj/item/weapon/kitchen/knife(M), slot_l_hand)
- M.equip_to_slot_or_del(new /obj/item/weapon/kitchen/knife(M), slot_r_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/kitchen/knife(M), slot_s_store)
-
- if("tournament janitor")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/janitor(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
- var/obj/item/weapon/storage/backpack/backpack = new(M)
- for(var/obj/item/I in backpack)
- qdel(I)
- M.equip_to_slot_or_del(backpack, slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/mop(M), slot_r_hand)
- var/obj/item/weapon/reagent_containers/glass/bucket/bucket = new(M)
- bucket.reagents.add_reagent("water", 70)
- M.equip_to_slot_or_del(bucket, slot_l_hand)
- M.equip_to_slot_or_del(new /obj/item/weapon/grenade/chem_grenade/cleaner(M), slot_r_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/grenade/chem_grenade/cleaner(M), slot_l_store)
- M.equip_to_slot_or_del(new /obj/item/stack/tile/plasteel(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/stack/tile/plasteel(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/stack/tile/plasteel(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/stack/tile/plasteel(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/stack/tile/plasteel(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/stack/tile/plasteel(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/stack/tile/plasteel(M), slot_in_backpack)
-
- if("pirate")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/pirate(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/bandana(M), slot_head)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/eyepatch(M), slot_glasses)
- M.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword/pirate(M), slot_r_hand)
- equip_special_id(M,list(access_maint_tunnels), "Pirate", /obj/item/weapon/card/id)
-
- if("space pirate") // not spaceworthy, just has fancier coat.
- M.equip_to_slot_or_del(new /obj/item/clothing/under/pirate(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/pirate(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/pirate(M), slot_head)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/eyepatch(M), slot_glasses)
- M.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword/pirate(M), slot_r_hand)
- equip_special_id(M,list(access_maint_tunnels), "Space Pirate", /obj/item/weapon/card/id)
-
- if("tunnel clown")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/clown(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/clown_shoes(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/black(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(M), slot_wear_mask)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full/multitool(M), slot_belt)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(M), slot_glasses)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/hooded/chaplain_hoodie(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/food/snacks/grown/banana(M), slot_l_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/bikehorn(M), slot_r_store)
- equip_special_id(M,list(access_clown, access_theatre, access_maint_tunnels), "Tunnel Clown", /obj/item/weapon/card/id)
- M.equip_to_slot_or_del(new /obj/item/device/flashlight(M), slot_in_backpack)
- var/obj/item/weapon/twohanded/fireaxe/fire_axe = new(M)
- M.equip_to_slot_or_del(fire_axe, slot_r_hand)
-
-
- if("mime assassin")
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/mime(M), slot_back)
- if(M.gender == FEMALE)
- M.equip_or_collect(new /obj/item/clothing/under/sexymime(M), slot_w_uniform)
- M.equip_or_collect(new /obj/item/clothing/mask/gas/sexymime(M), slot_wear_mask)
- else
- M.equip_or_collect(new /obj/item/clothing/under/mime(M), slot_w_uniform)
- M.equip_or_collect(new /obj/item/clothing/mask/gas/mime(M), slot_wear_mask)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/white(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/beret(M), slot_head)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full/multitool(M), slot_belt)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(M), slot_glasses)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/suspenders(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/syndie_kit/caneshotgun, slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/toy/crayon/mime, slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/automatic/pistol(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/suppressor(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/ammo_casing/shotgun/incendiary/dragonsbreath(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/ammo_casing/shotgun/incendiary/dragonsbreath(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/pen/sleepy(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/weapon/reagent_containers/food/snacks/syndidonkpocket(M), slot_in_backpack)
- var/obj/item/device/pda/mime/pda = new(M)
- pda.owner = M.real_name
- pda.ownjob = "Mime"
- pda.name = "PDA-[M.real_name] ([pda.ownjob])"
- M.equip_to_slot_or_del(pda, slot_wear_pda)
- equip_special_id(M,list(access_mime, access_theatre, access_maint_tunnels), "Mime", /obj/item/weapon/card/id/syndicate)
- M.equip_to_slot_or_del(new /obj/item/device/flashlight(M), slot_in_backpack)
-
- if("survivor")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/overalls(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/latex(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
- equip_special_id(M,list(access_maint_tunnels), "Survivor", /obj/item/weapon/card/id)
- for(var/obj/item/carried_item in M.contents)
- if(!istype(carried_item, /obj/item/weapon/implant))
- carried_item.add_blood(M)
-
- if("greytide")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas(M), slot_wear_mask)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/toolbox/mechanical(M), slot_l_hand)
- M.equip_to_slot_or_del(new /obj/item/flag/grey(M), slot_r_hand)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
- M.equip_to_slot_or_del(new /obj/item/device/flashlight(M), slot_in_backpack)
- equip_special_id(M,list(access_maint_tunnels), "Greytide", /obj/item/weapon/card/id)
-
- if("greytide leader")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas(M), slot_wear_mask)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/toolbox/mechanical(M), slot_l_hand)
- M.equip_to_slot_or_del(new /obj/item/flag/grey(M), slot_r_hand)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/yellow(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full/multitool(M), slot_belt)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/welding(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/device/flashlight(M), slot_in_backpack)
- equip_special_id(M,list(access_maint_tunnels), "Greytide Leader", /obj/item/weapon/card/id)
-
- if("greytide xeno")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas(M), slot_wear_mask)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/xenos(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/xenos(M), slot_head)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal(M), slot_glasses)
- M.equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen/double/full(M), slot_l_store)
- M.equip_to_slot_or_del(new /obj/item/toy/toy_xeno(M), slot_r_store)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/yellow(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full/multitool(M), slot_belt)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/welding(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/device/flashlight(M), slot_in_backpack)
- equip_special_id(M,list(access_maint_tunnels), "Legit Xenomorph", /obj/item/weapon/card/id)
-
- if("masked killer")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/overalls(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/latex(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/surgical(M), slot_wear_mask)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/welding(M), slot_head)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(M), slot_glasses)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/apron(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/weapon/kitchen/knife(M), slot_l_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/scalpel(M), slot_r_store)
- M.equip_to_slot_or_del(new /obj/item/device/flashlight(M), slot_in_backpack)
- equip_special_id(M,list(access_maint_tunnels), "Masked Killer", /obj/item/weapon/card/id/syndicate, "syndie")
- var/obj/item/weapon/twohanded/fireaxe/fire_axe = new(M)
- M.equip_to_slot_or_del(fire_axe, slot_r_hand)
- for(var/obj/item/carried_item in M.contents)
- if(!istype(carried_item, /obj/item/weapon/implant))
- carried_item.add_blood(M)//Oh yes, there will be blood...
-
- if("dark lord")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/black(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/device/flashlight(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset/syndicate(M), slot_l_ear)
- M.equip_to_slot_or_del(new /obj/item/weapon/twohanded/dualsaber/red(M), slot_l_hand)
- var/obj/item/clothing/suit/hooded/chaplain_hoodie/robe = new /obj/item/clothing/suit/hooded/chaplain_hoodie(M)
- robe.name = "dark lord robes"
- robe.hood.name = "dark lord hood"
- M.equip_to_slot_or_del(robe, slot_wear_suit)
- equip_special_id(M,get_all_accesses(), "Dark Lord", /obj/item/weapon/card/id/syndicate, "syndie")
-
- if("assassin")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/suit_jacket(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/black(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset/syndicate(M), slot_l_ear)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_glasses)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/wcoat(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword/saber(M), slot_l_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/device/flashlight(M), slot_in_backpack)
- var/obj/item/weapon/storage/secure/briefcase/sec_briefcase = new(M)
- for(var/obj/item/briefcase_item in sec_briefcase)
- qdel(briefcase_item)
- for(var/i=3, i>0, i--)
- sec_briefcase.handle_item_insertion(new /obj/item/weapon/spacecash/c1000, 1)
- sec_briefcase.handle_item_insertion(new /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow, 1)
- sec_briefcase.handle_item_insertion(new /obj/item/weapon/gun/projectile/revolver/mateba, 1)
- sec_briefcase.handle_item_insertion(new /obj/item/ammo_box/a357, 1)
- sec_briefcase.handle_item_insertion(new /obj/item/weapon/grenade/plastic/c4, 1)
- // briefcase must be unlocked by setting the code.
- M.equip_to_slot_or_del(sec_briefcase, slot_l_hand)
- var/obj/item/weapon/implant/dust/DUST = new /obj/item/weapon/implant/dust(M)
- DUST.implant(M)
- var/obj/item/device/pda/heads/pda = new(M)
- pda.owner = M.real_name
- pda.ownjob = "Reaper"
- pda.name = "PDA-[M.real_name] ([pda.ownjob])"
- M.equip_to_slot_or_del(pda, slot_wear_pda)
- equip_special_id(M,get_all_accesses(), "Reaper", /obj/item/weapon/card/id/syndicate, "syndie")
-
- if("spy")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/suit_jacket/really_black(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/automatic/pistol(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/suppressor(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/card/emag(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/device/flashlight(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/security/chameleon(M), slot_glasses)
- var/obj/item/clothing/gloves/combat/G = new /obj/item/clothing/gloves/combat(src)
- G.name = "black gloves"
- M.equip_to_slot_or_del(G, slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset/syndicate(M), slot_l_ear)
- M.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword/saber(M), slot_l_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/pen/sleepy(M), slot_r_store)
- var/obj/item/weapon/implant/dust/DUST = new /obj/item/weapon/implant/dust(M)
- DUST.implant(M)
- M.equip_to_slot_or_del(new /obj/item/weapon/implanter/storage(M), slot_in_backpack)
- var/obj/item/device/pda/heads/pda = new(M)
- pda.owner = M.real_name
- pda.ownjob = "Spy"
- pda.name = "PDA-[M.real_name] ([pda.ownjob])"
- M.equip_to_slot_or_del(pda, slot_belt)
- equip_special_id(M,list(access_maint_tunnels), "Spy", /obj/item/weapon/card/id/syndicate, "syndie")
-
-
- if("vox")
- if(istype(M, /mob/living/carbon/human/voxarmalis)) // have to do this, they cannot wear normal vox gear!
- M.equip_to_slot_or_del(new /obj/item/clothing/under/vox_grey(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/syndicate(M), slot_wear_mask)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/carapace(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/vox/carapace(M), slot_head)
- M.equip_to_slot_or_del(new /obj/item/clothing/under/vox/vox_robes (M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/vox(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/weapon/card/id/syndicate/vox(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset/syndicate, slot_l_ear)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/yellow/vox, slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/weapon/melee/classic_baton/telescopic, slot_l_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen/vox, slot_r_store)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle, slot_glasses)
- M.equip_to_slot_or_del(new /obj/item/device/flashlight, slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/restraints/handcuffs/cable/zipties, slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/device/flash, slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/noisecannon, slot_in_backpack)
- equip_special_id(M,get_all_accesses(), "Vox Armalis", /obj/item/weapon/card/id/syndicate/vox, "syndie")
- else
- M.equip_vox_raider()
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(M), slot_l_hand)
- M.regenerate_icons()
-
- if("death commando")
- M.equip_death_commando()
-
- if("syndicate agent")
- M.equip_or_collect(new /obj/item/clothing/under/syndicate(M), slot_w_uniform)
- M.equip_or_collect(new /obj/item/clothing/shoes/combat(M), slot_shoes)
- M.equip_or_collect(new /obj/item/clothing/gloves/combat(M), slot_gloves)
- M.equip_or_collect(new /obj/item/weapon/storage/backpack(M), slot_back)
- M.equip_or_collect(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/device/flashlight(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/card/emag(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/weapon/storage/belt/utility/full/multitool(M), slot_belt)
- M.equip_or_collect(new /obj/item/weapon/reagent_containers/food/snacks/syndidonkpocket(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/device/radio/headset/syndicate(M), slot_l_ear)
- equip_special_id(M,get_syndicate_access("Syndicate Operative"), "Syndicate Agent", /obj/item/weapon/card/id/syndicate, "syndie")
- var/obj/item/device/radio/uplink/U = new /obj/item/device/radio/uplink(M)
- U.hidden_uplink.uplink_owner="[M.key]"
- U.hidden_uplink.uses = 20
- M.equip_to_slot_or_del(U, slot_r_store)
-
- if("syndicate bomber")
- M.equip_or_collect(new /obj/item/clothing/under/syndicate(M), slot_w_uniform)
- M.equip_or_collect(new /obj/item/clothing/shoes/combat(M), slot_shoes)
- M.equip_or_collect(new /obj/item/clothing/gloves/combat(M), slot_gloves)
- M.equip_or_collect(new /obj/item/weapon/storage/backpack(M), slot_back)
- M.equip_or_collect(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/device/flashlight(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/card/emag(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/device/radio/beacon/syndicate/bomb(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/device/radio/beacon/syndicate/bomb(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/device/syndicatedetonator(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/weapon/storage/belt/utility/full/multitool(M), slot_belt)
- M.equip_or_collect(new /obj/item/weapon/reagent_containers/food/snacks/syndidonkpocket(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/device/radio/headset/syndicate(M), slot_l_ear)
- equip_special_id(M,get_syndicate_access("Syndicate Operative"), "Syndicate Bomber", /obj/item/weapon/card/id/syndicate, "syndie")
-
- if("syndicate operative")
- M.equip_or_collect(new /obj/item/clothing/under/syndicate(M), slot_w_uniform)
- M.equip_or_collect(new /obj/item/clothing/shoes/combat(M), slot_shoes)
- M.equip_or_collect(new /obj/item/clothing/gloves/combat(M), slot_gloves)
- M.equip_or_collect(new /obj/item/weapon/storage/backpack(M), slot_back)
- M.equip_or_collect(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/weapon/reagent_containers/food/pill/initropidril(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/weapon/gun/projectile/automatic/pistol(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/ammo_box/magazine/m10mm(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/weapon/crowbar/red(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/clothing/glasses/night(M), slot_glasses)
- M.equip_or_collect(new /obj/item/weapon/storage/belt/military(M), slot_belt)
- M.equip_or_collect(new /obj/item/weapon/grenade/plastic/c4(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/weapon/pinpointer/advpinpointer(M), slot_l_store)
- M.equip_or_collect(new /obj/item/weapon/reagent_containers/food/snacks/syndidonkpocket(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/device/flashlight(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/clothing/mask/gas/syndicate(M), slot_wear_mask)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/syndi(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/syndi(M), slot_head)
- var/obj/item/device/radio/R = new /obj/item/device/radio/headset/syndicate/alt(M)
- R.set_frequency(SYND_FREQ)
- M.equip_to_slot_or_del(R, slot_l_ear)
- var/obj/item/device/radio/uplink/U = new /obj/item/device/radio/uplink(M)
- U.hidden_uplink.uplink_owner="[M.key]"
- U.hidden_uplink.uses = 20
- M.equip_to_slot_or_del(U, slot_r_store)
- M.equip_or_collect(new /obj/item/weapon/tank/jetpack/oxygen/harness(M), slot_in_backpack)
- equip_special_id(M,get_syndicate_access("Syndicate Operative"), "Syndicate Operative", /obj/item/weapon/card/id/syndicate, "syndie")
- var/obj/item/weapon/implant/explosive/E = new/obj/item/weapon/implant/explosive(M)
- E.implant(M)
-
- if("syndicate strike team")
- M.equip_syndicate_commando()
-
- if("syndicate officer")
- M.equip_or_collect(new /obj/item/clothing/under/syndicate(M), slot_w_uniform)
- M.equip_or_collect(new /obj/item/clothing/shoes/combat(M), slot_shoes)
- M.equip_or_collect(new /obj/item/clothing/gloves/combat(M), slot_gloves)
- M.equip_or_collect(new /obj/item/weapon/storage/backpack(M), slot_back)
- M.equip_or_collect(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/weapon/reagent_containers/food/pill/initropidril(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/clothing/glasses/thermal(M), slot_glasses)
- M.equip_or_collect(new /obj/item/weapon/storage/belt/military(M), slot_belt)
- M.equip_or_collect(new /obj/item/weapon/pinpointer/advpinpointer(M), slot_l_store)
- M.equip_or_collect(new /obj/item/weapon/reagent_containers/food/snacks/syndidonkpocket(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/clothing/mask/gas/syndicate(M), slot_wear_mask)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/syndicate/black/red/strike(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/syndicate/black/red/strike(M), slot_head)
- var/obj/item/device/radio/R = new /obj/item/device/radio/headset/syndicate/alt(M)
- R.set_frequency(SYND_FREQ)
- M.equip_to_slot_or_del(R, slot_l_ear)
- var/obj/item/device/radio/uplink/U = new /obj/item/device/radio/uplink(M)
- U.hidden_uplink.uplink_owner="[M.key]"
- U.hidden_uplink.uses = 50
- M.equip_to_slot_or_del(U, slot_r_store)
- M.equip_or_collect(new /obj/item/weapon/tank/jetpack/oxygen/harness(M), slot_in_backpack)
- equip_special_id(M,get_all_accesses() + get_syndicate_access("Syndicate Commando"), "Syndicate Officer", /obj/item/weapon/card/id/syndicate, "commander")
- var/obj/item/weapon/implant/dust/DUST = new /obj/item/weapon/implant/dust(M)
- DUST.implant(M)
-
- if("nt vip guest")
- M.equip_or_collect(new /obj/item/clothing/under/suit_jacket/really_black(M), slot_w_uniform)
- M.equip_or_collect(new /obj/item/clothing/shoes/black(M), slot_shoes)
- M.equip_or_collect(new /obj/item/clothing/gloves/color/black(M), slot_gloves)
- M.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
- M.equip_or_collect(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/clothing/head/that(M), slot_head)
- M.equip_or_collect(new /obj/item/device/radio/headset/ert(M), slot_l_ear)
- M.equip_or_collect(new /obj/item/device/pda/(M), slot_wear_pda)
- equip_special_id(M,get_centcom_access("VIP Guest"), "VIP Guest", /obj/item/weapon/card/id/centcom)
-
- if("nt navy officer")
- M.equip_or_collect(new /obj/item/clothing/under/rank/centcom/officer(M), slot_w_uniform)
- M.equip_or_collect(new /obj/item/clothing/shoes/centcom(M), slot_shoes)
- M.equip_or_collect(new /obj/item/clothing/gloves/color/white(M), slot_gloves)
- M.equip_or_collect(new /obj/item/device/radio/headset/centcom(M), slot_l_ear)
- M.equip_or_collect(new /obj/item/clothing/head/beret/centcom/officer(M), slot_head)
- M.equip_or_collect(new /obj/item/device/pda/centcom(M), slot_wear_pda)
- M.equip_or_collect(new /obj/item/clothing/glasses/hud/security/sunglasses(M), slot_glasses)
- M.equip_or_collect(new /obj/item/weapon/gun/energy/pulse/pistol(M), slot_belt)
- M.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
- M.equip_or_collect(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/weapon/implanter/dust(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/weapon/implanter/death_alarm(M), slot_in_backpack)
- var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(M)
- L.imp_in = M
- L.implanted = 1
- M.sec_hud_set_implants()
- equip_special_id(M,get_centcom_access("Nanotrasen Navy Officer"), "Nanotrasen Navy Officer", /obj/item/weapon/card/id/centcom)
-
- if("nt navy captain")
- M.equip_or_collect(new /obj/item/clothing/under/rank/centcom/captain(M), slot_w_uniform)
- M.equip_or_collect(new /obj/item/clothing/shoes/centcom(M), slot_shoes)
- M.equip_or_collect(new /obj/item/clothing/gloves/color/white(M), slot_gloves)
- M.equip_or_collect(new /obj/item/device/radio/headset/centcom(M), slot_l_ear)
- M.equip_or_collect(new /obj/item/clothing/head/beret/centcom/captain(M), slot_head)
- M.equip_or_collect(new /obj/item/device/pda/centcom(M), slot_wear_pda)
- M.equip_or_collect(new /obj/item/clothing/glasses/hud/security/sunglasses(M), slot_glasses)
- M.equip_or_collect(new /obj/item/weapon/gun/energy/pulse/pistol(M), slot_belt)
- M.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
- M.equip_or_collect(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/weapon/implanter/dust(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/weapon/implanter/death_alarm(M), slot_in_backpack)
- var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(M)
- L.imp_in = M
- L.implanted = 1
- M.sec_hud_set_implants()
- equip_special_id(M,get_centcom_access("Nanotrasen Navy Captain"), "Nanotrasen Navy Captain", /obj/item/weapon/card/id/centcom)
if("emergency response team member", "emergency response team leader")
var/datum/response_team/equip_team = null
@@ -1173,189 +654,17 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
else
to_chat(src, "Invalid ERT Loadout selected")
- if("nt special ops officer")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate/combat(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset/centcom(src), slot_l_ear)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad/beret(M), slot_head) // job has /obj/item/clothing/head/beret/centcom/officer/navy
- M.equip_to_slot_or_del(new /obj/item/device/pda/centcom(M), slot_wear_pda)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/cyber(M), slot_glasses) // job has /obj/item/clothing/glasses/hud/security/sunglasses
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/pistol/m1911(M), slot_belt)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(M), slot_back)
- M.equip_or_collect(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/deathsquad/officer(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen/double/full(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/implanter/dust(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/implanter/death_alarm(M), slot_in_backpack)
- equip_special_id(M,get_centcom_access("Special Operations Officer"), "Special Operations Officer", /obj/item/weapon/card/id/centcom)
- // The following items are unique to this outfit - the special ops officer job does not spawn with them.
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/twohanded/dualsaber/red(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/pinpointer/advpinpointer(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/hypospray/combat/nanites(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/flashbangs(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/zipties(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/cigarette/cigar/cohiba(M), slot_wear_mask)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/matches(M), slot_r_store)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/advance(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/implanter/loyalty(M), slot_in_backpack)
- if("nt special ops formal")
- M.equip_or_collect(new /obj/item/clothing/under/rank/centcom/captain(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset/centcom(src), slot_l_ear)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad/beret(M), slot_head)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/cyber(M), slot_glasses) // special
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/pistol/m1911(M), slot_belt)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/cigarette/cigar/cohiba(M), slot_wear_mask)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
- M.equip_or_collect(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/matches(M), slot_r_store)
- M.equip_or_collect(new /obj/item/weapon/melee/classic_baton/telescopic(M), slot_in_backpack)
-
- var/obj/item/device/pda/centcom/pda = new(M)
- pda.owner = M.real_name
- pda.ownjob = "Special Operations Officer"
- pda.icon_state = "pda-syndi"
- pda.name = "PDA-[M.real_name] ([pda.ownjob])"
- pda.desc = "A portable microcomputer by Thinktronic Systems, LTD. This is model is a special edition designed for military field work."
-
- M.equip_or_collect(pda, slot_wear_pda)
- M.equip_or_collect(new /obj/item/weapon/implanter/dust(M), slot_in_backpack)
- M.equip_or_collect(new /obj/item/weapon/implanter/death_alarm(M), slot_in_backpack)
- equip_special_id(M,get_centcom_access("Special Operations Officer"), "Special Operations Officer", /obj/item/weapon/card/id/centcom)
-
- if("singuloth knight")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate/combat(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/singuloth(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset/ert(src), slot_l_ear)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/meson/cyber(M), slot_glasses)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/breath(M), slot_wear_mask)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/singuloth(M), slot_head)
- M.equip_to_slot_or_del(new /obj/item/weapon/claymore/ceremonial(M), slot_belt)
- M.equip_to_slot_or_del(new /obj/item/weapon/tank/oxygen(M), slot_s_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/twohanded/knighthammer(M), slot_back)
- equip_special_id(M,get_all_accesses(), "Singuloth Knight", /obj/item/weapon/card/id)
-
- if("blue wizard")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(M), slot_head)
- M.equip_to_slot_or_del(new /obj/item/weapon/teleportation_scroll(M), slot_r_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/spellbook(M), slot_r_hand)
- M.equip_to_slot_or_del(new /obj/item/weapon/twohanded/staff(M), slot_l_hand)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack)
- equip_special_id(M,get_all_accesses(), "Wizard", /obj/item/weapon/card/id)
-
- if("red wizard")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/red(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/red(M), slot_head)
- M.equip_to_slot_or_del(new /obj/item/weapon/teleportation_scroll(M), slot_r_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/spellbook(M), slot_r_hand)
- M.equip_to_slot_or_del(new /obj/item/weapon/twohanded/staff(M), slot_l_hand)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack)
- equip_special_id(M,get_all_accesses(), "Wizard", /obj/item/weapon/card/id)
-
- if("marisa wizard")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/marisa(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/marisa(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/marisa(M), slot_head)
- M.equip_to_slot_or_del(new /obj/item/weapon/teleportation_scroll(M), slot_r_store)
- M.equip_to_slot_or_del(new /obj/item/weapon/spellbook(M), slot_r_hand)
- M.equip_to_slot_or_del(new /obj/item/weapon/twohanded/staff(M), slot_l_hand)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack)
- equip_special_id(M,get_all_accesses(), "Wizard", /obj/item/weapon/card/id)
-
- if("soviet tourist")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/soviet(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/ushanka(M), slot_head)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/black(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(M), slot_in_backpack)
- equip_special_id(M,list(access_maint_tunnels), "Soviet Tourist", /obj/item/weapon/card/id)
-
- if("soviet soldier")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/soviet(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/ushanka(M), slot_head)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset/syndicate(M), slot_l_ear)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_glasses)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/card/emag(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/device/flashlight(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/grenade/plastic/c4(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/grenade/plastic/c4(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/revolver/mateba(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/ammo_box/a357(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/ammo_box/a357(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/ammo_box/a357(M), slot_in_backpack)
- equip_special_id(M,list(access_maint_tunnels), "Soviet Soldier", /obj/item/weapon/card/id)
-
- if("soviet admiral")
- M.equip_to_slot_or_del(new /obj/item/clothing/under/soviet(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/clothing/head/hgpiratecap(M), slot_head)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/device/radio/headset/syndicate(M), slot_l_ear)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), slot_glasses)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/hgpirate(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/revolver/mateba(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/ammo_box/a357(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/ammo_box/a357(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/ammo_box/a357(M), slot_in_backpack)
- equip_special_id(M,get_all_accesses() + get_all_centcom_access(), "Soviet Admiral", /obj/item/weapon/card/id, "commander")
- //W.icon_state = "commander"
-
- if("chrono legionnaire")
- M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/chronos(M), slot_head)
- M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/syndicate(src), slot_wear_mask)
- M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes)
- M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
- M.equip_to_slot_or_del(new /obj/item/clothing/glasses/night(M), slot_glasses)
- M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/chronos(M), slot_wear_suit)
- M.equip_to_slot_or_del(new /obj/item/weapon/chrono_eraser(M), slot_back)
- M.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(M), slot_w_uniform)
- M.equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen/double/full(src), slot_s_store)
- equip_special_id(M,get_all_accesses() + get_all_centcom_access(), "Chrono Legionnaire", /obj/item/weapon/card/id/syndicate, "syndie")
+ else // outfit datum
+ if(O)
+ M.equipOutfit(O, FALSE)
M.regenerate_icons()
log_admin("[key_name(usr)] changed the equipment of [key_name(M)] to [dresscode].")
- message_admins("\blue [key_name_admin(usr)] changed the equipment of [key_name_admin(M)] to [dresscode].", 1)
+ message_admins("[key_name_admin(usr)] changed the equipment of [key_name_admin(M)] to [dresscode].", 1)
return
-/client/proc/equip_special_id(var/mob/living/carbon/human/H, var/list/theaccess = null, var/jobtext, var/obj/item/weapon/card/id/id_type = /obj/item/weapon/card/id, var/special_icon = null)
- if(!check_rights(R_EVENT))
- return
-
- var/obj/item/weapon/card/id/W = new id_type(H)
- if(special_icon)
- W.icon_state = special_icon
- W.name = "[H.real_name]'s ID Card ([jobtext])"
- W.access = theaccess
- W.assignment = "[jobtext]"
- W.registered_name = H.real_name
- H.equip_to_slot_or_del(W, slot_wear_id)
/client/proc/startSinglo()
set category = "Debug"
@@ -1474,15 +783,15 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
return
error_cache.showTo(usr)
-
+
/client/proc/jump_to_ruin()
set category = "Debug"
set name = "Jump to Ruin"
set desc = "Displays a list of all placed ruins to teleport to."
-
+
if(!check_rights(R_DEBUG))
return
-
+
var/list/names = list()
for(var/i in ruin_landmarks)
var/obj/effect/landmark/ruin/ruin_landmark = i
@@ -1505,21 +814,21 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(istype(landmark))
var/datum/map_template/ruin/template = landmark.ruin_template
admin_forcemove(usr, get_turf(landmark))
-
+
to_chat(usr, "[template.name]")
to_chat(usr, "[template.description]")
-
+
log_admin("[key_name(usr)] jumped to ruin [ruinname]")
if(!isobserver(usr))
message_admins("[key_name_admin(usr)] jumped to ruin [ruinname]", 1)
-
+
feedback_add_details("admin_verb","JT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
+
/client/proc/toggle_medal_disable()
set category = "Debug"
set name = "Toggle Medal Disable"
set desc = "Toggles the safety lock on trying to contact the medal hub."
-
+
if(!check_rights(R_DEBUG))
return
diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm
index 30f97569c3b..8b8a2b58a52 100644
--- a/code/modules/admin/verbs/diagnostics.dm
+++ b/code/modules/admin/verbs/diagnostics.dm
@@ -15,7 +15,7 @@
if(T.active_hotspot)
burning = 1
- to_chat(usr, "\blue @[target.x],[target.y]: O:[GM.oxygen] T:[GM.toxins] N:[GM.nitrogen] C:[GM.carbon_dioxide] w [GM.temperature] Kelvin, [GM.return_pressure()] kPa [(burning)?("\red BURNING"):(null)]")
+ to_chat(usr, "@[target.x],[target.y]: O:[GM.oxygen] T:[GM.toxins] N:[GM.nitrogen] C:[GM.carbon_dioxide] w [GM.temperature] Kelvin, [GM.return_pressure()] kPa [(burning)?("BURNING"):(null)]")
for(var/datum/gas/trace_gas in GM.trace_gases)
to_chat(usr, "[trace_gas.type]: [trace_gas.moles]")
diff --git a/code/modules/admin/verbs/freeze.dm b/code/modules/admin/verbs/freeze.dm
index 6ebd6b1256a..523fe5cb302 100644
--- a/code/modules/admin/verbs/freeze.dm
+++ b/code/modules/admin/verbs/freeze.dm
@@ -45,7 +45,7 @@ var/global/list/frozen_mob_list = list()
/mob/living/proc/admin_unFreeze(var/client/admin)
if(istype(admin))
to_chat(src, "You have been unfrozen by [key_name(admin)]")
- message_admins("\blue [key_name_admin(admin)] unfroze [key_name_admin(src)]")
+ message_admins("[key_name_admin(admin)] unfroze [key_name_admin(src)]")
log_admin("[key_name(admin)] unfroze [key_name(src)]")
anchored = 0
@@ -106,10 +106,10 @@ var/global/list/frozen_mob_list = list()
if(M.occupant)
M.removeVerb(/obj/mecha/verb/eject)
to_chat(M.occupant, "You have been frozen by [key]")
- message_admins("\blue [key_name_admin(usr)] froze [key_name(M.occupant)] in a [M.name]")
+ message_admins("[key_name_admin(usr)] froze [key_name(M.occupant)] in a [M.name]")
log_admin("[key_name(usr)] froze [key_name(M.occupant)] in a [M.name]")
else
- message_admins("\blue [key_name_admin(usr)] froze an empty [M.name]")
+ message_admins("[key_name_admin(usr)] froze an empty [M.name]")
log_admin("[key_name(usr)] froze an empty [M.name]")
else if(M.can_move == 0)
M.can_move = 1
@@ -117,8 +117,8 @@ var/global/list/frozen_mob_list = list()
if(M.occupant)
M.addVerb(/obj/mecha/verb/eject)
to_chat(M.occupant, "You have been unfrozen by [key]")
- message_admins("\blue [key_name_admin(usr)] unfroze [key_name(M.occupant)] in a [M.name]")
+ message_admins("[key_name_admin(usr)] unfroze [key_name(M.occupant)] in a [M.name]")
log_admin("[key_name(usr)] unfroze [M.occupant.name]/[M.occupant.ckey] in a [M.name]")
else
- message_admins("\blue [key_name_admin(usr)] unfroze an empty [M.name]")
+ message_admins("[key_name_admin(usr)] unfroze an empty [M.name]")
log_admin("[key_name(usr)] unfroze an empty [M.name]")
diff --git a/code/modules/admin/verbs/honksquad.dm b/code/modules/admin/verbs/honksquad.dm
index 480ff434a30..cecf04b93aa 100644
--- a/code/modules/admin/verbs/honksquad.dm
+++ b/code/modules/admin/verbs/honksquad.dm
@@ -62,14 +62,14 @@ var/global/sent_honksquad = 0
new_honksquad.update_internals_hud_icon(1)
//So they don't forget their code or mission.
- new_honksquad.mind.store_memory("Mission: \red [input].")
+ new_honksquad.mind.store_memory("Mission:[input].")
- to_chat(new_honksquad, "\blue You are a HONKsquad. [!honk_leader_selected?"commando":"LEADER"] in the service of Clown Planet. You are called in cases of exteme low levels of HONK. You are NOT authorized to kill. \nYour current mission is: [input]")
+ to_chat(new_honksquad, "You are a HONKsquad. [!honk_leader_selected ? "commando" : "LEADER"] in the service of Clown Planet. You are called in cases of exteme low levels of HONK. You are NOT authorized to kill.\nYour current mission is: [input]")
honksquad_number--
- message_admins("\blue [key_name_admin(usr)] has spawned a HONKsquad.", 1)
+ message_admins("[key_name_admin(usr)] has spawned a HONKsquad.", 1)
log_admin("[key_name(usr)] used Spawn HONKsquad.")
return 1
diff --git a/code/modules/admin/verbs/infiltratorteam_syndicate.dm b/code/modules/admin/verbs/infiltratorteam_syndicate.dm
index 86a899ab847..4e691979507 100644
--- a/code/modules/admin/verbs/infiltratorteam_syndicate.dm
+++ b/code/modules/admin/verbs/infiltratorteam_syndicate.dm
@@ -122,8 +122,8 @@ var/global/sent_syndicate_infiltration_team = 0
syndimgmtmob.update_internals_hud_icon(1)
syndimgmtmob.faction += "syndicate"
syndimgmtmob.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal(src), slot_glasses)
- syndimgmtmob.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/syndi/elite, slot_wear_suit)
- syndimgmtmob.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/syndi/elite, slot_head)
+ syndimgmtmob.equip_to_slot_or_del(new /obj/item/clothing/suit/space/hardsuit/syndi/elite, slot_wear_suit)
+ syndimgmtmob.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite, slot_head)
syndimgmtmob.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/syndicate, slot_wear_mask)
var/datum/atom_hud/antag/opshud = huds[ANTAG_HUD_OPS]
opshud.join_hud(syndimgmtmob.mind.current)
diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm
index e71c6981d97..d581c99644b 100644
--- a/code/modules/admin/verbs/one_click_antag.dm
+++ b/code/modules/admin/verbs/one_click_antag.dm
@@ -337,7 +337,7 @@ client/proc/one_click_antag()
//So they don't forget their code or mission.
- to_chat(new_syndicate_commando, "\blue You are an Elite Syndicate. [!syndicate_leader_selected?"commando":"LEADER"] in the service of the Syndicate. \nYour current mission is: [input]")
+ to_chat(new_syndicate_commando, "You are an Elite Syndicate. [!syndicate_leader_selected ? "commando" : "LEADER"] in the service of the Syndicate. \nYour current mission is: [input]")
numagents--
if(numagents >= 6)
@@ -444,8 +444,8 @@ client/proc/one_click_antag()
new_vox.key = theghost.key
ticker.mode.traitors += new_vox.mind
- to_chat(new_vox, "\blue You are a Vox Primalis, fresh out of the Shoal. Your ship has arrived at the Tau Ceti system hosting the NSV Exodus... or was it the Luna? NSS? Utopia? Nobody is really sure, but everyong is raring to start pillaging! Your current goal is: [input]")
- to_chat(new_vox, "\red Don't forget to turn on your nitrogen internals!")
+ to_chat(new_vox, "You are a Vox Primalis, fresh out of the Shoal. Your ship has arrived at the Tau Ceti system hosting the NSV Exodus... or was it the Luna? NSS? Utopia? Nobody is really sure, but everyong is raring to start pillaging! Your current goal is: [input]")
+ to_chat(new_vox, "Don't forget to turn on your nitrogen internals!")
raiders--
if(raiders > max_raiders)
diff --git a/code/modules/admin/verbs/onlyone.dm b/code/modules/admin/verbs/onlyone.dm
index 907fcb92913..9bfe544cef5 100644
--- a/code/modules/admin/verbs/onlyone.dm
+++ b/code/modules/admin/verbs/onlyone.dm
@@ -49,7 +49,7 @@
W.assignment = "Highlander"
W.registered_name = H.real_name
H.equip_to_slot_or_del(W, slot_wear_id)
- H.species.equip(H)
+ H.species.after_equip_job(null, H)
H.regenerate_icons()
message_admins("[key_name_admin(usr)] used THERE CAN BE ONLY ONE! -NO ATTACK LOGS WILL BE SENT TO ADMINS FROM THIS POINT FORTH-", 1)
diff --git a/code/modules/admin/verbs/onlyoneteam.dm b/code/modules/admin/verbs/onlyoneteam.dm
index a88270077d6..750d0d89b93 100644
--- a/code/modules/admin/verbs/onlyoneteam.dm
+++ b/code/modules/admin/verbs/onlyoneteam.dm
@@ -55,7 +55,7 @@
H.equip_to_slot_or_del(W, slot_wear_id)
team_toggle = !team_toggle
- H.species.equip(H)
+ H.species.after_equip_job(null, H)
H.regenerate_icons()
message_admins("[key_name_admin(usr)] used DODGEBAWWWWWWWL! -NO ATTACK LOGS WILL BE SENT TO ADMINS FROM THIS POINT FORTH-", 1)
diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm
index 957070eae8e..69093944f67 100644
--- a/code/modules/admin/verbs/playsound.dm
+++ b/code/modules/admin/verbs/playsound.dm
@@ -1,5 +1,18 @@
var/list/sounds_cache = list()
+/client/proc/stop_global_admin_sounds()
+ set category = "Event"
+ set name = "Stop Global Admin Sounds"
+ if(!check_rights(R_SOUNDS))
+ return
+
+ var/sound/awful_sound = sound(null, repeat = 0, wait = 0, channel = 777)
+
+ log_admin("[key_name(src)] stopped admin sounds.")
+ message_admins("[key_name_admin(src)] stopped admin sounds.", 1)
+ for(var/mob/M in player_list)
+ M << awful_sound
+
/client/proc/play_sound(S as sound)
set category = "Event"
set name = "Play Global Sound"
diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm
index ad926d61de7..4560c7affa9 100644
--- a/code/modules/admin/verbs/pray.dm
+++ b/code/modules/admin/verbs/pray.dm
@@ -7,13 +7,13 @@
if(usr.client)
if(usr.client.prefs.muted & MUTE_PRAY)
- to_chat(usr, "\red You cannot pray (muted).")
+ to_chat(usr, "You cannot pray (muted).")
return
if(client.handle_spam_prevention(msg, MUTE_PRAY, OOC_COOLDOWN))
return
var/image/cross = image('icons/obj/storage.dmi',"bible")
- msg = "\blue [bicon(cross)] PRAY: [key_name(src, 1)] (?) (PP) (VV) (SM) ([admin_jump_link(src)]) (CA) (SC) (BLESS) (SMITE): [msg]"
+ msg = "[bicon(cross)] PRAY: [key_name(src, 1)] (?) (PP) (VV) (SM) ([admin_jump_link(src)]) (CA) (SC) (BLESS) (SMITE): [msg]"
for(var/client/X in admins)
if(check_rights(R_EVENT,0,X.mob))
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index 9cacaefbd3f..170e5e8cf9f 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -39,9 +39,9 @@
prisoner.equip_to_slot_or_del(new /obj/item/clothing/under/color/orange(prisoner), slot_w_uniform)
prisoner.equip_to_slot_or_del(new /obj/item/clothing/shoes/orange(prisoner), slot_shoes)
spawn(50)
- to_chat(M, "\red You have been sent to the prison station!")
+ to_chat(M, "You have been sent to the prison station!")
log_admin("[key_name(usr)] sent [key_name(M)] to the prison station.")
- message_admins("\blue [key_name_admin(usr)] sent [key_name_admin(M)] to the prison station.", 1)
+ message_admins("[key_name_admin(usr)] sent [key_name_admin(M)] to the prison station.", 1)
feedback_add_details("admin_verb","PRISON") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_subtle_message(mob/M as mob in mob_list)
@@ -61,10 +61,10 @@
if(usr)
if(usr.client)
if(usr.client.holder)
- to_chat(M, "\bold You hear a voice in your head... \italic [msg]")
+ to_chat(M, "old You hear a voice in your head... [msg]")
log_admin("SubtlePM: [key_name(usr)] -> [key_name(M)] : [msg]")
- message_admins("\blue \bold SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] : [msg]", 1)
+ message_admins("SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] : [msg]", 1)
feedback_add_details("admin_verb","SMS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_mentor_check_new_players() //Allows mentors / admins to determine who the newer players are.
@@ -88,7 +88,7 @@
missing_ages = 1
continue
if(C.player_age < age)
- if(check_rights(R_ADMIN))
+ if(check_rights(R_ADMIN, 0))
msg += "[key_name_admin(C.mob)]: [C.player_age] days old "
else
msg += "[key_name_mentor(C.mob)]: [C.player_age] days old "
@@ -115,7 +115,7 @@
return
to_chat(world, "[msg]")
log_admin("GlobalNarrate: [key_name(usr)] : [msg]")
- message_admins("\blue \bold GlobalNarrate: [key_name_admin(usr)]: [msg] ", 1)
+ message_admins("GlobalNarrate: [key_name_admin(usr)]: [msg] ", 1)
feedback_add_details("admin_verb","GLN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_direct_narrate(var/mob/M) // Targetted narrate -- TLE
@@ -138,7 +138,7 @@
to_chat(M, msg)
log_admin("DirectNarrate: [key_name(usr)] to ([key_name(M)]): [msg]")
- message_admins("\blue \bold DirectNarrate: [key_name_admin(usr)] to ([key_name_admin(M)]): [msg] ", 1)
+ message_admins("DirectNarrate: [key_name_admin(usr)] to ([key_name_admin(M)]): [msg] ", 1)
feedback_add_details("admin_verb","DIRN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_godmode(mob/M as mob in mob_list)
@@ -149,7 +149,7 @@
return
M.status_flags ^= GODMODE
- to_chat(usr, "\blue Toggled [(M.status_flags & GODMODE) ? "ON" : "OFF"]")
+ to_chat(usr, "Toggled [(M.status_flags & GODMODE) ? "ON" : "OFF"]")
log_admin("[key_name(usr)] has toggled [key_name(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]")
message_admins("[key_name_admin(usr)] has toggled [key_name_admin(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]", 1)
@@ -333,7 +333,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
G_found.mind.transfer_to(new_xeno) //be careful when doing stuff like this! I've already checked the mind isn't in use
new_xeno.key = G_found.key
to_chat(new_xeno, "You have been fully respawned. Enjoy the game.")
- message_admins("\blue [key_name_admin(usr)] has respawned [new_xeno.key] as a filthy xeno.", 1)
+ message_admins("[key_name_admin(usr)] has respawned [new_xeno.key] as a filthy xeno.", 1)
return //all done. The ghost is auto-deleted
var/mob/living/carbon/human/new_character = new(pick(latejoin))//The mob being spawned.
@@ -437,7 +437,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(alert(new_character,"Would you like an active AI to announce this character?",,"No","Yes")=="Yes")
call(/mob/new_player/proc/AnnounceArrival)(new_character, new_character.mind.assigned_role)
- message_admins("\blue [key_name_admin(usr)] has respawned [key_name_admin(G_found)] as [new_character.real_name].", 1)
+ message_admins("[key_name_admin(usr)] has respawned [key_name_admin(G_found)] as [new_character.real_name].", 1)
to_chat(new_character, "You have been fully respawned. Enjoy the game.")
@@ -473,7 +473,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
else return 0
new_xeno.ckey = ckey
- message_admins("\blue [key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste].", 1)
+ message_admins("[key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste].", 1)
return 1
@@ -537,7 +537,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
M.revive()
log_admin("[key_name(usr)] healed / revived [key_name(M)]")
- message_admins("\red Admin [key_name_admin(usr)] healed / revived [key_name_admin(M)]!", 1)
+ message_admins("Admin [key_name_admin(usr)] healed / revived [key_name_admin(M)]!", 1)
feedback_add_details("admin_verb","REJU") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_create_centcom_report()
@@ -549,9 +549,11 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/type = input(usr, "Pick a type of report to send", "Report Type", "") as anything in MsgType
var/input = input(usr, "Please enter anything you want. Anything. Serious.", "What?", "") as message|null
- var/customname = input(usr, "Pick a title for the report.", "Title") as text|null
if(!input)
return
+ var/customname = input(usr, "Pick a title for the report.", "Title") as text|null
+ if(!customname)
+ return
if(type == "Enemy Communications")
if(!customname)
@@ -560,11 +562,13 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/from = input(usr, "What kind of report? Example: Syndicate Communique", "From") as text|null
if(!from)
from = "Syndicate Communique"
- switch(alert("Should this be announced to the general population?",,"Yes","No"))
+ switch(alert("Should this be announced to the general population?",,"Yes","No", "Cancel"))
if("Yes")
communications_announcement.Announce(input, customname, , , , from);
- if("No")
+ else if("No")
to_chat(world, "[from] available at all communications consoles.")
+ else
+ return
print_command_report(input, from)
@@ -707,7 +711,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
mob.gib()
log_admin("[key_name(usr)] used gibself.")
- message_admins("\blue [key_name_admin(usr)] used gibself.", 1)
+ message_admins("[key_name_admin(usr)] used gibself.", 1)
feedback_add_details("admin_verb","GIBS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_check_contents(mob/living/M as mob in mob_list)
@@ -736,7 +740,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
view = world.view
log_admin("[key_name(usr)] changed their view range to [view].")
- //message_admins("\blue [key_name_admin(usr)] changed their view range to [view].", 1) //why? removed by order of XSI
+ //message_admins("[key_name_admin(usr)] changed their view range to [view].", 1) //why? removed by order of XSI
feedback_add_details("admin_verb","CVRA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -834,7 +838,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
message_admins("Admin [key_name_admin(usr)] has forced the players to have random appearances.", 1)
if(notifyplayers == "Yes")
- to_chat(world, "\blue Admin [usr.key] has forced the players to have completely random identities!")
+ to_chat(world, "Admin [usr.key] has forced the players to have completely random identities!")
to_chat(usr, "Remember: you can always disable the randomness by using the verb again, assuming the round hasn't started yet.")
@@ -891,15 +895,15 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(ticker.mode.ert_disabled)
ticker.mode.ert_disabled = 0
- to_chat(usr, "\blue ERT has been Enabled.")
+ to_chat(usr, "ERT has been Enabled.")
log_admin("Admin [key_name(src)] has enabled ERT calling.")
message_admins("Admin [key_name_admin(usr)] has enabled ERT calling.", 1)
else
ticker.mode.ert_disabled = 1
- to_chat(usr, "\red ERT has been Disabled.")
+ to_chat(usr, "ERT has been Disabled.")
log_admin("Admin [key_name(src)] has disabled ERT calling.")
message_admins("Admin [key_name_admin(usr)] has disabled ERT calling.", 1)
-
+
/client/proc/modify_goals()
set category = "Event"
set name = "Modify Station Goals"
@@ -910,8 +914,12 @@ Traitors and the like can also be revived with the previous role mostly intact.
holder.modify_goals()
/datum/admins/proc/modify_goals()
+ if(!ticker || !ticker.mode)
+ to_chat(usr, "This verb can only be used if the round has started.")
+ return
+
var/dat = ""
for(var/datum/station_goal/S in ticker.mode.station_goals)
dat += "[S.name] - Announce | Remove "
dat += " Add New Goal"
- usr << browse(dat, "window=goals;size=400x400")
\ No newline at end of file
+ usr << browse(dat, "window=goals;size=400x400")
diff --git a/code/modules/admin/verbs/striketeam.dm b/code/modules/admin/verbs/striketeam.dm
index f6de49de939..d90c8a50a84 100644
--- a/code/modules/admin/verbs/striketeam.dm
+++ b/code/modules/admin/verbs/striketeam.dm
@@ -68,10 +68,10 @@ var/global/sent_strike_team = 0
//So they don't forget their code or mission.
if(nuke_code)
- new_commando.mind.store_memory("Nuke Code: \red [nuke_code].")
- new_commando.mind.store_memory("Mission: \red [input].")
+ new_commando.mind.store_memory("Nuke Code:[nuke_code].")
+ new_commando.mind.store_memory("Mission:[input].")
- to_chat(new_commando, "\blue You are a Special Ops. [!leader_selected?"commando":"LEADER"] in the service of Central Command. Check the table ahead for detailed instructions.\nYour current mission is: [input]")
+ to_chat(new_commando, "You are a Special Ops. [!leader_selected ? "commando" : "LEADER"] in the service of Central Command. Check the table ahead for detailed instructions.\nYour current mission is: [input]")
commando_number--
@@ -92,7 +92,7 @@ var/global/sent_strike_team = 0
new /obj/effect/spawner/newbomb/timer/syndicate(L.loc)
qdel(L)
- message_admins("\blue [key_name_admin(usr)] has spawned a CentComm strike squad.", 1)
+ message_admins("[key_name_admin(usr)] has spawned a CentComm strike squad.", 1)
log_admin("[key_name(usr)] used Spawn Death Squad.")
return 1
@@ -157,7 +157,7 @@ var/global/sent_strike_team = 0
equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse(src), slot_r_hand)
- var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(src)//Here you go Deuryn
+ var/obj/item/weapon/implant/mindshield/L = new/obj/item/weapon/implant/mindshield(src)
L.imp_in = src
L.implanted = 1
sec_hud_set_implants()
diff --git a/code/modules/admin/verbs/striketeam_syndicate.dm b/code/modules/admin/verbs/striketeam_syndicate.dm
index 33512a3fe10..da6d981a890 100644
--- a/code/modules/admin/verbs/striketeam_syndicate.dm
+++ b/code/modules/admin/verbs/striketeam_syndicate.dm
@@ -75,10 +75,10 @@ var/global/sent_syndicate_strike_team = 0
//So they don't forget their code or mission.
if(nuke_code)
- new_syndicate_commando.mind.store_memory("Nuke Code: \red [nuke_code].")
- new_syndicate_commando.mind.store_memory("Mission: \red [input].")
+ new_syndicate_commando.mind.store_memory("Nuke Code:[nuke_code].")
+ new_syndicate_commando.mind.store_memory("Mission:[input].")
- to_chat(new_syndicate_commando, "\blue You are an Elite Syndicate. [!syndicate_leader_selected?"commando":"LEADER"] in the service of the Syndicate. \nYour current mission is: [input]")
+ to_chat(new_syndicate_commando, "You are an Elite Syndicate. [!syndicate_leader_selected ? "commando" : "LEADER"] in the service of the Syndicate. \nYour current mission is: [input]")
new_syndicate_commando.faction += "syndicate"
syndicate_commando_number--
@@ -87,7 +87,7 @@ var/global/sent_syndicate_strike_team = 0
new /obj/effect/spawner/newbomb/timer/syndicate(L.loc)
qdel(L)
- message_admins("\blue [key_name_admin(usr)] has spawned a Syndicate strike squad.", 1)
+ message_admins("[key_name_admin(usr)] has spawned a Syndicate strike squad.", 1)
log_admin("[key_name(usr)] used Spawn Syndicate Squad.")
feedback_add_details("admin_verb","SDTHS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/verbs/ticklag.dm b/code/modules/admin/verbs/ticklag.dm
index cabf767b620..f49984b8fb3 100644
--- a/code/modules/admin/verbs/ticklag.dm
+++ b/code/modules/admin/verbs/ticklag.dm
@@ -19,6 +19,6 @@
if("Yes") config.Tickcomp = 1
else config.Tickcomp = 0
else
- to_chat(src, "\red Error: ticklag(): Invalid world.ticklag value. No changes made.")
+ to_chat(src, "Error: ticklag(): Invalid world.ticklag value. No changes made.")
diff --git a/code/modules/admin/verbs/tripAI.dm b/code/modules/admin/verbs/tripAI.dm
index 6c95873a7da..0da0dfc42f6 100644
--- a/code/modules/admin/verbs/tripAI.dm
+++ b/code/modules/admin/verbs/tripAI.dm
@@ -14,9 +14,9 @@
if(ticker.triai)
ticker.triai = 0
to_chat(usr, "Only one AI will be spawned at round start.")
- message_admins("\blue [key_name_admin(usr)] has toggled off triple AIs at round start.", 1)
+ message_admins("[key_name_admin(usr)] has toggled off triple AIs at round start.", 1)
else
ticker.triai = 1
to_chat(usr, "There will be an AI Triumvirate at round start.")
- message_admins("\blue [key_name_admin(usr)] has toggled on triple AIs at round start.", 1)
+ message_admins("[key_name_admin(usr)] has toggled on triple AIs at round start.", 1)
return
diff --git a/code/modules/alarm/alarm_handler.dm b/code/modules/alarm/alarm_handler.dm
index 9878a4b5e5e..cd09ebe4427 100644
--- a/code/modules/alarm/alarm_handler.dm
+++ b/code/modules/alarm/alarm_handler.dm
@@ -47,6 +47,11 @@
existing.clear(source)
return check_alarm_cleared(existing)
+/datum/alarm_handler/proc/has_major_alarms()
+ if(alarms && alarms.len)
+ return 1
+ return 0
+
/datum/alarm_handler/proc/major_alarms()
return alarms
diff --git a/code/modules/arcade/arcade_base.dm b/code/modules/arcade/arcade_base.dm
index 3c68c7142f4..b043eb934c9 100644
--- a/code/modules/arcade/arcade_base.dm
+++ b/code/modules/arcade/arcade_base.dm
@@ -61,7 +61,7 @@
/obj/machinery/arcade/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
if(istype(O, /obj/item/weapon/screwdriver) && anchored)
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
+ playsound(src.loc, O.usesound, 50, 1)
panel_open = !panel_open
to_chat(user, "You [panel_open ? "open" : "close"] the maintenance panel.")
update_icon()
@@ -72,8 +72,8 @@
if(pay_with_card(C))
tokens += 1
return
- else if(istype(O, /obj/item/weapon/spacecash))
- var/obj/item/weapon/spacecash/C = O
+ else if(istype(O, /obj/item/stack/spacecash))
+ var/obj/item/stack/spacecash/C = O
if(pay_with_cash(C, user))
tokens += 1
return
@@ -83,16 +83,12 @@
/obj/machinery/arcade/update_icon()
return
-/obj/machinery/arcade/proc/pay_with_cash(var/obj/item/weapon/spacecash/cashmoney, var/mob/user)
- if(cashmoney.get_total() < token_price)
+/obj/machinery/arcade/proc/pay_with_cash(obj/item/stack/spacecash/cashmoney, mob/user)
+ if(cashmoney.amount < token_price)
to_chat(user, "[bicon(cashmoney)] That is not enough money.")
return 0
visible_message("[usr] inserts a credit chip into [src].")
- var/left = cashmoney.get_total() - token_price
- user.unEquip(cashmoney)
- qdel(cashmoney)
- if(left)
- dispense_cash(left, src.loc, user)
+ cashmoney.use(token_price)
return 1
/obj/machinery/arcade/proc/pay_with_card(var/obj/item/weapon/card/id/I, var/mob/user)
diff --git a/code/modules/arcade/mob_hunt/battle_computer.dm b/code/modules/arcade/mob_hunt/battle_computer.dm
index 97055664cdb..dc0b47cd4b0 100644
--- a/code/modules/arcade/mob_hunt/battle_computer.dm
+++ b/code/modules/arcade/mob_hunt/battle_computer.dm
@@ -51,8 +51,7 @@
mob_hunt_server.red_terminal = null
if(mob_hunt_server.blue_terminal == src)
mob_hunt_server.blue_terminal = null
- if(avatar)
- qdel(avatar)
+ QDEL_NULL(avatar)
return ..()
/obj/machinery/computer/mob_battle_terminal/attackby(obj/item/O, mob/user)
diff --git a/code/modules/arcade/mob_hunt/mob_cards.dm b/code/modules/arcade/mob_hunt/mob_cards.dm
index 16aea7ba55f..0479644ad85 100644
--- a/code/modules/arcade/mob_hunt/mob_cards.dm
+++ b/code/modules/arcade/mob_hunt/mob_cards.dm
@@ -35,7 +35,7 @@
/obj/item/weapon/storage/box/nanomob_booster_pack
name = "Nano-Mob Hunter Trading Card Booster Pack"
desc = "Contains 6 random Nano-Mob Hunter Trading Cards. May contain a holographic card!"
- can_hold = list("/obj/item/weapon/nanomob_card")
+ can_hold = list(/obj/item/weapon/nanomob_card)
/obj/item/weapon/storage/box/nanomob_booster_pack/New()
..()
diff --git a/code/modules/arcade/prize_counter.dm b/code/modules/arcade/prize_counter.dm
index e1636fa4e33..93ffbe7e419 100644
--- a/code/modules/arcade/prize_counter.dm
+++ b/code/modules/arcade/prize_counter.dm
@@ -41,7 +41,7 @@
to_chat(user, "\The [T] seems stuck to your hand!")
return
if(istype(O, /obj/item/weapon/screwdriver) && anchored)
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
+ playsound(src.loc, O.usesound, 50, 1)
panel_open = !panel_open
to_chat(user, "You [panel_open ? "open" : "close"] the maintenance panel.")
update_icon()
diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm
index 84e10835215..bd981e99076 100644
--- a/code/modules/assembly/assembly.dm
+++ b/code/modules/assembly/assembly.dm
@@ -10,6 +10,8 @@
throw_speed = 3
throw_range = 10
origin_tech = "magnets=1"
+ toolspeed = 1
+ usesound = 'sound/items/Deconstruct.ogg'
var/bomb_name = "bomb" // used for naming bombs / mines
@@ -114,7 +116,7 @@
attach_assembly(var/obj/item/device/assembly/A, var/mob/user)
holder = new/obj/item/device/assembly_holder(get_turf(src))
if(holder.attach(A,src,user))
- to_chat(user, "\blue You attach \the [A] to \the [src]!")
+ to_chat(user, "You attach \the [A] to \the [src]!")
return 1
return 0
@@ -127,9 +129,9 @@
return
if(istype(W, /obj/item/weapon/screwdriver))
if(toggle_secure())
- to_chat(user, "\blue \The [src] is ready!")
+ to_chat(user, "\The [src] is ready!")
else
- to_chat(user, "\blue \The [src] can now be attached!")
+ to_chat(user, "\The [src] can now be attached!")
return
..()
return
diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm
index f4cafef9c97..47d33a1e5ce 100644
--- a/code/modules/assembly/holder.dm
+++ b/code/modules/assembly/holder.dm
@@ -140,15 +140,15 @@
attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/weapon/screwdriver))
if(!a_left || !a_right)
- to_chat(user, "\red BUG:Assembly part missing, please report this!")
+ to_chat(user, "BUG:Assembly part missing, please report this!")
return
a_left.toggle_secure()
a_right.toggle_secure()
secured = !secured
if(secured)
- to_chat(user, "\blue \The [src] is ready!")
+ to_chat(user, "\The [src] is ready!")
else
- to_chat(user, "\blue \The [src] can now be taken apart!")
+ to_chat(user, "\The [src] can now be taken apart!")
update_icon()
return
else
@@ -160,7 +160,7 @@
src.add_fingerprint(user)
if(src.secured)
if(!a_left || !a_right)
- to_chat(user, "\red Assembly part missing!")
+ to_chat(user, "Assembly part missing!")
return
if(istype(a_left,a_right.type))//If they are the same type it causes issues due to window code
switch(alert("Which side would you like to use?",,"Left","Right"))
diff --git a/code/modules/assembly/igniter.dm b/code/modules/assembly/igniter.dm
index e6505e385ad..b1c76236853 100644
--- a/code/modules/assembly/igniter.dm
+++ b/code/modules/assembly/igniter.dm
@@ -12,8 +12,7 @@
sparks.attach(src)
/obj/item/device/assembly/igniter/Destroy()
- qdel(sparks)
- sparks = null
+ QDEL_NULL(sparks)
return ..()
diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm
index 7f9181ca937..60f3014d357 100644
--- a/code/modules/assembly/infrared.dm
+++ b/code/modules/assembly/infrared.dm
@@ -255,9 +255,7 @@
/obj/effect/beam/i_beam/Destroy()
if(master.first == src)
master.first = null
- if(next)
- qdel(next)
- next = null
+ QDEL_NULL(next)
if(previous)
previous.next = null
master.last = previous
diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm
index e1078ed9caa..f3296cdabb0 100644
--- a/code/modules/assembly/proximity.dm
+++ b/code/modules/assembly/proximity.dm
@@ -19,7 +19,7 @@
describe()
if(timing)
- return "\blue The proximity sensor is arming."
+ return "The proximity sensor is arming."
return "The proximity sensor is [scanning?"armed":"disarmed"]."
activate()
@@ -109,7 +109,7 @@
interact(mob/user as mob)//TODO: Change this to the wires thingy
if(!secured)
- user.show_message("\red The [name] is unsecured!")
+ user.show_message("The [name] is unsecured!")
return 0
var/second = time % 60
var/minute = (time - second) / 60
diff --git a/code/modules/assembly/shock_kit.dm b/code/modules/assembly/shock_kit.dm
index 3aa24a2d014..6ffe6f42d12 100644
--- a/code/modules/assembly/shock_kit.dm
+++ b/code/modules/assembly/shock_kit.dm
@@ -10,10 +10,8 @@
flags = CONDUCT
/obj/item/assembly/shock_kit/Destroy()
- qdel(part1)
- part1 = null
- qdel(part2)
- part2 = null
+ QDEL_NULL(part1)
+ QDEL_NULL(part2)
return ..()
/obj/item/assembly/shock_kit/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm
index 0ce52543909..9a76869d339 100644
--- a/code/modules/assembly/signaler.dm
+++ b/code/modules/assembly/signaler.dm
@@ -61,7 +61,7 @@
if(!flag1)
dat += {"
Send Signal
- Reciever is [receiving?"on":"off"]
+ Receiver is [receiving?"on":"off"]
"}
dat += {"
Frequency/Code for signaler:
diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm
index 179d7df2347..0587a806b2b 100644
--- a/code/modules/assembly/timer.dm
+++ b/code/modules/assembly/timer.dm
@@ -74,7 +74,7 @@
interact(mob/user as mob)//TODO: Have this use the wires
if(!secured)
- user.show_message("\red The [name] is unsecured!")
+ user.show_message("The [name] is unsecured!")
return 0
var/second = time % 60
var/minute = (time - second) / 60
diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm
index af9138724e6..ba0752dd28e 100644
--- a/code/modules/assembly/voice.dm
+++ b/code/modules/assembly/voice.dm
@@ -35,7 +35,7 @@
if(findtext(msg, recorded) && type == recorded_type)
pulse(0)
var/turf/T = get_turf(src) //otherwise it won't work in hand
- T.visible_message("[bicon(src)] \red beeps!")
+ T.visible_message("[bicon(src)] beeps!")
activate()
return // previously this toggled listning when not in a holder, that's a little silly. It was only called in attack_self that way.
diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm
index 4c050e0d4f3..be88df0c4e4 100644
--- a/code/modules/awaymissions/corpse.dm
+++ b/code/modules/awaymissions/corpse.dm
@@ -116,12 +116,12 @@
/obj/effect/landmark/corpse/syndicatecommando
name = "Syndicate Commando"
corpseuniform = /obj/item/clothing/under/syndicate
- corpsesuit = /obj/item/clothing/suit/space/rig/syndi
+ corpsesuit = /obj/item/clothing/suit/space/hardsuit/syndi
corpseshoes = /obj/item/clothing/shoes/combat
corpsegloves = /obj/item/clothing/gloves/combat
corpseradio = /obj/item/device/radio/headset
corpsemask = /obj/item/clothing/mask/gas/syndicate
- corpsehelmet = /obj/item/clothing/head/helmet/space/rig/syndi
+ corpsehelmet = /obj/item/clothing/head/helmet/space/hardsuit/syndi
corpseback = /obj/item/weapon/tank/jetpack/oxygen
corpsepocket1 = /obj/item/weapon/tank/emergency_oxygen
corpseid = 1
@@ -170,10 +170,10 @@
corpseidjob = "Station Engineer"
corpseidaccess = "Station Engineer"
-/obj/effect/landmark/corpse/engineer/rig
- corpsesuit = /obj/item/clothing/suit/space/rig
+/obj/effect/landmark/corpse/engineer/hardsuit
+ corpsesuit = /obj/item/clothing/suit/space/hardsuit
corpsemask = /obj/item/clothing/mask/breath
- corpsehelmet = /obj/item/clothing/head/helmet/space/rig
+ corpsehelmet = /obj/item/clothing/head/helmet/space/hardsuit
/obj/effect/landmark/corpse/clown
@@ -255,10 +255,10 @@
corpseidjob = "Shaft Miner"
corpseidaccess = "Shaft Miner"
-/obj/effect/landmark/corpse/miner/rig
- corpsesuit = /obj/item/clothing/suit/space/rig/mining
+/obj/effect/landmark/corpse/miner/hardsuit
+ corpsesuit = /obj/item/clothing/suit/space/hardsuit/mining
corpsemask = /obj/item/clothing/mask/breath
- corpsehelmet = /obj/item/clothing/head/helmet/space/rig/mining
+ corpsehelmet = /obj/item/clothing/head/helmet/space/hardsuit/mining
/////////////////Officers//////////////////////
diff --git a/code/modules/awaymissions/map_rng.dm b/code/modules/awaymissions/map_rng.dm
index 147d41171c4..64350c99737 100644
--- a/code/modules/awaymissions/map_rng.dm
+++ b/code/modules/awaymissions/map_rng.dm
@@ -18,6 +18,11 @@
template_name = tname
if(template_name)
template = map_templates[template_name]
+ // Catches the interim-zone of worldstart and roundstart
+ // I want both the ticker to exist (so mapped-in maploaders don't trip this)
+ // but also not have started yet (since the zlevel system would handle this on its own otherwise)
+ if((ticker && ticker.current_state < GAME_STATE_PLAYING))
+ attempt_init()
/obj/effect/landmark/map_loader/initialize()
..()
diff --git a/code/modules/awaymissions/mission_code/UO71-terrorspiders.dm b/code/modules/awaymissions/mission_code/UO71-terrorspiders.dm
new file mode 100644
index 00000000000..52d8caa6f74
--- /dev/null
+++ b/code/modules/awaymissions/mission_code/UO71-terrorspiders.dm
@@ -0,0 +1,257 @@
+/area/awaymission/UO71
+ name = "UO71"
+ icon_state = "away"
+ report_alerts = 0
+ tele_proof = 1
+
+
+/area/awaymission/UO71/plaza
+ name = "UO71 Plaza"
+ icon_state = "awaycontent1"
+ fire = 1
+
+/area/awaymission/UO71/centralhall
+ name = "UO71 Central"
+ icon_state = "awaycontent2"
+ fire = 1
+
+/area/awaymission/UO71/eng
+ name = "UO71 Engineering"
+ icon_state = "awaycontent3"
+ fire = 1
+
+/area/awaymission/UO71/mining
+ name = "UO71 Mining"
+ icon_state = "awaycontent4"
+ fire = 1
+
+/area/awaymission/UO71/science
+ name = "UO71 Science"
+ icon_state = "awaycontent5"
+ fire = 1
+
+/area/awaymission/UO71/medical
+ name = "UO71 Medical"
+ icon_state = "awaycontent6"
+ fire = 1
+
+/area/awaymission/UO71/gateway
+ name = "UO71 Gateway"
+ icon_state = "awaycontent7"
+ fire = 1
+
+/area/awaymission/UO71/outside
+ name = "UO71 Outside"
+ icon_state = "awaycontent8"
+
+/area/awaymission/UO71/bridge
+ name = "UO71 Bridge"
+ icon_state = "awaycontent21"
+ fire = 1
+ requires_power = 0
+ tele_proof = 1
+
+/area/awaymission/UO71/queen
+ name = "UO71 Queen Lair"
+ icon_state = "awaycontent9"
+ fire = 1
+ requires_power = 0
+ tele_proof = 1
+
+/area/awaymission/UO71/prince
+ name = "UO71 Prince Containment"
+ icon_state = "awaycontent10"
+ fire = 1
+ requires_power = 0
+ tele_proof = 1
+
+/area/awaymission/UO71/mother
+ name = "UO71 Mother Containment"
+ icon_state = "awaycontent10"
+ fire = 1
+ requires_power = 0
+ tele_proof = 1
+
+/area/awaymission/UO71/loot
+ name = "UO71 Loot Vault"
+ icon_state = "awaycontent11"
+ requires_power = 0
+ tele_proof = 1
+
+/obj/item/weapon/paper/terrorspiders1
+ name = "paper - 'Sealed Facility'"
+ info = {"SEALED FACILITY
+
+ This facility is sealed shut by order of Commander Marquez. Do not enter.
+ Terror spiders live here. We believe they are a weapon developed by the syndicate.
+ Any surviving personnel are to evacuate immediately via the gateway.
+ "}
+
+/obj/item/weapon/paper/terrorspiders2
+ name = "paper - 'The Trio of Terror'"
+ info = {"Status Report on the 'Terrors'
+
+ All the spiders are deadly. We know this much already. Within an hour of their appearance, they have killed several staff.
+ Three, however, bear particular mention, as they appear to be leading the spider hivemind.
+
+ The Mother is held in containment 1. Advise leaving her alone.
+ It is likely that the hundreds of tiny spiders swarming over her back would come to her defense if she was threatened.
+
+ The Prince is held in containment 2. He appears very aggressive, incredibly fast, strong, and durable. Extreme force and agility would be required to neutralize him.
+ It is likely the appearance of the prince was related to our initial aggression against the Queen. These things can THINK.
+
+ The Queen cannot be contained. She lives in the old bar, south of mining. She continues to breed dangerous spiders at an alarming rate.
+ Many of her offspring are already roaming the compound, traveling through the vents. Contact with the team sent to subdue her has been lost.
+
+
+ Based on the situation, Commander, I advise immediate evacuation through the gateway.
+ -Research Director Simons
+ "}
+
+
+/obj/item/weapon/paper/terrorspiders3
+ name = "paper - 'Final Report'"
+ info = {"FROM: Field Agent 0738
+ TO: Syndicate #873589
+ SUBJECT: Mission Success
+
+ I have seeded the Terror Queen egg in a dingy looking bar that bored engineers constructed near the mining tunnels.
+ No doubt she will grow soon.
+
+ I have also placed the Mother and Prince eggs nearby, injected with sedative. Hopefully the dimwitted NT scientists bring them back for study.
+ With any luck, the Queen will sense them telepathically, think NT is holding her children hostage, and attack.
+
+ I am going to extract out of the gateway before this all goes down.
+ I don't imagine the staff have very long to live once the Queen declares war on this place.
+ "}
+
+/obj/item/weapon/paper/terrorspiders4
+ name = "paper - 'Prescription for Jones, David'"
+ info = {"PRESCRIPTION FOR: David Jones
+ RANK: Miner
+ FOR: Haloperidol
+ REASON FOR TREATMENT: Hallucinations, Paranoia
+ CAUSE: Hallucinations caused by encounter with toxic spit of spider in the caves. Paranoia caused by disappearing staff and suspicions of syndicate infiltration.
+ TREATMENT PLAN: Take as needed. See Dr. Phloxi in one week if symptoms persist.
+ "}
+
+/obj/item/weapon/paper/terrorspiders5
+ name = "paper - 'A Study in Terror'"
+ info = {"Findings Overview
+
+
Gray Spiders Stealthy predators that ambush prey from vents. Otherwise weak.
+
Red Spiders Can kill anyone in melee, but slow.
+
Green Will lay eggs on dead bodies, breeding more spiders.
+
Black Even a single bite is enough to kill a humanoid, given time.
+
White Injects a parasitic agent. Deemed to pose too great an infection risk to study.
+
Purple Only seen guarding the nest of the Queen to the south. Appear to be territorial, and very dangerous.
+
Prince Held in containment 2. Appears to be a sort of super-warrior. Fast, strong, and thickly armored.
+
Mother Carries hordes of spiderlings on its back. Held in containment 1.
+
Queen Unable to contain. Present south of Cargo before contact was lost. Presumed ruler of the local hive.
+ "}
+
+/obj/item/weapon/paper/terrorspiders6
+ name = "paper - 'A Study in Venom'"
+ info = {"Initial Report - Black Widow Venom
+
+ Even a single bite kills within a few minutes. Immediate charcoal is necessary for the victim to survive.
+ The fascinating thing is that multiple bites actually cause rapid symptom onset. The victim quickly loses the ability to walk.
+ One test monkey went from perfect health to death in under 60 seconds - from 3 bites.
+ I am so very glad I'm not responsible for keeping these things contained."}
+
+/obj/item/weapon/paper/terrorspiders7
+ name = "paper - 'Security Orders'"
+ info = {"Directives for Officer James
+
+ 1. Find a way to lift the bridge lockdown.
+ 2. Kill any spiders you encounter.
+ 3. Once on the bridge, open a path to the Queen in the south, and find a way to kill her, ending the infestation.
+ Good luck, Officer.
+ "}
+
+/obj/item/weapon/paper/terrorspiders8
+ name = "paper - 'Last Words'"
+ info = {"The Last Words of Nurse Barnes
+
+ It is too much. First Phil, then those damn spiders bite Mary too. Heaven help us.
+ I'll be evacuating as soon as I've grabbed my supplies. I had to pay for those myself. Stupid budget cuts.
+ The new world they've found for us isn't that hospitable, but at least there are no deadly spid---
+ (the writing trails off, as if the writer was interrupted)
+ "}
+
+
+/obj/item/weapon/gun/energy/laser/awaymission_aeg
+ name = "Wireless Energy Gun"
+ desc = "An energy gun that recharges wirelessly during away missions. Does not work on the main station."
+ force = 10
+ origin_tech = null
+ selfcharge = 1
+ can_charge = 0
+ var/inawaymission = 1
+
+/obj/item/weapon/gun/energy/laser/awaymission_aeg/process()
+ var/turf/my_loc = get_turf(src)
+ if(is_away_level(my_loc.z))
+ if(inawaymission)
+ return ..()
+ if(ismob(loc))
+ to_chat(loc, "Your [src] activates, starting to draw power from a nearby wireless power source.")
+ inawaymission = 1
+ else
+ if(inawaymission)
+ if(ismob(loc))
+ to_chat(loc, "Your [src] deactivates, as it is out of range from its power source.")
+ power_supply.charge = 0
+ inawaymission = 0
+ update_icon()
+
+
+
+/obj/item/weapon/reagent_containers/glass/beaker/terror_black_toxin
+ name = "beaker 'Black Terror Venom'"
+
+/obj/item/weapon/reagent_containers/glass/beaker/terror_black_toxin/New()
+ ..()
+ reagents.add_reagent("terror_black_toxin", 50)
+ update_icon()
+
+
+/obj/machinery/computer/id_upgrader
+ name = "ID Upgrade Machine"
+ icon_state = "guest"
+ icon_screen = "pass"
+ var/list/access_to_give = list(access_away01)
+ var/beenused = 0
+ var/door_to_open = "UO71_Start"
+
+/obj/machinery/computer/id_upgrader/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/weapon/card/id))
+ var/obj/item/weapon/card/id/D = I
+ if(!access_to_give.len)
+ to_chat(user, "This machine appears to be configured incorrectly.")
+ return
+ var/did_upgrade = 0
+ var/list/id_access = D.GetAccess()
+ for(var/this_access in access_to_give)
+ if(!(this_access in id_access))
+ // don't have it - add it
+ D.access |= this_access
+ did_upgrade = 1
+ if(did_upgrade)
+ to_chat(user, "An access type was added to your ID card.")
+ if(beenused)
+ return
+ spawn(1)
+ beenused = 1
+ var/unlocked_something = 0
+ for(var/obj/machinery/door/poddoor/P in airlocks)
+ if(P.density && P.id_tag == door_to_open && P.z == z)
+ P.open()
+ unlocked_something = 1
+ if(unlocked_something)
+ to_chat(user, "Activating the machine has unlocked a way forward!")
+ else
+ to_chat(user, "Your ID card already has all the access this machine can give.")
+ . = 1
+
+
diff --git a/code/modules/awaymissions/mission_code/beach.dm b/code/modules/awaymissions/mission_code/beach.dm
index fd54ffaa7ee..7ae37e759c1 100644
--- a/code/modules/awaymissions/mission_code/beach.dm
+++ b/code/modules/awaymissions/mission_code/beach.dm
@@ -18,6 +18,7 @@
if(water_timer)
deltimer(water_timer)
water_timer = null
+ return ..()
/obj/effect/waterfall/proc/drip()
var/obj/effect/effect/water/W = new(loc)
diff --git a/code/modules/awaymissions/mission_code/centcomAway.dm b/code/modules/awaymissions/mission_code/centcomAway.dm
index 06f36c5bf44..8f86980e276 100644
--- a/code/modules/awaymissions/mission_code/centcomAway.dm
+++ b/code/modules/awaymissions/mission_code/centcomAway.dm
@@ -3,9 +3,8 @@
/area/awaymission/centcomAway
name = "XCC-P5831"
icon_state = "away"
- requires_power = 0
report_alerts = 0
-
+
/area/awaymission/centcomAway/general
name = "XCC-P5831"
music = "music/ambigen3.ogg"
diff --git a/code/modules/awaymissions/mission_code/spacehotel.dm b/code/modules/awaymissions/mission_code/spacehotel.dm
index d1e9a9555be..0cd06c5d6a7 100644
--- a/code/modules/awaymissions/mission_code/spacehotel.dm
+++ b/code/modules/awaymissions/mission_code/spacehotel.dm
@@ -92,8 +92,8 @@
icon = 'icons/obj/doors/Doorsand.dmi'
icon_state = "door_closed"
autoclose = 1
- var/doorOpen = 'sound/machines/airlock.ogg'
- var/doorClose = 'sound/machines/airlock.ogg'
+ var/doorOpen = 'sound/machines/airlock_open.ogg'
+ var/doorClose = 'sound/machines/airlock_close.ogg'
var/doorDeni = 'sound/machines/DeniedBeep.ogg'
var/id // the room number, eg 101
var/obj/item/weapon/card/hotel_card/card// room's key card
@@ -116,8 +116,7 @@
if(roomtimer)
deltimer(roomtimer)
roomtimer = null
- qdel(card)
- card = null
+ QDEL_NULL(card)
return ..()
/obj/machinery/door/unpowered/hotel_door/examine(mob/user)
@@ -220,9 +219,7 @@
vacant_rooms.Cut()
guests.Cut()
- if(radio)
- qdel(radio)
- radio = null
+ QDEL_NULL(radio)
return ..()
diff --git a/code/modules/awaymissions/mission_code/wildwest.dm b/code/modules/awaymissions/mission_code/wildwest.dm
index dd1afe83361..0a2eaeef1bf 100644
--- a/code/modules/awaymissions/mission_code/wildwest.dm
+++ b/code/modules/awaymissions/mission_code/wildwest.dm
@@ -83,9 +83,9 @@
if(ishuman(user))
var/mob/living/carbon/human/human = user
if(human.species.name != "Shadow")
- to_chat(user, "\red Your flesh rapidly mutates!")
+ to_chat(user, "Your flesh rapidly mutates!")
to_chat(user, "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids.")
- to_chat(user, "\red Your body reacts violently to light. \green However, it naturally heals in darkness.")
+ to_chat(user, "Your body reacts violently to light.However, it naturally heals in darkness.")
to_chat(user, "Aside from your new traits, you are mentally unchanged and retain your prior obligations.")
human.set_species("Shadow")
user.regenerate_icons()
@@ -96,9 +96,9 @@
if(ishuman(user))
var/mob/living/carbon/human/human = user
if(human.species.name != "Shadow")
- to_chat(user, "\red Your flesh rapidly mutates!")
+ to_chat(user, "Your flesh rapidly mutates!")
to_chat(user, "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids.")
- to_chat(user, "\red Your body reacts violently to light. \green However, it naturally heals in darkness.")
+ to_chat(user, "Your body reacts violently to light.However, it naturally heals in darkness.")
to_chat(user, "Aside from your new traits, you are mentally unchanged and retain your prior obligations.")
human.set_species("Shadow")
user.regenerate_icons()
@@ -109,9 +109,9 @@
if(ishuman(user))
var/mob/living/carbon/human/human = user
if(human.species.name != "Shadow")
- to_chat(user, "\red Your flesh rapidly mutates!")
+ to_chat(user, "Your flesh rapidly mutates!")
to_chat(user, "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids.")
- to_chat(user, "\red Your body reacts violently to light. \green However, it naturally heals in darkness.")
+ to_chat(user, "Your body reacts violently to light.However, it naturally heals in darkness.")
to_chat(user, "Aside from your new traits, you are mentally unchanged and retain your prior obligations.")
human.set_species("Shadow")
user.regenerate_icons()
@@ -131,9 +131,9 @@
if(ishuman(user))
var/mob/living/carbon/human/human = user
if(human.species.name != "Shadow")
- to_chat(user, "\red Your flesh rapidly mutates!")
+ to_chat(user, "Your flesh rapidly mutates!")
to_chat(user, "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids.")
- to_chat(user, "\red Your body reacts violently to light. \green However, it naturally heals in darkness.")
+ to_chat(user, "Your body reacts violently to light.However, it naturally heals in darkness.")
to_chat(user, "Aside from your new traits, you are mentally unchanged and retain your prior obligations.")
human.set_species("Shadow")
user.regenerate_icons()
diff --git a/code/modules/awaymissions/zlevel.dm b/code/modules/awaymissions/zlevel.dm
index d340fc6a651..50b09d72788 100644
--- a/code/modules/awaymissions/zlevel.dm
+++ b/code/modules/awaymissions/zlevel.dm
@@ -70,6 +70,7 @@ var/global/list/potentialRandomZlevels = generateMapList(filename = "config/away
log_startup_progress(" No away missions found.")
return
+
/proc/createALLZlevels()
if(awaydestinations.len) //crude, but it saves another var!
return
diff --git a/code/modules/awaymissions/zvis.dm b/code/modules/awaymissions/zvis.dm
index 735dd307ddb..73bbff2198f 100644
--- a/code/modules/awaymissions/zvis.dm
+++ b/code/modules/awaymissions/zvis.dm
@@ -111,8 +111,7 @@
init(R)
/turf/unsimulated/floor/upperlevel/Destroy()
- qdel(sensor)
- sensor = null
+ QDEL_NULL(sensor)
return ..()
/turf/unsimulated/floor/upperlevel/proc/init(var/obj/effect/levelref/R)
diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm
index e02a1a8d810..72534169e6d 100644
--- a/code/modules/client/asset_cache.dm
+++ b/code/modules/client/asset_cache.dm
@@ -225,6 +225,29 @@ proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE)
"boardui.js" = 'html/browser/boardui.js'
)
+/datum/asset/simple/headers
+ assets = list(
+ "alarm_green.gif" = 'icons/program_icons/alarm_green.gif',
+ "alarm_red.gif" = 'icons/program_icons/alarm_red.gif',
+ "batt_5.gif" = 'icons/program_icons/batt_5.gif',
+ "batt_20.gif" = 'icons/program_icons/batt_20.gif',
+ "batt_40.gif" = 'icons/program_icons/batt_40.gif',
+ "batt_60.gif" = 'icons/program_icons/batt_60.gif',
+ "batt_80.gif" = 'icons/program_icons/batt_80.gif',
+ "batt_100.gif" = 'icons/program_icons/batt_100.gif',
+ "charging.gif" = 'icons/program_icons/charging.gif',
+ "downloader_finished.gif" = 'icons/program_icons/downloader_finished.gif',
+ "downloader_running.gif" = 'icons/program_icons/downloader_running.gif',
+ "ntnrc_idle.gif" = 'icons/program_icons/ntnrc_idle.gif',
+ "ntnrc_new.gif" = 'icons/program_icons/ntnrc_new.gif',
+ "power_norm.gif" = 'icons/program_icons/power_norm.gif',
+ "power_warn.gif" = 'icons/program_icons/power_warn.gif',
+ "sig_high.gif" = 'icons/program_icons/sig_high.gif',
+ "sig_low.gif" = 'icons/program_icons/sig_low.gif',
+ "sig_lan.gif" = 'icons/program_icons/sig_lan.gif',
+ "sig_none.gif" = 'icons/program_icons/sig_none.gif',
+ )
+
/datum/asset/nanoui
var/list/common = list()
diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm
index 894b5d39951..f846a1613bf 100644
--- a/code/modules/client/client procs.dm
+++ b/code/modules/client/client procs.dm
@@ -111,6 +111,8 @@
to_chat(usr, "You do not have enough karma!")
return
else
+ if(alert("Are you sure you want to unlock Barber?", "Confirmation", "No", "Yes") != "Yes")
+ return
DB_job_unlock("Barber",5)
return
if("2")
@@ -118,6 +120,8 @@
to_chat(usr, "You do not have enough karma!")
return
else
+ if(alert("Are you sure you want to unlock Brig Physician?", "Confirmation", "No", "Yes") != "Yes")
+ return
DB_job_unlock("Brig Physician",5)
return
if("3")
@@ -125,6 +129,8 @@
to_chat(usr, "You do not have enough karma!")
return
else
+ if(alert("Are you sure you want to unlock Nanotrasen Representative?", "Confirmation", "No", "Yes") != "Yes")
+ return
DB_job_unlock("Nanotrasen Representative",30)
return
if("5")
@@ -132,6 +138,8 @@
to_chat(usr, "You do not have enough karma!")
return
else
+ if(alert("Are you sure you want to unlock Blueshield?", "Confirmation", "No", "Yes") != "Yes")
+ return
DB_job_unlock("Blueshield",30)
return
if("6")
@@ -139,6 +147,8 @@
to_chat(usr, "You do not have enough karma!")
return
else
+ if(alert("Are you sure you want to unlock Mechanic?", "Confirmation", "No", "Yes") != "Yes")
+ return
DB_job_unlock("Mechanic",30)
return
if("7")
@@ -146,6 +156,8 @@
to_chat(usr, "You do not have enough karma!")
return
else
+ if(alert("Are you sure you want to unlock Magistrate?", "Confirmation", "No", "Yes") != "Yes")
+ return
DB_job_unlock("Magistrate",45)
return
if("9")
@@ -153,6 +165,8 @@
to_chat(usr, "You do not have enough karma!")
return
else
+ if(alert("Are you sure you want to unlock Security Pod Pilot?", "Confirmation", "No", "Yes") != "Yes")
+ return
DB_job_unlock("Security Pod Pilot",30)
return
if(href_list["KarmaBuy2"])
@@ -163,6 +177,8 @@
to_chat(usr, "You do not have enough karma!")
return
else
+ if(alert("Are you sure you want to unlock Machine People?", "Confirmation", "No", "Yes") != "Yes")
+ return
DB_species_unlock("Machine",15)
return
if("2")
@@ -170,6 +186,8 @@
to_chat(usr, "You do not have enough karma!")
return
else
+ if(alert("Are you sure you want to unlock Kidan?", "Confirmation", "No", "Yes") != "Yes")
+ return
DB_species_unlock("Kidan",30)
return
if("3")
@@ -177,6 +195,8 @@
to_chat(usr, "You do not have enough karma!")
return
else
+ if(alert("Are you sure you want to unlock Grey?", "Confirmation", "No", "Yes") != "Yes")
+ return
DB_species_unlock("Grey",30)
return
if("4")
@@ -184,6 +204,8 @@
to_chat(usr, "You do not have enough karma!")
return
else
+ if(alert("Are you sure you want to unlock Vox?", "Confirmation", "No", "Yes") != "Yes")
+ return
DB_species_unlock("Vox",45)
return
if("5")
@@ -191,6 +213,8 @@
to_chat(usr, "You do not have enough karma!")
return
else
+ if(alert("Are you sure you want to unlock Slime People?", "Confirmation", "No", "Yes") != "Yes")
+ return
DB_species_unlock("Slime People",45)
return
if("6")
@@ -198,6 +222,8 @@
to_chat(usr, "You do not have enough karma!")
return
else
+ if(alert("Are you sure you want to unlock Plasmaman?", "Confirmation", "No", "Yes") != "Yes")
+ return
DB_species_unlock("Plasmaman",100)
return
if("7")
@@ -205,6 +231,8 @@
to_chat(usr, "You do not have enough karma!")
return
else
+ if(alert("Are you sure you want to unlock Drask?", "Confirmation", "No", "Yes") != "Yes")
+ return
DB_species_unlock("Drask",30)
return
if(href_list["KarmaRefund"])
@@ -367,7 +395,7 @@
preload_rsc = pick(config.resource_urls)
else preload_rsc = 1 // If config.resource_urls is not set, preload like normal.
- to_chat(src, "\red If the title screen is black, resources are still downloading. Please be patient until the title screen appears.")
+ to_chat(src, "If the title screen is black, resources are still downloading. Please be patient until the title screen appears.")
clients += src
diff --git a/code/modules/client/preference/loadout/loadout_hat.dm b/code/modules/client/preference/loadout/loadout_hat.dm
index 7e4ca4620d9..2abfd08f8ce 100644
--- a/code/modules/client/preference/loadout/loadout_hat.dm
+++ b/code/modules/client/preference/loadout/loadout_hat.dm
@@ -118,6 +118,11 @@
path = /obj/item/clothing/head/beret/sci
allowed_roles = list("Research Director", "Scientist")
+/datum/gear/hat/med_beret
+ display_name = "medical beret"
+ path = /obj/item/clothing/head/beret/med
+ allowed_roles = list("Chief Medical Officer", "Medical Doctor" , "Virologist", "Brig Physician")
+
/datum/gear/hat/surgicalcap_purple
display_name = "surgical cap, purple"
path = /obj/item/clothing/head/surgery/purple
diff --git a/code/modules/client/preference/loadout/loadout_shoes.dm b/code/modules/client/preference/loadout/loadout_shoes.dm
index ec32e30d661..ead7257bba1 100644
--- a/code/modules/client/preference/loadout/loadout_shoes.dm
+++ b/code/modules/client/preference/loadout/loadout_shoes.dm
@@ -7,6 +7,14 @@
display_name = "sandals, wooden"
path = /obj/item/clothing/shoes/sandal
+/datum/gear/shoes/winterboots
+ display_name = "winter boots"
+ path = /obj/item/clothing/shoes/winterboots
+
+/datum/gear/shoes/workboots
+ display_name = "work boots"
+ path = /obj/item/clothing/shoes/workboots
+
/datum/gear/shoes/fancysandals
display_name = "sandals, fancy"
cost = 5
diff --git a/code/modules/client/preference/loadout/loadout_uniform.dm b/code/modules/client/preference/loadout/loadout_uniform.dm
index d7df4da720b..82ccc357312 100644
--- a/code/modules/client/preference/loadout/loadout_uniform.dm
+++ b/code/modules/client/preference/loadout/loadout_uniform.dm
@@ -36,7 +36,7 @@
/datum/gear/uniform/skirt/job/atmos
display_name = "skirt, atmos"
path = /obj/item/clothing/under/rank/atmospheric_technician/skirt
- allowed_roles = list("Chief Engineer","Atmospheric Technician")
+ allowed_roles = list("Chief Engineer","Life Support Specialist")
/datum/gear/uniform/skirt/job/eng
display_name = "skirt, engineer"
@@ -50,7 +50,7 @@
/datum/gear/uniform/skirt/job/cmo
display_name = "skirt, cmo"
- path = /obj/item/clothing/under/rank/chief_medical_officer
+ path = /obj/item/clothing/under/rank/chief_medical_officer/skirt
allowed_roles = list("Chief Medical Officer")
/datum/gear/uniform/skirt/job/chem
diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm
index 15af19c19e4..ed3a19a0ca5 100644
--- a/code/modules/client/preference/preferences.dm
+++ b/code/modules/client/preference/preferences.dm
@@ -108,7 +108,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
var/underwear = "Nude" //underwear type
var/undershirt = "Nude" //undershirt type
var/socks = "Nude" //socks type
- var/backbag = 2 //backpack type
+ var/backbag = GBACKPACK //backpack type
var/ha_style = "None" //Head accessory style
var/r_headacc = 0 //Head accessory colour
var/g_headacc = 0 //Head accessory colour
@@ -175,7 +175,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
var/job_karma_low = 0
//Keeps track of preferrence for not getting any wanted jobs
- var/alternate_option = 0
+ var/alternate_option = 2
// maps each organ to either null(intact), "cyborg" or "amputated"
// will probably not be able to do this for head and torso ;)
@@ -268,9 +268,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
dat += "
"
@@ -279,7 +279,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
dat += "You are banned from using custom names and appearances. \
You can continue to adjust your characters, but you will be randomised once you join the game.\
"
- dat += "Gender:[gender == MALE ? "Male" : "Female"] "
+ dat += "Gender:[gender == MALE ? "Male" : (gender == FEMALE ? "Female" : "Genderless")]"
+ dat += " "
dat += "Age:[age] "
dat += "Body:(®) "
dat += "Species:[species] "
@@ -293,7 +294,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
dat += "Skin Tone:[species == "Vox" ? "[s_tone]" : "[-s_tone + 35]/220"] "
dat += "Disabilities:\[Set\] "
dat += "Nanotrasen Relation:[nanotrasen_relation] "
- dat += "Set Flavor Text "
+ dat += "Set Flavor Text "
if(lentext(flavor_text) <= 40)
if(!lentext(flavor_text)) dat += "\[...\] "
else dat += "[flavor_text] "
@@ -301,7 +302,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
dat += "
Hair & Accessories
"
- if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) //Species that have head accessories.
+ if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine", "Kidan")) //Species that have head accessories.
var/headaccessoryname = "Head Accessory: "
if(species == "Unathi")
headaccessoryname = "Horns: "
@@ -357,7 +358,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
if(jobban_isbanned(user, "Records"))
dat += "You are banned from using character records. "
else
- dat += "Character Records "
+ dat += "Character Records "
dat += "
Limbs
"
if(species in list("Unathi")) //Species with alt heads.
@@ -414,7 +415,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
dat += "Underwear:[underwear] "
dat += "Undershirt:[undershirt] "
dat += "Socks:[socks] "
- dat += "Backpack Type:[backbaglist[backbag]] "
+ dat += "Backpack Type:[backbag] "
dat += "
"
@@ -657,7 +658,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
else
HTML += " \[No]"
if(job.alt_titles)
- HTML += " \[[GetPlayerAltTitle(job)]\]
"
+ HTML += " \[[GetPlayerAltTitle(job)]\]"
HTML += ""
continue
/*
@@ -673,7 +674,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
HTML += "[prefLevelLabel]"
if(job.alt_titles)
- HTML += " \[[GetPlayerAltTitle(job)]\]"
+ HTML += " \[[GetPlayerAltTitle(job)]\]"
HTML += ""
@@ -787,7 +788,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
return
if(!isnum(desiredLvl))
- to_chat(user, "\red UpdateJobPreference - desired level was not a number. Please notify coders!")
+ to_chat(user, "UpdateJobPreference - desired level was not a number. Please notify coders!")
ShowChoices(user)
return
@@ -811,12 +812,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
/datum/preferences/proc/SetDisabilities(mob/user)
var/HTML = ""
+ HTML += "
"
- // AUTOFIXED BY fix_string_idiocy.py
- // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\client\preferences.dm:474: HTML += "
"
- HTML += {"
- Choose disabilities
"}
- // END AUTOFIX
HTML += ShowDisabilityState(user,DISABILITY_FLAG_NEARSIGHTED,"Needs Glasses")
HTML += ShowDisabilityState(user,DISABILITY_FLAG_FAT,"Obese")
HTML += ShowDisabilityState(user,DISABILITY_FLAG_EPILEPTIC,"Seizures")
@@ -826,50 +823,46 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
HTML += ShowDisabilityState(user,DISABILITY_FLAG_MUTE,"Mute")
- // AUTOFIXED BY fix_string_idiocy.py
- // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\client\preferences.dm:481: HTML += "
"
- HTML += "Set Character Records "
- HTML += "Medical Records "
+ HTML += "Medical Records "
if(lentext(med_record) <= 40)
HTML += "[med_record]"
else
HTML += "[copytext(med_record, 1, 37)]..."
- HTML += "
Employment Records "
+ HTML += " Employment Records "
if(lentext(gen_record) <= 40)
HTML += "[gen_record]"
else
HTML += "[copytext(gen_record, 1, 37)]..."
- HTML += "
Security Records "
+ HTML += " Security Records "
if(lentext(sec_record) <= 40)
HTML += "[sec_record] "
else
HTML += "[copytext(sec_record, 1, 37)]... "
- HTML += " "
- HTML += "\[Done\]"
+ HTML += "\[Done\]"
HTML += "
"
- user << browse(null, "window=preferences")
- user << browse(HTML, "window=records;size=350x300")
- return
+ var/datum/browser/popup = new(user, "records", "
Character Records
", 350, 300)
+ popup.set_content(HTML)
+ popup.open(0)
/datum/preferences/proc/GetPlayerAltTitle(datum/job/job)
return player_alt_titles.Find(job.title) > 0 \
@@ -1031,6 +1024,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
/datum/preferences/proc/process_link(mob/user, list/href_list)
if(!user) return
+ var/datum/species/S = all_species[species]
if(href_list["preference"] == "job")
switch(href_list["task"])
if("close")
@@ -1240,7 +1234,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
g_skin = rand(0,255)
b_skin = rand(0,255)
if("bag")
- backbag = rand(1,4)
+ backbag = pick(backbaglist)
/*if("skin_style")
h_style = random_skin_style(gender)*/
if("all")
@@ -1266,9 +1260,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
// var/whitelisted = 0
if(config.usealienwhitelist) //If we're using the whitelist, make sure to check it!
- for(var/S in whitelisted_species)
- if(is_alien_whitelisted(user,S))
- new_species += S
+ for(var/Spec in whitelisted_species)
+ if(is_alien_whitelisted(user,Spec))
+ new_species += Spec
// whitelisted = 1
// if(!whitelisted)
// alert(user, "You cannot change your species as you need to be whitelisted. If you wish to be whitelisted contact an admin in-game, on the forums, or on IRC.")
@@ -1276,8 +1270,10 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
new_species += whitelisted_species
species = input("Please select a species", "Character Generation", null) in new_species
-
+ var/datum/species/NS = all_species[species]
if(prev_species != species)
+ if(NS.has_gender && gender == PLURAL)
+ gender = pick(MALE,FEMALE)
var/datum/robolimb/robohead
if(species == "Machine")
var/head_model = "[!rlimb_data["head"] ? "Morpheus Cyberkinetics" : rlimb_data["head"]]"
@@ -1315,16 +1311,16 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
m_colours["tail"] = "#000000"
// Don't wear another species' underwear!
- var/datum/sprite_accessory/S = underwear_list[underwear]
- if(!S || !(species in S.species_allowed))
+ var/datum/sprite_accessory/SA = underwear_list[underwear]
+ if(!SA || !(species in SA.species_allowed))
underwear = random_underwear(gender, species)
- S = undershirt_list[undershirt]
- if(!S || !(species in S.species_allowed))
+ SA = undershirt_list[undershirt]
+ if(!SA || !(species in SA.species_allowed))
undershirt = random_undershirt(gender, species)
- S = socks_list[socks]
- if(!S || !(species in S.species_allowed))
+ SA = socks_list[socks]
+ if(!SA || !(species in SA.species_allowed))
socks = random_socks(gender, species)
//reset skin tone and colour
@@ -1402,7 +1398,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
if("h_style")
var/list/valid_hairstyles = list()
for(var/hairstyle in hair_styles_list)
- var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
+ var/datum/sprite_accessory/SA = hair_styles_list[hairstyle]
if(hairstyle == "Bald") //Just in case.
valid_hairstyles += hairstyle
@@ -1414,14 +1410,14 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
else
head_model = rlimb_data["head"]
var/datum/robolimb/robohead = all_robolimbs[head_model]
- if((species in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list.
+ if((species in SA.species_allowed) && robohead.is_monitor && ((SA.models_allowed && (robohead.company in SA.models_allowed)) || !SA.models_allowed)) //If this is a hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list.
valid_hairstyles += hairstyle //Give them their hairstyles if they do.
else
- if(!robohead.is_monitor && ("Human" in S.species_allowed)) /*If the hairstyle is not native to the user's species and they're using a head with an ipc-style screen, don't let them access it.
+ if(!robohead.is_monitor && ("Human" in SA.species_allowed)) /*If the hairstyle is not native to the user's species and they're using a head with an ipc-style screen, don't let them access it.
But if the user has a robotic humanoid head and the hairstyle can fit humans, let them use it as a wig. */
valid_hairstyles += hairstyle
else //If the user is not a species who can have robotic heads, use the default handling.
- if(species in S.species_allowed) //If the user's head is of a species the hairstyle allows, add it to the list.
+ if(species in SA.species_allowed) //If the user's head is of a species the hairstyle allows, add it to the list.
valid_hairstyles += hairstyle
var/new_h_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in valid_hairstyles
@@ -1429,7 +1425,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
h_style = new_h_style
if("headaccessory")
- if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) //Species with head accessories.
+ if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine", "Kidan")) //Species with head accessories.
var/input = "Choose the colour of your your character's head accessory:"
var/new_head_accessory = input(user, input, "Character Preference", rgb(r_headacc, g_headacc, b_headacc)) as color|null
if(new_head_accessory)
@@ -1438,7 +1434,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
b_headacc = color2B(new_head_accessory)
if("ha_style")
- if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) //Species with head accessories.
+ if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine", "Kidan")) //Species with head accessories.
var/list/valid_head_accessory_styles = list()
for(var/head_accessory_style in head_accessory_styles_list)
var/datum/sprite_accessory/H = head_accessory_styles_list[head_accessory_style]
@@ -1609,14 +1605,14 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
if("f_style")
var/list/valid_facial_hairstyles = list()
for(var/facialhairstyle in facial_hair_styles_list)
- var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle]
+ var/datum/sprite_accessory/SA = facial_hair_styles_list[facialhairstyle]
if(facialhairstyle == "Shaved") //Just in case.
valid_facial_hairstyles += facialhairstyle
continue
- if(gender == MALE && S.gender == FEMALE)
+ if(gender == MALE && SA.gender == FEMALE)
continue
- if(gender == FEMALE && S.gender == MALE)
+ if(gender == FEMALE && SA.gender == MALE)
continue
if(species == "Machine") //Species that can use prosthetic heads.
var/head_model
@@ -1625,14 +1621,14 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
else
head_model = rlimb_data["head"]
var/datum/robolimb/robohead = all_robolimbs[head_model]
- if((species in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a facial hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list.
+ if((species in SA.species_allowed) && robohead.is_monitor && ((SA.models_allowed && (robohead.company in SA.models_allowed)) || !SA.models_allowed)) //If this is a facial hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list.
valid_facial_hairstyles += facialhairstyle //Give them their facial hairstyles if they do.
else
- if(!robohead.is_monitor && ("Human" in S.species_allowed)) /*If the facial hairstyle is not native to the user's species and they're using a head with an ipc-style screen, don't let them access it.
+ if(!robohead.is_monitor && ("Human" in SA.species_allowed)) /*If the facial hairstyle is not native to the user's species and they're using a head with an ipc-style screen, don't let them access it.
But if the user has a robotic humanoid head and the facial hairstyle can fit humans, let them use it as a wig. */
valid_facial_hairstyles += facialhairstyle
else //If the user is not a species who can have robotic heads, use the default handling.
- if(species in S.species_allowed) //If the user's head is of a species the facial hair style allows, add it to the list.
+ if(species in SA.species_allowed) //If the user's head is of a species the facial hair style allows, add it to the list.
valid_facial_hairstyles += facialhairstyle
var/new_f_style = input(user, "Choose your character's facial-hair style:", "Character Preference") as null|anything in valid_facial_hairstyles
@@ -1642,12 +1638,12 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
if("underwear")
var/list/valid_underwear = list()
for(var/underwear in underwear_list)
- var/datum/sprite_accessory/S = underwear_list[underwear]
- if(gender == MALE && S.gender == FEMALE)
+ var/datum/sprite_accessory/SA = underwear_list[underwear]
+ if(gender == MALE && SA.gender == FEMALE)
continue
- if(gender == FEMALE && S.gender == MALE)
+ if(gender == FEMALE && SA.gender == MALE)
continue
- if(!(species in S.species_allowed))
+ if(!(species in SA.species_allowed))
continue
valid_underwear[underwear] = underwear_list[underwear]
var/new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in valid_underwear
@@ -1657,12 +1653,12 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
if("undershirt")
var/list/valid_undershirts = list()
for(var/undershirt in undershirt_list)
- var/datum/sprite_accessory/S = undershirt_list[undershirt]
- if(gender == MALE && S.gender == FEMALE)
+ var/datum/sprite_accessory/SA = undershirt_list[undershirt]
+ if(gender == MALE && SA.gender == FEMALE)
continue
- if(gender == FEMALE && S.gender == MALE)
+ if(gender == FEMALE && SA.gender == MALE)
continue
- if(!(species in S.species_allowed))
+ if(!(species in SA.species_allowed))
continue
valid_undershirts[undershirt] = undershirt_list[undershirt]
var/new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in valid_undershirts
@@ -1673,12 +1669,12 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
if("socks")
var/list/valid_sockstyles = list()
for(var/sockstyle in socks_list)
- var/datum/sprite_accessory/S = socks_list[sockstyle]
- if(gender == MALE && S.gender == FEMALE)
+ var/datum/sprite_accessory/SA = socks_list[sockstyle]
+ if(gender == MALE && SA.gender == FEMALE)
continue
- if(gender == FEMALE && S.gender == MALE)
+ if(gender == FEMALE && SA.gender == MALE)
continue
- if(!(species in S.species_allowed))
+ if(!(species in SA.species_allowed))
continue
valid_sockstyles[sockstyle] = socks_list[sockstyle]
var/new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in valid_sockstyles
@@ -1718,9 +1714,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
ooccolor = new_ooccolor
if("bag")
- var/new_backbag = input(user, "Choose your character's style of bag:", "Character Preference") as null|anything in backbaglist
+ var/new_backbag = input(user, "Choose your character's style of bag:", "Character Preference") as null|anything in backbaglist
if(new_backbag)
- backbag = backbaglist.Find(new_backbag)
+ backbag = new_backbag
if("nt_relation")
var/new_relation = input(user, "Choose your relation to NT. Note that this represents what others can find out about your character by researching your background, not what your character actually thinks.", "Character Preference") as null|anything in list("Loyal", "Supportive", "Neutral", "Skeptical", "Opposed")
@@ -1909,10 +1905,20 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
toggles ^= DONATOR_PUBLIC
if("gender")
- if(gender == MALE)
- gender = FEMALE
+ if(!S.has_gender)
+ var/newgender = input(user, "Choose Gender:") as null|anything in list("Male", "Female", "Genderless")
+ switch(newgender)
+ if("Male")
+ gender = MALE
+ if("Female")
+ gender = FEMALE
+ if("Genderless")
+ gender = PLURAL
else
- gender = MALE
+ if(gender == MALE)
+ gender = FEMALE
+ else
+ gender = MALE
underwear = random_underwear(gender)
if("hear_adminhelps")
@@ -2150,12 +2156,10 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
if(body_accessory)
character.body_accessory = body_accessory_by_name["[body_accessory]"]
- if(backbag > 4 || backbag < 1)
- backbag = 1 //Same as above
character.backbag = backbag
//Debugging report to track down a bug, which randomly assigned the plural gender to people.
- if(character.gender in list(PLURAL, NEUTER))
+ if(S.has_gender && (character.gender in list(PLURAL, NEUTER)))
if(isliving(src)) //Ghosts get neuter by default
message_admins("[key_name_admin(character)] has spawned with their gender as plural or neuter. Please notify coders.")
character.change_gender(MALE)
@@ -2224,7 +2228,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
dat += "[name] "
dat += ""
- dat += "Close "
+ dat += "Close "
dat += "
"
- else
- dat += "<--"
- dat += " [categories[prev_cat()]] |"
- dat += " [categories[viewing_category]] "
- dat += "| [categories[next_cat()]] "
- dat += "-->
"
-
- dat += "
"
-
- //Filter the recipes we can craft to the top
- var/list/can_craft = list()
- var/list/cant_craft = list()
- for(var/datum/crafting_recipe/R in crafting_recipes)
- if(R.category != categories[viewing_category])
- continue
- if(check_contents(R, surroundings))
- can_craft += R
- else
- cant_craft += R
-
- for(var/datum/crafting_recipe/R in can_craft)
- dat += build_recipe_text(R, surroundings)
- for(var/datum/crafting_recipe/R in cant_craft)
- dat += build_recipe_text(R, surroundings)
-
-
- dat += "
"
-
- var/datum/browser/popup = new(user, "crafting", "Crafting", 500, 500)
- popup.set_content(dat)
- popup.open()
- return
+ var/list/can_craft = list()
+ var/list/cant_craft = list()
+ for(var/rec in crafting_recipes)
+ var/datum/crafting_recipe/R = rec
+ if(R.category != cur_category)
+ continue
+ if(check_contents(R, surroundings))
+ can_craft += list(build_recipe_data(R))
+ else
+ cant_craft += list(build_recipe_data(R))
+ data["can_craft"] = can_craft
+ data["cant_craft"] = cant_craft
+ return data
/datum/personal_crafting/Topic(href, href_list)
- if(usr.stat || usr.lying)
+ if(..())
return
+
if(href_list["make"])
var/datum/crafting_recipe/TR = locate(href_list["make"])
busy = 1
- craft(usr)
+ nanomanager.update_uis(src)
var/fail_msg = construct_item(usr, TR)
if(!fail_msg)
- usr << "[TR.name] constructed."
+ to_chat(usr, "[TR.name] constructed.")
else
- usr << "Construction failed[fail_msg]"
+ to_chat(usr, "Construction failed[fail_msg]")
busy = 0
- craft(usr)
+ nanomanager.update_uis(src)
if(href_list["forwardCat"])
viewing_category = next_cat()
- usr << "Category is now [categories[viewing_category]]."
- craft(usr)
+ to_chat(usr, "Category is now [categories[viewing_category]].")
+ . = TRUE
if(href_list["backwardCat"])
viewing_category = prev_cat()
- usr << "Category is now [categories[viewing_category]]."
- craft(usr)
+ to_chat(usr, "Category is now [categories[viewing_category]].")
+ . = TRUE
+ if(href_list["toggle_recipes"])
+ display_craftable_only = !display_craftable_only
+ to_chat(usr, "You will now [display_craftable_only ? "only see recipes you can craft":"see all recipes"].")
+ . = TRUE
+ if(href_list["toggle_compact"])
+ display_compact = !display_compact
+ to_chat(usr, "Crafting menu is now [display_compact? "compact" : "full size"].")
+ . = TRUE
+
+ nanomanager.update_uis(src)
//Next works nicely with modular arithmetic
/datum/personal_crafting/proc/next_cat()
@@ -301,39 +305,32 @@
if(. <= 0)
. = categories.len
-/datum/personal_crafting/proc/build_recipe_text(datum/crafting_recipe/R, list/contents)
- . = ""
- var/name_text = ""
+/datum/personal_crafting/proc/build_recipe_data(datum/crafting_recipe/R)
+ var/list/data = list()
+ data["name"] = R.name
+ data["ref"] = "\ref[R]"
var/req_text = ""
var/tool_text = ""
- var/catalist_text = ""
- if(check_contents(R, contents))
- name_text ="[R.name]"
+ var/catalyst_text = ""
- else
- name_text = "[R.name]"
+ for(var/a in R.reqs)
+ //We just need the name, so cheat-typecast to /atom for speed (even tho Reagents are /datum they DO have a "name" var)
+ //Also these are typepaths so sadly we can't just do "[a]"
+ var/atom/A = a
+ req_text += " [R.reqs[A]] [initial(A.name)],"
+ req_text = replacetext(req_text, ",", "", -1)
+ data["req_text"] = req_text
- if(name_text)
- for(var/A in R.reqs)
- if(ispath(A, /obj))
- var/obj/O = A
- req_text += " [R.reqs[A]] [initial(O.name)]"
- else if(ispath(A, /datum/reagent))
- var/datum/reagent/RE = A
- req_text += " [R.reqs[A]] [initial(RE.name)]"
+ for(var/a in R.chem_catalysts)
+ var/atom/A = a //cheat-typecast
+ catalyst_text += " [R.chem_catalysts[A]] [initial(A.name)],"
+ catalyst_text = replacetext(catalyst_text, ",", "", -1)
+ data["catalyst_text"] = catalyst_text
- if(R.chem_catalists.len)
- catalist_text += ", Catalysts:"
- for(var/C in R.chem_catalists)
- if(ispath(C, /datum/reagent))
- var/datum/reagent/RE = C
- catalist_text += " [R.chem_catalists[C]] [initial(RE.name)]"
+ for(var/a in R.tools)
+ var/atom/A = a //cheat-typecast
+ tool_text += " [R.tools[A]] [initial(A.name)],"
+ tool_text = replacetext(tool_text, ",", "", -1)
+ data["tool_text"] = tool_text
- if(R.tools.len)
- tool_text += ", Tools:"
- for(var/O in R.tools)
- if(ispath(O, /obj))
- var/obj/T = O
- tool_text += " [R.tools[O]] [initial(T.name)]"
-
- . = "[name_text][req_text][tool_text][catalist_text] "
+ return data
\ No newline at end of file
diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm
index d8111a3fed0..ae964af74a8 100644
--- a/code/modules/crafting/recipes.dm
+++ b/code/modules/crafting/recipes.dm
@@ -5,7 +5,7 @@
var/tools[] = list() //type paths of items needed but not consumed
var/time = 30 //time in deciseconds
var/parts[] = list() //type paths of items that will be placed in the result
- var/chem_catalists[] = list() //like tools but for reagents
+ var/chem_catalysts[] = list() //like tools but for reagents
var/category = CAT_MISC // Recipe category
/datum/crafting_recipe/proc/AdjustChems(var/obj/resultobj as obj)
@@ -286,7 +286,7 @@
time = 150
reqs = list(/obj/item/stack/rods = 3,
/obj/item/stack/cable_coil = 10,
- /obj/item/stack/sheet/mineral/plastic = 3,
+ /obj/item/stack/sheet/plastic = 3,
/obj/item/stack/sheet/wood = 5)
tools = list(/obj/item/weapon/weldingtool,
/obj/item/weapon/screwdriver)
diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm
index 97d010439c9..7a9620a1d1a 100644
--- a/code/modules/customitems/item_defines.dm
+++ b/code/modules/customitems/item_defines.dm
@@ -26,6 +26,8 @@
var/tattoo_r = 1 // RGB values for the body markings
var/tattoo_g = 1
var/tattoo_b = 1
+ toolspeed = 1
+ usesound = 'sound/items/Welder2.ogg'
/obj/item/device/fluff/tattoo_gun/attack(mob/living/carbon/M as mob, mob/user as mob)
if(user.a_intent == "harm")
@@ -61,7 +63,7 @@
else
user.visible_message("[user] begins to apply a [tattoo_name] [target] with the [src].", "You begin to tattoo [target] with the [src]!")
- if(!do_after(user,30, target = M))
+ if(!do_after(user, 30 * toolspeed, target = M))
return
user.visible_message("[user] finishes the [tattoo_name] on [target].", "You finish the [tattoo_name].")
@@ -69,7 +71,7 @@
target.change_markings(tattoo_icon, "body")
target.change_marking_color(rgb(tattoo_r, tattoo_g, tattoo_b), "body")
- playsound(src.loc, 'sound/items/Welder2.ogg', 20, 1)
+ playsound(src.loc, usesound, 20, 1)
used = 1
update_icon()
@@ -127,6 +129,12 @@
icon_state = "zeldacrowbar"
item_state = "crowbar"
+/obj/item/clothing/glasses/monocle/fluff/trubus //Trubus: Wolf O'Shaw
+ name = "Gold Thermal Eyepatch"
+ desc = "Wolf's non-functional thermal eyepatch."
+ icon = 'icons/obj/custom_items.dmi'
+ icon_state = "wolf_eyepatch"
+
/obj/item/clothing/glasses/meson/fluff/book_berner_1 // Adrkiller59: Adam Cooper
name = "bespectacled mesonic surveyors"
desc = "One of the older meson scanner models retrofitted to perform like its modern counterparts."
@@ -138,6 +146,28 @@
desc = "A weathered Vox thermonocle, doesn't seem to work anymore."
icon_state = "thermoncle"
+/obj/item/device/fluff/rapid_wheelchair_kit //Rapidvalj: Hakikarahiti
+ name = "wheelchair conversion kit"
+ desc = "An assorted set of exchangable parts for a wheelchair."
+ icon_state = "modkit"
+
+/obj/item/device/fluff/rapid_wheelchair_kit/afterattack(atom/target, mob/user, proximity)
+ if(!proximity || !ishuman(user) || user.incapacitated())
+ return
+
+ if(istype(target, /obj/structure/stool/bed/chair/wheelchair) && !istype(target, /obj/structure/stool/bed/chair/wheelchair/bike))
+ to_chat(user, "You modify the appearance of [target].")
+ var/obj/structure/stool/bed/chair/wheelchair/chair = target
+ chair.icon = 'icons/obj/custom_items.dmi'
+ chair.icon_state = "vox_wheelchair"
+ chair.name = "vox wheelchair"
+ chair.desc = "A luxurious Vox Wheelchair, weathered from use."
+ chair.handle_rotation()
+ qdel(src)
+ return
+
+ to_chat(user, "You can't modify [target]!")
+
/obj/item/weapon/lighter/zippo/fluff/purple // GodOfOreos: Jason Conrad
name = "purple engraved zippo"
desc = "All craftsspacemanship is of the highest quality. It is encrusted with refined plasma sheets. On the item is an image of a dwarf and the words 'Strike the Earth!' etched onto the side."
@@ -233,6 +263,32 @@
to_chat(target, "You comb your tail with the [src].")
used = 1
+/obj/item/device/fluff/desolate_baton_kit //DesolateG: Michael steampunk_witch
+ name = "stun baton converstion kit"
+ desc = "Some sci-fi looking parts for a stun baton."
+ icon = 'icons/obj/custom_items.dmi'
+ icon_state = "scifikit"
+ w_class = 2
+
+/obj/item/device/fluff/desolate_baton_kit/afterattack(atom/target, mob/user, proximity)
+ if(!proximity || !ishuman(user) || user.incapacitated())
+ return
+
+ if(istype(target, /obj/item/weapon/melee/baton) && !istype(target, /obj/item/weapon/melee/baton/cattleprod))
+ to_chat(user, "You modify the appearance of [target].")
+ var/obj/item/weapon/melee/baton/the_baton = target
+ the_baton.base_icon = "desolate_baton"
+ the_baton.item_state = "desolate_baton"
+ the_baton.icon = 'icons/obj/custom_items.dmi'
+ the_baton.lefthand_file = 'icons/mob/inhands/fluff_lefthand.dmi'
+ the_baton.righthand_file = 'icons/mob/inhands/fluff_righthand.dmi'
+ the_baton.update_icon()
+ user.update_icons()
+ qdel(src)
+ return
+
+ to_chat(user, "You can't modify [target]!")
+
/obj/item/device/fluff/cardgage_helmet_kit //captain cardgage: Richard Ulery
name = "welding helmet modkit"
desc = "Some spraypaint and a stencil, perfect for painting flames onto a welding helmet!"
@@ -242,14 +298,14 @@
throwforce = 0
/obj/item/device/fluff/cardgage_helmet_kit/afterattack(atom/target, mob/user, proximity)
- if(!proximity || !ishuman(user) || user.lying)
+ if(!proximity || !ishuman(user) || user.incapacitated())
return
if(istype(target, /obj/item/clothing/head/welding))
to_chat(user, "You modify the appearance of [target].")
var/obj/item/clothing/head/welding/flamedecal/P = new(get_turf(target))
- transfer_fingerprints_to(P)
+ target.transfer_fingerprints_to(P)
qdel(target)
qdel(src)
return
@@ -267,7 +323,7 @@
throwforce = 0
/obj/item/device/fluff/shadey_plasman_modkit/afterattack(atom/target, mob/user, proximity)
- if(!proximity || !ishuman(user) || user.lying)
+ if(!proximity || !ishuman(user) || user.incapacitated())
return
var/mob/living/carbon/human/H = user
@@ -324,6 +380,7 @@
/obj/item/clothing/glasses/hud/security/sunglasses/fluff/voxxyhud //LP Spartan: Kaskreyarawkta
name = "VoxxyHUD"
desc = "A worn down visor from a vox raider's gear, crudely ripped from its helmet and linked into the security systems of the station. The word 'Kask' is scratched into the side."
+ icon = 'icons/obj/custom_items.dmi'
icon_state = "hud-spartan"
//////////// Hats ////////////
@@ -339,13 +396,12 @@
desc = "Fuzzy, and also stained with blood."
icon = 'icons/obj/custom_items.dmi'
icon_state = "polarbearpelt"
- item_state = "polarbearpelt"
/obj/item/clothing/head/fluff/sparkyninja_beret // Sparkyninja: Neil Wilkinson
name = "royal marines commando beret"
desc = "Dark Green beret with an old insignia on it."
+ icon = 'icons/obj/custom_items.dmi'
icon_state = "sparkyninja_beret"
- item_state = "sparkyninja_beret"
/obj/item/clothing/head/beret/fluff/sigholt //sigholtstarsong: Sigholt Starsong
name = "Lieutenant Starsong's beret"
@@ -376,25 +432,29 @@
/obj/item/clothing/head/beret/fluff/linda //Epic_Charger: Linda Clark
name = "Green beret"
desc = "A beret, an artist's favorite headwear. This one has two holes cut on the edges."
+ icon = 'icons/obj/custom_items.dmi'
icon_state = "linda_beret"
/obj/item/clothing/head/fluff/kaki //Rapidvalj: Kakicharakiti
name = "sleek fancy leader hat"
desc = "A uniquely colored vox leader hat. Has some signs of wear."
+ icon = 'icons/obj/custom_items.dmi'
icon_state = "kakicharakiti"
//////////// Suits ////////////
+/obj/item/clothing/suit/fluff
+ icon = 'icons/obj/custom_items.dmi'
+ actions_types = list()
+ ignore_suitadjust = 1
+ adjust_flavour = null
+ species_fit = null
+ sprite_sheets = null
+
/obj/item/clothing/suit/fluff/dusty_jacket //ComputerlessCitizen: Screech
name = "Dusty Jacket"
desc = "A worn leather jacket. Some burn holes have been patched."
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
- icon = 'icons/obj/custom_items.dmi'
icon_state = "dusty_jacket"
- ignore_suitadjust = 1
- actions_types = list()
- adjust_flavour = null
- species_fit = null
- sprite_sheets = null
/obj/item/clothing/suit/storage/labcoat/fluff/aeneas_rinil //Socialsystem: Lynn Fea
name = "Robotics labcoat"
@@ -419,6 +479,7 @@
/obj/item/clothing/suit/fluff/kluys // Kluys: Cripty Pandaen
name = "Nano Fibre Jacket"
desc = "A Black Suit made out of nanofibre. The newest of cyberpunk fashion using hightech liquid to solid materials."
+ icon = 'icons/obj/custom_items.dmi'
icon_state = "Kluysfluff1"
item_state = "Kluysfluff1"
blood_overlay_type = "coat"
@@ -465,15 +526,29 @@
/obj/item/clothing/suit/hooded/hoodie/fluff/linda // Epic_Charger: Linda Clark
name = "Green Nanotrasen Hoodie"
desc = "A green hoodie with the Nanotrasen logo on the back. It looks weathered."
+ icon = 'icons/obj/custom_items.dmi'
icon_state = "linda_hoodie"
hoodtype = /obj/item/clothing/head/hood/fluff/linda
/obj/item/clothing/head/hood/fluff/linda //Epic_Charger: Linda Clark
icon_state = "greenhood"
+/obj/item/clothing/suit/hooded/fluff/bone //Doru7: Jack Bone
+ name = "skeleton suit"
+ desc = "A spooky full-body suit! This one doesn't glow in the dark."
+ body_parts_covered = HEAD|UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
+ icon = 'icons/obj/custom_items.dmi'
+ icon_state = "skeleton_suit"
+ hoodtype = /obj/item/clothing/head/hood/fluff/skeleton
+
+/obj/item/clothing/head/hood/fluff/skeleton
+ icon = 'icons/obj/custom_items.dmi'
+ icon_state = "skeleton_hood"
+
/obj/item/clothing/suit/armor/shodanscoat // RazekPraxis: SHODAN
name = "SHODAN's Captain's Coat"
desc = "A black coat with gold trim and an old US Chevron printed on the back. Edgy."
+ icon = 'icons/obj/custom_items.dmi'
icon_state = "shodancoat"
//////////// Uniforms ////////////
@@ -494,6 +569,15 @@
item_color = "elishirt"
displays_id = 0
+/obj/item/clothing/under/fluff/jay_turtleneck // Jayfeather: Jay Wingler
+ name = "Mar's Pattern Custom Turtleneck"
+ desc = "It seems to be lightly dusted in orange fuzz, and damp with the smell of anti-freeze. It has a strange symbol in the middle."
+ icon = 'icons/obj/custom_items.dmi'
+ icon_state = "jaywingler"
+ item_state = "jaywingler"
+ item_color = "jaywingler"
+ displays_id = 0
+
/obj/item/clothing/under/psysuit/fluff/isaca_sirius_1 // Xilia: Isaca Sirius
name = "Isaca's suit"
desc = "Black, comfortable and nicely fitting suit. Made not to hinder the wearer in any way. Made of some exotic fabric. And some strange glowing jewel at the waist. Name labels says; Property of Isaca Sirius; The Seeder."
@@ -540,6 +624,9 @@
/obj/item/clothing/under/fluff/aegis //PlagueWalker: A.E.G.I.S.
name = "gilded waistcoat"
desc = "This black, gold-trimmed, rather expensive-looking uniform laced with fine materials appears comfortable despite its stiffness."
+ icon = 'icons/obj/custom_items.dmi'
+ lefthand_file = 'icons/mob/inhands/fluff_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/fluff_righthand.dmi'
icon_state = "aegisuniform"
item_state = "aegisuniform"
item_color = "aegisuniform"
@@ -550,8 +637,17 @@
/obj/item/clothing/mask/bandana/fluff/dar //sasanek12: Dar'Konr
name = "camo bandana"
desc = "It's a worn-out bandana in camo paint"
+ icon = 'icons/obj/custom_items.dmi'
icon_state = "bandcamo"
+/obj/item/clothing/mask/gas/sechailer/fluff/spartan //LP Spartan: Kaskreyarawkta
+ name = "minimal gasmask"
+ desc = "Designed to cover as little of face as possible while still being a functional gasmask."
+ icon = 'icons/obj/custom_items.dmi'
+ icon_state = "spartan_mask"
+ item_state = "spartan_mask"
+ species_restricted = list("Vox")
+
//////////// Shoes ////////////
//////////// Sets ////////////
@@ -614,7 +710,8 @@
icon = 'icons/obj/custom_items.dmi'
icon_state = "chronx_hood"
item_state = "chronx_hood"
- flags = HEADCOVERSEYES | BLOCKHAIR
+ flags = BLOCKHAIR
+ flags_cover = HEADCOVERSEYES
actions_types = list(/datum/action/item_action/toggle)
var/adjusted = 0
@@ -684,4 +781,52 @@
/obj/item/weapon/storage/backpack/fluff/krich_back //lizardzsi: Krichahka
name = "Voxcaster"
desc = "Battered, Sol-made military radio backpack that had its speakers fried from playing Vox opera. The words 'Swift-Talon' are crudely scratched onto its side."
+ icon = 'icons/obj/custom_items.dmi'
icon_state = "voxcaster_fluff"
+
+/obj/item/clothing/head/wizard/fake/fluff/dreamy //phantasmicdream : Dreamy Rockwall
+ name = "strange witch hat"
+ desc = "A shapeshifting witch hat. A strange aura comes from it..."
+ icon = 'icons/obj/custom_items.dmi'
+ icon_state = "classic_witch"
+ item_state = "classic_witch"
+
+/obj/item/clothing/head/wizard/fake/fluff/dreamy/attack_self(mob/user)
+ var/list/options = list()
+ options["Classic"] = "classic_witch"
+ options["Good"] = "good_witch"
+ options["Dark"] = "dark_witch"
+ options["Steampunk"] ="steampunk_witch"
+ options["Healer"] = "healer_witch"
+ options["Cute"] = "cutie_witch"
+ options["Shy"] = "shy_witch"
+ options["Sexy"] ="sexy_witch"
+ options["Bunny"] = "bunny_witch"
+ options["Potions"] = "potions_witch"
+ options["Syndicate"] = "syndie_witch"
+ options["Nanotrasen"] ="nt_witch"
+
+ var/choice = input(user, "To what form do you wish to Shapeshift this hat?", "Shapeshift Hat") as null|anything in options
+
+ if(choice && !user.stat && in_range(user, src))
+ icon_state = options[choice]
+ to_chat(user, "Your strange witch hat has now shapeshifted into it's [choice] form!")
+ return 1
+
+/obj/item/weapon/reagent_containers/food/drinks/bottle/fluff/moonshine //nethiafins : Serhij Zozulia
+ name = "Cloudy Bottle"
+ desc = "The contents of this bottle are vile. You should only drink it when you hit rock bottom."
+ icon = 'icons/obj/custom_items.dmi'
+ icon_state = "questionable_liquid"
+ item_state = "questionable_liquid"
+ amount_per_transfer_from_this = 5
+ list_reagents = list("moonshine" = 100)
+
+/obj/item/weapon/storage/box/fluff/moonshine_kit //nethiafins : Serhij Zozulia
+ name = "Moonshine Serving box"
+
+/obj/item/weapon/storage/box/fluff/moonshine_kit/New()
+ ..()
+ new /obj/item/weapon/reagent_containers/food/drinks/drinkingglass/shotglass(src)
+ new /obj/item/weapon/reagent_containers/food/drinks/drinkingglass/shotglass(src)
+ new /obj/item/weapon/reagent_containers/food/drinks/bottle/fluff/moonshine(src)
diff --git a/code/modules/detective_work/footprints_and_rag.dm b/code/modules/detective_work/footprints_and_rag.dm
index 64ade59adee..cc93863cc95 100644
--- a/code/modules/detective_work/footprints_and_rag.dm
+++ b/code/modules/detective_work/footprints_and_rag.dm
@@ -25,6 +25,7 @@
volume = 5
can_be_placed_into = null
flags = OPENCONTAINER | NOBLUDGEON
+ var/wipespeed = 30
/obj/item/weapon/reagent_containers/glass/rag/attack(atom/target as obj|turf|area, mob/user as mob , flag)
if(ismob(target) && target.reagents && reagents.total_volume)
@@ -39,7 +40,7 @@
if(!proximity) return
if(istype(A) && src in user)
user.visible_message("[user] starts to wipe down [A] with [src]!")
- if(do_after(user,30, target = A))
+ if(do_after(user, wipespeed, target = A))
user.visible_message("[user] finishes wiping off the [A]!")
A.clean_blood()
return
diff --git a/code/modules/economy/ATM.dm b/code/modules/economy/ATM.dm
index 0ff4af7b405..40f258b0c2a 100644
--- a/code/modules/economy/ATM.dm
+++ b/code/modules/economy/ATM.dm
@@ -46,11 +46,11 @@ log transactions
if(stat & NOPOWER)
return
- if(linked_db && ( (linked_db.stat & NOPOWER) || !linked_db.activated ) )
+ if(linked_db && ((linked_db.stat & NOPOWER) || !linked_db.activated))
linked_db = null
authenticated_account = null
- src.visible_message("\red [bicon(src)] [src] buzzes rudely, \"Connection to remote database lost.\"")
- updateDialog()
+ visible_message("[bicon(src)][src] buzzes rudely, \"Connection to remote database lost.\"")
+ nanomanager.update_uis(src)
if(ticks_left_timeout > 0)
ticks_left_timeout--
@@ -63,158 +63,101 @@ log transactions
if(authenticated_account)
var/turf/T = get_turf(src)
- if(istype(T) && locate(/obj/item/weapon/spacecash) in T)
- var/list/cash_found = list()
- for(var/obj/item/weapon/spacecash/S in T)
- cash_found+=S
- if(cash_found.len>0)
- if(prob(50))
- playsound(loc, 'sound/items/polaroid1.ogg', 50, 1)
- else
- playsound(loc, 'sound/items/polaroid2.ogg', 50, 1)
- var/amount = count_cash(cash_found)
- for(var/obj/item/weapon/spacecash/S in cash_found)
- qdel(S)
- authenticated_account.charge(-amount,null,"Credit deposit",terminal_id=machine_id,dest_name = "Terminal")
+ if(istype(T) && locate(/obj/item/stack/spacecash) in T)
+ var/cash_amount = 0
+ for(var/obj/item/stack/spacecash/S in T)
+ cash_amount += S.amount
+ if(cash_amount)
+ playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 50, 1)
+ for(var/obj/item/stack/spacecash/S in T)
+ S.use(S.amount)
+ authenticated_account.charge(-cash_amount, null, "Credit deposit", terminal_id = machine_id, dest_name = "Terminal")
/obj/machinery/atm/proc/reconnect_database()
- for(var/obj/machinery/computer/account_database/DB in world) //Hotfix until someone finds out why it isn't in 'machines'
- if( DB.z == src.z && !(DB.stat & NOPOWER) && DB.activated )
+ for(var/obj/machinery/computer/account_database/DB in machines)
+ if(DB.z == z && !(DB.stat & NOPOWER) && DB.activated)
linked_db = DB
break
-/obj/machinery/atm/attackby(obj/item/I as obj, mob/user as mob, params)
+/obj/machinery/atm/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/card))
- var/obj/item/weapon/card/id/idcard = I
if(!held_card)
- usr.drop_item()
- idcard.loc = src
- held_card = idcard
+ user.drop_item()
+ I.forceMove(src)
+ held_card = I
if(authenticated_account && held_card.associated_account_number != authenticated_account.account_number)
authenticated_account = null
+ nanomanager.update_uis(src)
else if(authenticated_account)
- if(istype(I,/obj/item/weapon/spacecash))
+ if(istype(I, /obj/item/stack/spacecash))
//consume the money
- var/obj/item/weapon/spacecash/C = I
- authenticated_account.money += C.get_total()
- if(prob(50))
- playsound(loc, 'sound/items/polaroid1.ogg', 50, 1)
- else
- playsound(loc, 'sound/items/polaroid2.ogg', 50, 1)
+ var/obj/item/stack/spacecash/C = I
+ authenticated_account.money += C.amount
+ playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 50, 1)
//create a transaction log entry
var/datum/transaction/T = new()
T.target_name = authenticated_account.owner_name
T.purpose = "Credit deposit"
- T.amount = C.get_total()
+ T.amount = C.amount
T.source_terminal = machine_id
T.date = current_date_string
T.time = worldtime2text()
authenticated_account.transaction_log.Add(T)
to_chat(user, "You insert [C] into [src].")
- src.attack_hand(user)
- qdel(I)
+ nanomanager.update_uis(src)
+ C.use(C.amount)
else
..()
-/obj/machinery/atm/attack_hand(mob/user as mob)
- if(istype(user, /mob/living/silicon))
- to_chat(user, "\red Artificial unit recognized. Artificial units do not currently receive monetary compensation, as per Nanotrasen regulation #1005.")
+/obj/machinery/atm/attack_hand(mob/user)
+ if(..())
+ return 1
+ if(issilicon(user))
+ to_chat(user, "Artificial unit recognized. Artificial units do not currently receive monetary compensation, as per Nanotrasen regulation #1005.")
return
- if(get_dist(src,user) <= 1)
- add_fingerprint(user)
+ ui_interact(user)
+
+/obj/machinery/atm/attack_ghost(mob/user)
+ ui_interact(user)
- //js replicated from obj/machinery/computer/card
- var/dat = {"
Nanotrasen Automatic Teller Machine
- For all your monetary needs!
- This terminal is [machine_id]. Report this code when contacting Nanotrasen IT Support
- Card: [held_card ? held_card.name : "------"]
"}
+/obj/machinery/atm/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ user.set_machine(src)
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open)
+ if (!ui)
+ ui = new(user, src, ui_key, "atm.tmpl", name, 550, 650)
+ ui.open()
- if(ticks_left_locked_down > 0)
- dat += "Maximum number of pin attempts exceeded! Access to this ATM has been temporarily disabled."
- else if(authenticated_account)
- switch(view_screen)
- if(CHANGE_SECURITY_LEVEL)
- dat += "Select a new security level for this account: "
- var/text = "Zero - Either the account number or card is required to access this account. EFTPOS transactions will require a card and ask for a pin, but not verify the pin is correct."
- if(authenticated_account.security_level != 0)
- text = "[text]"
- dat += "[text]"
- text = "One - An account number and pin must be manually entered to access this account and process transactions."
- if(authenticated_account.security_level != 1)
- text = "[text]"
- dat += "[text]"
- text = "Two - In addition to account number and pin, a card is required to access this account and process transactions."
- if(authenticated_account.security_level != 2)
- text = "[text]"
- dat += {"[text]
- Back"}
- if(VIEW_TRANSACTION_LOGS)
- dat += {"Transaction logs
- Back
-
-
-
Date
-
Time
-
Target
-
Purpose
-
Value
-
Source terminal ID
-
"}
- for(var/datum/transaction/T in authenticated_account.transaction_log)
- dat += {"
-
[T.date]
-
[T.time]
-
[T.target_name]
-
[T.purpose]
-
$[T.amount]
-
[T.source_terminal]
-
"}
- dat += "
"
- if(TRANSFER_FUNDS)
- dat += {"Account balance: $[authenticated_account.money]
- Back
- Transaction purpose: [transaction_purpose]
- Value: $[transaction_amount]
- Linked account: [linked_account ? linked_account.owner_name : "None"]"}
- // END AUTOFIX
- if(transaction_paid)
- dat += "This transaction has been processed successfully."
- else
-
- // AUTOFIXED BY fix_string_idiocy.py
- // C:\Users\Rob\Documents\Projects\vgstation13\code\WorkInProgress\Cael_Aislinn\Economy\EFTPOS.dm:67: dat += "Swipe your card below the line to finish this transaction."
- dat += {"Swipe your card below the line to finish this transaction.
- \[------\]"}
- // END AUTOFIX
- else
-
- // AUTOFIXED BY fix_string_idiocy.py
- // C:\Users\Rob\Documents\Projects\vgstation13\code\WorkInProgress\Cael_Aislinn\Economy\EFTPOS.dm:70: dat += "Lock in new transaction
Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.
")
+ playsound_local(null, 'sound/AI/aimalf.ogg')
if("hudscrew")
//Screwy HUD
-// to_chat(src, "Screwy HUD")
- hal_screwyhud = pick(1,2,3,3,4,4)
- spawn(rand(100,250))
- hal_screwyhud = 0
+ hal_screwyhud = pick(SCREWYHUD_NONE, SCREWYHUD_CRIT, SCREWYHUD_DEAD, SCREWYHUD_HEALTHY)
+ sleep(rand(100,250))
+ hal_screwyhud = SCREWYHUD_NONE
+ if("fake_alert")
+ var/alert_type = pick("oxy","not_enough_tox","not_enough_co2","too_much_oxy","too_much_co2","tox_in_air","newlaw","nutrition","charge","weightless","fire","locked","hacked","temp","pressure")
+ if(specific)
+ alert_type = specific
+ switch(alert_type)
+ if("oxy")
+ throw_alert("oxy", /obj/screen/alert/oxy, override = TRUE)
+ if("not_enough_tox")
+ throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox, override = TRUE)
+ if("not_enough_co2")
+ throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2, override = TRUE)
+ if("too_much_oxy")
+ throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy, override = TRUE)
+ if("too_much_co2")
+ throw_alert("too_much_co2", /obj/screen/alert/too_much_co2, override = TRUE)
+ if("tox_in_air")
+ throw_alert("tox_in_air", /obj/screen/alert/tox_in_air, override = TRUE)
+ if("nutrition")
+ if(prob(50))
+ throw_alert("nutrition", /obj/screen/alert/fat, override = TRUE)
+ else
+ throw_alert("nutrition", /obj/screen/alert/starving, override = TRUE)
+ if("weightless")
+ throw_alert("weightless", /obj/screen/alert/weightless, override = TRUE)
+ if("fire")
+ throw_alert("fire", /obj/screen/alert/fire, override = TRUE)
+ if("temp")
+ if(prob(50))
+ throw_alert("temp", /obj/screen/alert/hot, 3, override = TRUE)
+ else
+ throw_alert("temp", /obj/screen/alert/cold, 3, override = TRUE)
+ if("pressure")
+ if(prob(50))
+ throw_alert("pressure", /obj/screen/alert/highpressure, 2, override = TRUE)
+ else
+ throw_alert("pressure", /obj/screen/alert/lowpressure, 2, override = TRUE)
+ //BEEP BOOP I AM A ROBOT
+ if("newlaw")
+ throw_alert("newlaw", /obj/screen/alert/newlaw, override = TRUE)
+ if("locked")
+ throw_alert("locked", /obj/screen/alert/locked, override = TRUE)
+ if("hacked")
+ throw_alert("hacked", /obj/screen/alert/hacked, override = TRUE)
+ if("charge")
+ throw_alert("charge",/obj/screen/alert/emptycell, override = TRUE)
+ sleep(rand(100,200))
+ clear_alert(alert_type, clear_override = TRUE)
if("items")
//Strange items
// to_chat(src, "Traitor Items")
if(!halitem)
halitem = new
var/list/slots_free = list(ui_lhand,ui_rhand)
- if(l_hand) slots_free -= ui_lhand
- if(r_hand) slots_free -= ui_rhand
+ if(l_hand)
+ slots_free -= ui_lhand
+ if(r_hand)
+ slots_free -= ui_rhand
if(istype(src,/mob/living/carbon/human))
var/mob/living/carbon/human/H = src
- if(!H.belt) slots_free += ui_belt
- if(!H.l_store) slots_free += ui_storage1
- if(!H.r_store) slots_free += ui_storage2
+ if(!H.belt)
+ slots_free += ui_belt
+ if(!H.l_store)
+ slots_free += ui_storage1
+ if(!H.r_store)
+ slots_free += ui_storage2
if(slots_free.len)
halitem.screen_loc = pick(slots_free)
halitem.layer = 50
@@ -726,7 +1035,6 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite
qdel(halitem)
if("dangerflash")
//Flashes of danger
-// to_chat(src, "Danger Flash")
if(!halimage)
var/list/possible_points = list()
for(var/turf/simulated/floor/F in view(src,world.view))
@@ -734,31 +1042,38 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite
if(possible_points.len)
var/turf/simulated/floor/target = pick(possible_points)
- switch(rand(1,3))
+ switch(rand(1,4))
if(1)
-// to_chat(src, "Space")
halimage = image('icons/turf/space.dmi',target,"[rand(1,25)]",TURF_LAYER)
if(2)
-// to_chat(src, "Fire")
- halimage = image('icons/effects/fire.dmi',target,"1",TURF_LAYER)
+ halimage = image('icons/turf/floors/lava.dmi',target,"smooth",TURF_LAYER)
if(3)
-// to_chat(src, "C4")
+ halimage = image('icons/turf/floors/Chasms.dmi',target,"smooth",TURF_LAYER)
+ if(4)
halimage = image('icons/obj/assemblies.dmi',target,"plastic-explosive2",OBJ_LAYER+0.01)
- if(client) client.images += halimage
- spawn(rand(10,50)) //Only seen for a brief moment.
- if(client) client.images -= halimage
- halimage = null
+ if(client)
+ client.images += halimage
+ sleep(rand(40,60)) //Only seen for a brief moment.
+ if(client)
+ client.images -= halimage
+ halimage = null
if("death")
- //Fake death
- Sleeping(20)
- hal_crit = 1
- hal_screwyhud = 1
- spawn(rand(50,100))
- SetSleeping(0)
- hal_crit = 0
- hal_screwyhud = 0
+ hal_screwyhud = SCREWYHUD_DEAD
+ SetSleeping(20, no_alert = TRUE)
+ if(prob(50))
+ var/list/dead_people = list()
+ for(var/mob/dead/observer/G in player_list)
+ dead_people += G
+ var/mob/dead/observer/fakemob = pick(dead_people)
+ if(fakemob)
+ sleep(rand(30, 60))
+ to_chat(src, "[fakemob.name](FOLLOW) [pick("complains", "moans", "whines", "laments", "blubbers", "salts")], \"[pick("rip","welcome [name]","you too?","is the AI malf?",\
+ "i[prob(50)?" fucking":""] hate [pick("blood cult", "clock cult", "revenants", "abductors","double agents","viruses","badmins","you")]")]\"")
+ sleep(rand(50,70))
+ hal_screwyhud = SCREWYHUD_NONE
+ SetSleeping(0)
if("husks")
if(!halbody)
var/list/possible_points = list()
@@ -768,17 +1083,19 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite
var/turf/simulated/floor/target = pick(possible_points)
switch(rand(1,4))
if(1)
- var/image/body = image('icons/mob/human.dmi',target,"husk_s",TURF_LAYER)
+ var/image/body = image('icons/mob/human.dmi', target, "husk_s", TURF_LAYER)
var/matrix/M = matrix()
M.Turn(90)
body.transform = M
halbody = body
if(2,3)
- halbody = image('icons/mob/human.dmi',target,"husk_s",TURF_LAYER)
+ halbody = image('icons/mob/human.dmi', target, "husk_s", TURF_LAYER)
if(4)
- halbody = image('icons/mob/alien.dmi',target,"alienother",TURF_LAYER)
+ halbody = image('icons/mob/alien.dmi', target, "alienother", TURF_LAYER)
- if(client) client.images += halbody
- spawn(rand(50,80)) //Only seen for a brief moment.
- if(client) client.images -= halbody
+ if(client)
+ client.images += halbody
+ spawn(rand(30,50)) //Only seen for a brief moment.
+ if(client)
+ client.images -= halbody
halbody = null
diff --git a/code/modules/food_and_drinks/drinks/bottler/bottler.dm b/code/modules/food_and_drinks/drinks/bottler/bottler.dm
index 81974b39c0e..89c55a65f98 100644
--- a/code/modules/food_and_drinks/drinks/bottler/bottler.dm
+++ b/code/modules/food_and_drinks/drinks/bottler/bottler.dm
@@ -41,7 +41,7 @@
/obj/machinery/bottler/attackby(obj/item/O, mob/user, params)
if(iswrench(O)) //This being before the canUnequip check allows borgs to (un)wrench bottlers in case they need move them to fix stuff
- playsound(src, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(src, O.usesound, 50, 1)
if(anchored)
anchored = 0
to_chat(user, "[src] can now be moved.")
@@ -179,7 +179,7 @@
con_type = "glass bottle"
max_define = MAX_GLASS
mat_ratio = RATIO_GLASS
- else if(istype(S, /obj/item/stack/sheet/mineral/plastic))
+ else if(istype(S, /obj/item/stack/sheet/plastic))
con_type = "plastic bottle"
max_define = MAX_PLAST
mat_ratio = RATIO_PLAST
diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm
index ee1d2821fa1..23ae568af9b 100644
--- a/code/modules/food_and_drinks/drinks/drinks.dm
+++ b/code/modules/food_and_drinks/drinks/drinks.dm
@@ -41,6 +41,17 @@
return 1
return 0
+/obj/item/weapon/reagent_containers/food/drinks/MouseDrop(atom/over_object) //CHUG! CHUG! CHUG!
+ var/mob/living/carbon/chugger = over_object
+ if(istype(chugger) && loc == chugger && src == chugger.get_active_hand() && reagents.total_volume)
+ chugger.visible_message("[chugger] raises the [src] to their mouth and starts [pick("chugging","gulping")] it down like [pick("a savage","a mad beast","it's going out of style","there's no tomorrow")]!", "You start chugging \the [src].", "You hear what sounds like gulping.")
+ while(do_mob(chugger, chugger, 40)) //Between the default time for do_mob and the time it takes for a vampire to suck blood.
+ chugger.eat(src, chugger, 25) //Half of a glass, quarter of a bottle.
+ if(!reagents.total_volume) //Finish in style.
+ chugger.emote("gasp")
+ chugger.visible_message("[chugger] [pick("finishes","downs","polishes off","slams")] the entire [src], what a [pick("savage","monster","champ","beast")]!", "You finish off the [src]![prob(50) ? " Maybe that wasn't such a good idea..." : ""]", "You hear a gasp and a clink.")
+ break
+
/obj/item/weapon/reagent_containers/food/drinks/afterattack(obj/target, mob/user, proximity)
if(!proximity) return
diff --git a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm
index 0412c93626b..4188afe209a 100644
--- a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm
+++ b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm
@@ -37,11 +37,17 @@
extinguish()
/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/on_reagent_change()
+ overlays.Cut()
if(reagents.reagent_list.len)
var/datum/reagent/R = reagents.get_master_reagent()
- icon_state = R.drink_icon
name = R.drink_name
desc = R.drink_desc
+ if(R.drink_icon)
+ icon_state = R.drink_icon
+ else
+ var/image/I = image(icon, "glassoverlay")
+ I.color = mix_color_from_reagents(reagents.reagent_list)
+ overlays += I
else
icon_state = "glass_empty"
name = "glass"
@@ -56,4 +62,7 @@
list_reagents = list("cola" = 50)
/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/devilskiss
- list_reagents = list("devilskiss" = 50)
\ No newline at end of file
+ list_reagents = list("devilskiss" = 50)
+
+/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/alliescocktail
+ list_reagents = list("alliescocktail" = 50)
\ No newline at end of file
diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm
index add4e7c474f..3a079e99da4 100644
--- a/code/modules/food_and_drinks/food/snacks.dm
+++ b/code/modules/food_and_drinks/food/snacks.dm
@@ -717,6 +717,14 @@
bitesize = 3
list_reagents = list("nutriment" = 6, "vitamin" = 1)
+/obj/item/weapon/reagent_containers/food/snacks/baseballburger
+ name = "home run baseball burger"
+ desc = "It's still warm. The steam coming off of it looks like baseball."
+ icon_state = "baseball"
+ filling_color = "#CD853F"
+ bitesize = 3
+ list_reagents = list("nutriment" = 6, "vitamin" = 1)
+
/obj/item/weapon/reagent_containers/food/snacks/omelette
name = "Omelette Du Fromage"
desc = "That's all you can say!"
@@ -1210,28 +1218,19 @@
var/monkey_type = "Monkey"
list_reagents = list("nutriment" = 2)
-/obj/item/weapon/reagent_containers/food/snacks/monkeycube/afterattack(obj/O, mob/user, proximity)
- if(!proximity)
- return
- if(istype(O, /obj/structure/sink))
- to_chat(user, "You place [src] under a stream of water...")
- user.drop_item()
- forceMove(get_turf(O))
- return Expand()
- ..()
-
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/water_act(volume, temperature)
if(volume >= 5)
return Expand()
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wash(mob/user, atom/source)
- if(do_after(user, 40, target = source))
- return 1
+ user.drop_item()
+ forceMove(get_turf(source))
+ return 1
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/proc/Expand()
if(isnull(gcDestroyed))
visible_message("[src] expands!")
- new/mob/living/carbon/human(get_turf(src),monkey_type)
+ new/mob/living/carbon/human(get_turf(src), monkey_type)
qdel(src)
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/farwacube
diff --git a/code/modules/food_and_drinks/kitchen_machinery/cooker.dm b/code/modules/food_and_drinks/kitchen_machinery/cooker.dm
index 381525a13ae..1c8db0d9b20 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/cooker.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/cooker.dm
@@ -41,6 +41,8 @@
return 0
if(istype(check, /obj/item/weapon/reagent_containers/food/snacks))
return 1
+ if(istype(check, /obj/item/weapon/grab))
+ return special_attack(check, user)
to_chat(user, "You can only process food!")
return 0
@@ -144,6 +146,9 @@
turnoff(I)
//qdel(I)
+/obj/machinery/cooker/proc/special_attack(obj/item/weapon/grab/G, mob/user)
+ return 0
+
// MAKE SURE TO OVERRIDE THESE ON THE MACHINE IF IT HAS SPECIAL FOOD INTERACTIONS!
// FAILURE TO OVERRIDE WILL RESULT IN FAILURE TO PROPERLY HANDLE SPECIAL INTERACTIONS! --FalseIncarnate
/obj/machinery/cooker/proc/checkSpecials(obj/item/I)
diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
index d9b98c82724..1781479ec6c 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
@@ -43,6 +43,28 @@
var/obj/item/weapon/reagent_containers/food/snacks/deepfryholder/type = new(get_turf(src))
return type
+/obj/machinery/cooker/deepfryer/special_attack(obj/item/weapon/grab/G, mob/user)
+ if(ishuman(G.affecting))
+ if(G.state < GRAB_AGGRESSIVE)
+ to_chat(user, "You need a better grip to do that!")
+ return 0
+ var/mob/living/carbon/human/C = G.affecting
+ var/obj/item/organ/external/head/head = C.get_organ("head")
+ if(!head)
+ to_chat(user, "This person doesn't have a head!")
+ return 0
+ C.visible_message("[user] dunks [C]'s face into [src]!", \
+ "[user] dunks your face into [src]!")
+ C.emote("scream")
+ user.changeNext_move(CLICK_CD_MELEE)
+ C.apply_damage(25, BURN, "head") //25 fire damage and disfigurement because your face was just deep fried!
+ head.disfigure("burn")
+ add_logs(user, G.affecting, "deep-fried", addition="'s face")
+ qdel(G) //Removes the grip so the person MIGHT have a small chance to run the fuck away and to prevent rapid dunks.
+ return 1
+ return 0
+
+
/obj/machinery/cooker/deepfryer/checkSpecials(obj/item/I)
if(!I)
return 0
@@ -76,7 +98,7 @@
output = /obj/item/weapon/reagent_containers/food/snacks/fried_shrimp
/datum/deepfryer_special/banana
- input = "banana"
+ input = /obj/item/weapon/reagent_containers/food/snacks/grown/banana
output = /obj/item/weapon/reagent_containers/food/snacks/friedbanana
/datum/deepfryer_special/potato_chips
@@ -84,7 +106,7 @@
output = /obj/item/weapon/reagent_containers/food/snacks/chips
/datum/deepfryer_special/corn_chips
- input = "corn"
+ input = /obj/item/weapon/reagent_containers/food/snacks/grown/corn
output = /obj/item/weapon/reagent_containers/food/snacks/cornchips
/datum/deepfryer_special/fried_tofu
@@ -93,4 +115,12 @@
/datum/deepfryer_special/chimichanga
input = /obj/item/weapon/reagent_containers/food/snacks/burrito
- output = /obj/item/weapon/reagent_containers/food/snacks/chimichanga
\ No newline at end of file
+ output = /obj/item/weapon/reagent_containers/food/snacks/chimichanga
+
+/datum/deepfryer_special/fries
+ input = /obj/item/weapon/reagent_containers/food/snacks/grown/potato/wedges
+ output = /obj/item/weapon/reagent_containers/food/snacks/fries
+
+/datum/deepfryer_special/carrotfries
+ input = /obj/item/weapon/reagent_containers/food/snacks/grown/carrot/wedges
+ output = /obj/item/weapon/reagent_containers/food/snacks/carrotfries
\ No newline at end of file
diff --git a/code/modules/food_and_drinks/kitchen_machinery/grill_new.dm b/code/modules/food_and_drinks/kitchen_machinery/grill_new.dm
index 8b9ac0cd27c..d63971dcc30 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/grill_new.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/grill_new.dm
@@ -43,3 +43,19 @@
for(var/obj/item/weapon/stock_parts/micro_laser/M in component_parts)
E += M.rating
efficiency = round((E/2), 1) // There's 2 lasers, so halve the effect on the efficiency to keep it balanced
+
+/obj/machinery/kitchen_machine/grill/special_attack(obj/item/weapon/grab/G, mob/user)
+ if(ishuman(G.affecting))
+ if(G.state < GRAB_AGGRESSIVE)
+ to_chat(user, "You need a better grip to do that!")
+ return 0
+ var/mob/living/carbon/human/C = G.affecting
+ C.visible_message("[user] forces [C] onto [src], searing [C]'s body!", \
+ "[user] forces you onto [src]! It burns!")
+ C.emote("scream")
+ user.changeNext_move(CLICK_CD_MELEE)
+ C.adjustFireLoss(30)
+ add_logs(user, G.affecting, "burned", src)
+ qdel(G) //Removes the grip to prevent rapid sears and give you a chance to run
+ return 1
+ return 0
\ No newline at end of file
diff --git a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat_2.dm b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat_2.dm
index 19da4fb85ac..a6401446767 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat_2.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat_2.dm
@@ -179,7 +179,7 @@ var/list/ingredients_source = list(
return
if(href_list["dispense"])
dispense_flavour = text2num(href_list["dispense"])
- visible_message("\blue[usr] sets [src] to dispense [get_icecream_flavour_string(dispense_flavour)] flavoured icecream.")
+ visible_message("[usr] sets [src] to dispense [get_icecream_flavour_string(dispense_flavour)] flavoured icecream.")
if(href_list["cone"])
var/dispense_cone = text2num(href_list["cone"])
diff --git a/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm b/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm
index baf5e8e98ee..e09198cb4e9 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm
@@ -65,7 +65,7 @@
if(exchange_parts(user, O))
return
if(!broken && istype(O, /obj/item/weapon/wrench))
- playsound(src, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(src, O.usesound, 50, 1)
if(anchored)
anchored = 0
to_chat(user, "\The [src] can now be moved.")
@@ -83,7 +83,7 @@
"[user] starts to fix part of \the [src].", \
"You start to fix part of \the [src]." \
)
- if(do_after(user,20, target = src))
+ if(do_after(user, 20 * O.toolspeed, target = src))
user.visible_message( \
"[user] fixes part of \the [src].", \
"You have fixed part of \the [src]." \
@@ -94,7 +94,7 @@
"[user] starts to fix part of \the [src].", \
"You start to fix part of \the [src]." \
)
- if(do_after(user,20, target = src))
+ if(do_after(user, 20 * O.toolspeed, target = src))
user.visible_message( \
"[user] fixes \the [src].", \
"You have fixed \the [src]." \
@@ -112,7 +112,7 @@
"[user] starts to clean \the [src].", \
"You start to clean \the [src]." \
)
- if(do_after(user,20, target = src))
+ if(do_after(user, 20 * O.toolspeed, target = src))
user.visible_message( \
"[user] has cleaned \the [src].", \
"You have cleaned \the [src]." \
@@ -155,9 +155,7 @@
return 1
//G.reagents.trans_to(src,G.amount_per_transfer_from_this)
else if(istype(O,/obj/item/weapon/grab))
- var/obj/item/weapon/grab/G = O
- to_chat(user, "This is ridiculous. You can not fit \the [G.affecting] in this [src].")
- return 1
+ return special_attack(O, user)
else
to_chat(user, "You have no idea what you can cook with this [O].")
return 1
@@ -170,6 +168,10 @@
user.set_machine(src)
interact(user)
+/obj/machinery/kitchen_machine/proc/special_attack(obj/item/weapon/grab/G, mob/user)
+ to_chat(user, "This is ridiculous. You can not fit [G.affecting] in this [src].")
+ return 0
+
/********************
* Machine Menu *
********************/
diff --git a/code/modules/food_and_drinks/kitchen_machinery/oven_new.dm b/code/modules/food_and_drinks/kitchen_machinery/oven_new.dm
index c709fdf0b5e..bd850288bc4 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/oven_new.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/oven_new.dm
@@ -43,3 +43,25 @@
for(var/obj/item/weapon/stock_parts/micro_laser/M in component_parts)
E += M.rating
efficiency = round((E/2), 1) // There's 2 lasers, so halve the effect on the efficiency to keep it balanced
+
+/obj/machinery/kitchen_machine/oven/special_attack(obj/item/weapon/grab/G, mob/user)
+ if(ishuman(G.affecting))
+ if(G.state < GRAB_AGGRESSIVE)
+ to_chat(user, "You need a better grip to do that!")
+ return 0
+ var/mob/living/carbon/human/C = G.affecting
+ var/obj/item/organ/external/head/head = C.get_organ("head")
+ if(!head)
+ to_chat(user, "This person doesn't have a head!")
+ return 0
+ C.visible_message("[user] bashes [C]'s head in [src]'s door!", \
+ "[user] bashes your head in [src]'s door! It feels rather hot in the oven!")
+ C.emote("scream")
+ user.changeNext_move(CLICK_CD_MELEE)
+ C.apply_damage(5, BURN, "head") //5 fire damage, 15 brute damage, and weakening because your head was just in a hot oven with the door bashing into your neck!
+ C.apply_damage(15, BRUTE, "head")
+ C.Weaken(2)
+ add_logs(user, G.affecting, "smashed", addition="'s head on [src]")
+ qdel(G) //Removes the grip to prevent rapid bashes. With the weaken, you PROBABLY can't run unless they are slow to grab you again...
+ return 1
+ return 0
diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm
index df9d1dddf4d..38edb2e2174 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm
@@ -71,10 +71,6 @@
input = /obj/item/weapon/reagent_containers/food/snacks/meat
output = /obj/item/weapon/reagent_containers/food/snacks/meatball
-/datum/food_processor_process/potatowedges
- input = /obj/item/weapon/reagent_containers/food/snacks/grown/potato/wedges
- output = /obj/item/weapon/reagent_containers/food/snacks/fries
-
/datum/food_processor_process/sweetpotato
input = /obj/item/weapon/reagent_containers/food/snacks/grown/potato/sweet
output = /obj/item/weapon/reagent_containers/food/snacks/yakiimo
@@ -83,10 +79,6 @@
input = /obj/item/weapon/reagent_containers/food/snacks/grown/potato
output = /obj/item/weapon/reagent_containers/food/snacks/tatortot
-/datum/food_processor_process/carrot
- input = /obj/item/weapon/reagent_containers/food/snacks/grown/carrot
- output = /obj/item/weapon/reagent_containers/food/snacks/carrotfries
-
/datum/food_processor_process/soybeans
input = /obj/item/weapon/reagent_containers/food/snacks/grown/soybeans
output = /obj/item/weapon/reagent_containers/food/snacks/soydope
@@ -99,6 +91,10 @@
input = /obj/item/weapon/reagent_containers/food/snacks/grown/parsnip
output = /obj/item/weapon/reagent_containers/food/snacks/roastparsnip
+/datum/food_processor_process/carrot
+ input = /obj/item/weapon/reagent_containers/food/snacks/grown/carrot
+ output = /obj/item/weapon/reagent_containers/food/snacks/grown/carrot/wedges
+
/////////////////////////
///END OBJECT RECIPIES///
/////////////////////////
diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
index 936b9e30827..6b8d9cebd26 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
@@ -50,8 +50,7 @@
wires = new/datum/wires/smartfridge(src)
/obj/machinery/smartfridge/Destroy()
- qdel(wires)
- wires = null
+ QDEL_NULL(wires)
for(var/atom/movable/A in contents)
A.forceMove(loc)
return ..()
diff --git a/code/modules/food_and_drinks/recipes/recipes_microwave.dm b/code/modules/food_and_drinks/recipes/recipes_microwave.dm
index 962aa5e92a4..2fe0ccc28dd 100644
--- a/code/modules/food_and_drinks/recipes/recipes_microwave.dm
+++ b/code/modules/food_and_drinks/recipes/recipes_microwave.dm
@@ -126,6 +126,13 @@
)
result = /obj/item/weapon/reagent_containers/food/snacks/mimeburger
+/datum/recipe/microwave/baseballburger
+ items = list(
+ /obj/item/weapon/reagent_containers/food/snacks/bun,
+ /obj/item/weapon/melee/baseball_bat
+ )
+ result = /obj/item/weapon/reagent_containers/food/snacks/baseballburger
+
/datum/recipe/microwave/hotdog
items = list(
/obj/item/weapon/reagent_containers/food/snacks/bun,
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_table.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_table.dm
index f7eb2fa4a68..54203f92d12 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_table.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_table.dm
@@ -54,6 +54,15 @@
result = /obj/item/weapon/reagent_containers/food/snacks/jellyburger/cherry
category = CAT_FOOD
+/datum/crafting_recipe/baseballburger
+ name = "Home run baseball burger"
+ reqs = list(
+ /obj/item/weapon/melee/baseball_bat = 1,
+ /obj/item/weapon/reagent_containers/food/snacks/bun = 1,
+ )
+ result = /obj/item/weapon/reagent_containers/food/snacks/baseballburger
+ category = CAT_FOOD
+
/datum/crafting_recipe/notasandwich
name = "not-a-sandwich"
reqs = list(
diff --git a/code/modules/garbage_collection/garbage_collector.dm b/code/modules/garbage_collection/garbage_collector.dm
index e2204788016..f0ca2d64474 100644
--- a/code/modules/garbage_collection/garbage_collector.dm
+++ b/code/modules/garbage_collection/garbage_collector.dm
@@ -7,8 +7,12 @@
#define GC_FORCE_DEL_PER_TICK 30
//#define GC_DEBUG
-// A list of types that were queued in the GC, and had to be soft deleted; used in testing
-var/list/gc_hard_del_types = list()
+var/list/didntgc = list() // list of all types that have failed to GC associated with the number of times that's happened.
+ // the types are stored as strings
+var/list/sleptDestroy = list() //Same as above but these are paths that slept during their Destroy call
+
+var/list/noqdelhint = list() // list of all types that do not return a QDEL_HINT
+
var/global/datum/controller/process/garbage_collector/garbageCollector
// The time a datum was destroyed by the GC, or null if it hasn't been
@@ -82,7 +86,7 @@ var/global/datum/controller/process/garbage_collector/garbageCollector
#undef GC_COLLECTIONS_PER_TICK
/datum/controller/process/garbage_collector/proc/hardDel(var/datum/D)
- gc_hard_del_types |= D.type
+ didntgc["[D.type]"]++
D.hard_deleted = 1
if(!D.gcDestroyed)
spawn(-1)
@@ -126,6 +130,7 @@ var/global/datum/controller/process/garbage_collector/garbageCollector
return
if(!isnull(D.gcDestroyed) && D.gcDestroyed != world.time)
gcwarning("Sleep detected in Destroy() call of [D.type]")
+ sleptDestroy["[D.type]"]++
D.gcDestroyed = world.time
switch(hint)
@@ -155,7 +160,9 @@ var/global/datum/controller/process/garbage_collector/garbageCollector
#endif
garbageCollector.addTrash(D)
else
-// to_chat(world, "WARNING GC DID NOT GET A RETURN VALUE FOR [D], [D.type]!")
+ if(!noqdelhint["[D.type]"])
+ noqdelhint["[D.type]"] = "[D.type]"
+ gcwarning("WARNING: [D.type] is not returning a qdel hint. It is being placed in the queue. Further instances of this type will also be queued.")
garbageCollector.addTrash(D)
diff --git a/code/modules/garbage_collection/gc_testing.dm b/code/modules/garbage_collection/gc_testing.dm
index b1b413a0398..934a93adc21 100644
--- a/code/modules/garbage_collection/gc_testing.dm
+++ b/code/modules/garbage_collection/gc_testing.dm
@@ -11,23 +11,29 @@
garbageCollector.del_everything = !garbageCollector.del_everything
// to_chat(world, "GC: qdel turned [garbageCollector.del_everything ? "off" : "on"].")
log_admin("[key_name(usr)] turned qdel [garbageCollector.del_everything ? "off" : "on"].")
- message_admins("\blue [key_name_admin(usr)] turned qdel [garbageCollector.del_everything ? "off" : "on"].", 1)
+ message_admins("[key_name_admin(usr)] turned qdel [garbageCollector.del_everything ? "off" : "on"].", 1)
-/client/proc/gc_dump_hdl()
- set name = "(GC) Hard Del List"
- set desc = "List types that are hard del()'d by the GC."
+/client/proc/cmd_display_del_log()
set category = "Debug"
+ set name = "(GC) Display del() Log"
+ set desc = "Displays a list of things that have failed to GC this round"
if(!check_rights(R_DEBUG))
return
- if(!gc_hard_del_types || !gc_hard_del_types.len)
- to_chat(usr, "No hard del()'d types found.")
- return
+ var/dat = "List of things that failed to GC this round
"
+ for(var/path in didntgc)
+ dat += "[path] - [didntgc[path]] times "
- to_chat(usr, "Types hard del()'d by the GC:")
- for(var/A in gc_hard_del_types)
- to_chat(usr, "[A]")
+ dat += "List of paths that did not return a qdel hint in Destroy()
"
+ for(var/path in noqdelhint)
+ dat += "[path] "
+
+ dat += "List of paths that slept in Destroy()
"
+ for(var/path in sleptDestroy)
+ dat += "[path] "
+
+ usr << browse(dat, "window=dellog")
#ifdef TESTING
/client/var/running_find_references
diff --git a/code/modules/holiday/holiday.dm b/code/modules/holiday/holiday.dm
index db82a5227e6..85162a75c2d 100644
--- a/code/modules/holiday/holiday.dm
+++ b/code/modules/holiday/holiday.dm
@@ -354,5 +354,5 @@
//update our hub status
world.update_status()
- message_admins("\blue ADMIN: Event: [key_name(src)] force-set Holiday to \"[H]\"")
+ message_admins("ADMIN: Event: [key_name_admin(src)] force-set Holiday to \"[H]\"")
log_admin("[key_name(src)] force-set Holiday to \"[H]\"")
\ No newline at end of file
diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm
index ce393c16e15..deac3c6660d 100644
--- a/code/modules/hydroponics/biogenerator.dm
+++ b/code/modules/hydroponics/biogenerator.dm
@@ -31,9 +31,8 @@
RefreshParts()
/obj/machinery/biogenerator/Destroy()
- if(beaker)
- qdel(beaker)
- beaker = null
+ QDEL_NULL(beaker)
+ QDEL_NULL(files)
return ..()
/obj/machinery/biogenerator/ex_act(severity)
@@ -208,7 +207,7 @@
/obj/machinery/biogenerator/attack_hand(mob/user)
interact(user)
-
+
/obj/machinery/biogenerator/attack_ghost(mob/user)
interact(user)
diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm
index 95e195caaf7..ebe74316ed4 100644
--- a/code/modules/hydroponics/gene_modder.dm
+++ b/code/modules/hydroponics/gene_modder.dm
@@ -24,13 +24,22 @@
/obj/machinery/plantgenes/New()
..()
component_parts = list()
- component_parts += new /obj/item/weapon/circuitboard/plantgenes(src)
- component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
- component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
- component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
- component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
+ component_parts += new /obj/item/weapon/circuitboard/plantgenes(null)
+ component_parts += new /obj/item/weapon/stock_parts/console_screen(null)
+ component_parts += new /obj/item/weapon/stock_parts/scanning_module(null)
+ component_parts += new /obj/item/weapon/stock_parts/micro_laser(null)
+ component_parts += new /obj/item/weapon/stock_parts/manipulator(null)
RefreshParts()
+/obj/machinery/plantgenes/Destroy()
+ core_genes.Cut()
+ reagent_genes.Cut()
+ trait_genes.Cut()
+ target = null
+ QDEL_NULL(seed)
+ QDEL_NULL(disk)
+ return ..()
+
/obj/machinery/plantgenes/RefreshParts()
rating = 0
for(var/I in component_parts)
@@ -90,7 +99,7 @@
if(..())
return
interact(user)
-
+
/obj/machinery/plantgenes/attack_ghost(mob/user)
interact(user)
@@ -282,9 +291,9 @@
repaint_seed()
if("extract")
if(disk && !disk.read_only)
- disk.gene = G
- if(istype(G, /datum/plant_gene/core/potency))
- var/datum/plant_gene/core/gene = G
+ disk.gene = G.Copy()
+ if(istype(disk.gene, /datum/plant_gene/core/potency))
+ var/datum/plant_gene/core/gene = disk.gene
gene.value = min(gene.value, max_extract_pot)
disk.update_name()
qdel(seed)
@@ -370,6 +379,10 @@
pixel_x = rand(-5, 5)
pixel_y = rand(-5, 5)
+/obj/item/weapon/disk/plantgene/Destroy()
+ QDEL_NULL(gene)
+ return ..()
+
/obj/item/weapon/disk/plantgene/attackby(obj/item/weapon/W, mob/user, params)
..()
if(istype(W, /obj/item/weapon/pen))
diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm
index 2322bbad5ca..130fc2730ac 100644
--- a/code/modules/hydroponics/grown.dm
+++ b/code/modules/hydroponics/grown.dm
@@ -39,7 +39,9 @@
transform *= TransformUsingVariable(seed.potency, 100, 0.5) //Makes the resulting produce's sprite larger or smaller based on potency!
add_juice()
-
+/obj/item/weapon/reagent_containers/food/snacks/grown/Destroy()
+ QDEL_NULL(seed)
+ return ..()
/obj/item/weapon/reagent_containers/food/snacks/grown/proc/add_juice()
if(reagents)
diff --git a/code/modules/hydroponics/grown/kudzu.dm b/code/modules/hydroponics/grown/kudzu.dm
index e62d2df093e..1e975b4b79f 100644
--- a/code/modules/hydroponics/grown/kudzu.dm
+++ b/code/modules/hydroponics/grown/kudzu.dm
@@ -32,7 +32,7 @@
var/turf/T = get_turf(src)
message_admins("Kudzu planted by [key_name_admin(user)](?) (FLW) at ([T.x],[T.y],[T.z] - (JMP))",0,1)
investigate_log("was planted by [key_name(user)] at ([T.x],[T.y],[T.z])","kudzu")
- new /obj/effect/spacevine_controller(user.loc, mutations, potency, production)
+ new /obj/structure/spacevine_controller(user.loc, mutations, potency, production)
user.drop_item()
qdel(src)
diff --git a/code/modules/hydroponics/grown/mushrooms.dm b/code/modules/hydroponics/grown/mushrooms.dm
index 346e8344ca9..f923d08c694 100644
--- a/code/modules/hydroponics/grown/mushrooms.dm
+++ b/code/modules/hydroponics/grown/mushrooms.dm
@@ -220,7 +220,7 @@
rarity = 20
genes = list(/datum/plant_gene/trait/glow, /datum/plant_gene/trait/plant_type/fungal_metabolism)
growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi'
- mutatelist = list(/obj/item/seeds/glowshroom/glowcap)
+ mutatelist = list(/obj/item/seeds/glowshroom/glowcap, /obj/item/seeds/glowshroom/shadowshroom)
reagents_add = list("radium" = 0.1, "phosphorus" = 0.1, "nutriment" = 0.04)
/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom
@@ -229,20 +229,31 @@
desc = "Mycena Bregprox: This species of mushroom glows in the dark."
icon_state = "glowshroom"
filling_color = "#00FA9A"
- var/effect_path = /obj/effect/glowshroom
+ var/effect_path = /obj/structure/glowshroom
origin_tech = "biotech=4;plasmatech=6"
light_color = "#006622"
/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/attack_self(mob/user)
if(istype(user.loc, /turf/space))
- return
- var/obj/effect/glowshroom/planted = new effect_path(user.loc)
- planted.delay = planted.delay - seed.production * 100 //So the delay goes DOWN with better stats instead of up. :I
- planted.endurance = seed.endurance
- planted.yield = seed.yield
- planted.potency = seed.potency
+ return FALSE
+ if(!isturf(user.loc))
+ to_chat(user, "You need more space to plant [src].")
+ return FALSE
+ var/count = 0
+ var/maxcount = 1
+ for(var/tempdir in cardinal)
+ var/turf/simulated/wall = get_step(user.loc, tempdir)
+ if(istype(wall))
+ maxcount++
+ for(var/obj/structure/glowshroom/G in user.loc)
+ count++
+ if(count >= maxcount)
+ to_chat(user, "There are too many shrooms here to plant [src].")
+ return FALSE
+ new effect_path(user.loc, seed)
to_chat(user, "You plant [src].")
qdel(src)
+ return TRUE
// Glowcap
@@ -255,7 +266,7 @@
icon_dead = "glowshroom-dead"
plantname = "Glowcaps"
product = /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/glowcap
- genes = list(/datum/plant_gene/trait/glow, /datum/plant_gene/trait/cell_charge, /datum/plant_gene/trait/plant_type/fungal_metabolism)
+ genes = list(/datum/plant_gene/trait/glow/red, /datum/plant_gene/trait/cell_charge, /datum/plant_gene/trait/plant_type/fungal_metabolism)
mutatelist = list()
reagents_add = list("teslium" = 0.1, "nutriment" = 0.04)
rarity = 30
@@ -263,10 +274,10 @@
/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/glowcap
seed = /obj/item/seeds/glowshroom/glowcap
name = "glowcap cluster"
- desc = "Mycena Ruthenia: This species of mushroom glows in the dark, but aren't bioluminescent. They're warm to the touch..."
+ desc = "Mycena Ruthenia: This species of mushroom glows in the dark, but isn't actually bioluminescent. They're warm to the touch..."
icon_state = "glowcap"
filling_color = "#00FA9A"
- effect_path = /obj/effect/glowshroom/glowcap
+ effect_path = /obj/structure/glowshroom/glowcap
origin_tech = "biotech=4;powerstorage=6;plasmatech=4"
light_color = "#8E0300"
@@ -292,3 +303,26 @@
desc = "A fungus ideal for making antibacterials."
icon_state = "angel"
color = "#4f4331"
+
+//Shadowshroom
+/obj/item/seeds/glowshroom/shadowshroom
+ name = "pack of shadowshroom mycelium"
+ desc = "This mycelium will grow into something shadowy."
+ icon_state = "mycelium-shadowshroom"
+ species = "shadowshroom"
+ icon_grow = "shadowshroom-grow"
+ icon_dead = "shadowshroom-dead"
+ plantname = "Shadowshrooms"
+ product = /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/shadowshroom
+ genes = list(/datum/plant_gene/trait/glow/shadow, /datum/plant_gene/trait/plant_type/fungal_metabolism)
+ mutatelist = list()
+ reagents_add = list("radium" = 0.2, "nutriment" = 0.04)
+ rarity = 30
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/shadowshroom
+ seed = /obj/item/seeds/glowshroom/shadowshroom
+ name = "shadowshroom cluster"
+ desc = "Mycena Umbra: This species of mushroom emits shadow instead of light."
+ icon_state = "shadowshroom"
+ effect_path = /obj/structure/glowshroom/shadowshroom
+ origin_tech = "biotech=4;plasmatech=4;magnets=4"
diff --git a/code/modules/hydroponics/grown/root.dm b/code/modules/hydroponics/grown/root.dm
index 236c1465c8c..cc2a9ef4931 100644
--- a/code/modules/hydroponics/grown/root.dm
+++ b/code/modules/hydroponics/grown/root.dm
@@ -22,6 +22,13 @@
filling_color = "#FFA500"
bitesize_mod = 2
+/obj/item/weapon/reagent_containers/food/snacks/grown/carrot/wedges
+ name = "carrot wedges"
+ desc = "Slices of neatly cut carrot."
+ icon_state = "carrot_wedges"
+ filling_color = "#FFA500"
+ bitesize_mod = 2
+
/obj/item/weapon/reagent_containers/food/snacks/grown/carrot/attackby(obj/item/I, mob/user, params)
if(is_sharp(I))
to_chat(user, "You sharpen the carrot into a shiv with [I].")
@@ -33,6 +40,7 @@
else
return ..()
+
// Parsnip
/obj/item/seeds/carrot/parsnip
name = "pack of parsnip seeds"
diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm
index 64d2eff90b7..c94706f00e5 100644
--- a/code/modules/hydroponics/growninedible.dm
+++ b/code/modules/hydroponics/growninedible.dm
@@ -31,6 +31,9 @@
transform *= TransformUsingVariable(seed.potency, 100, 0.5)
add_juice()
+/obj/item/weapon/grown/Destroy()
+ QDEL_NULL(seed)
+ return ..()
/obj/item/weapon/grown/attackby(obj/item/O, mob/user, params)
..()
diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm
index 7ff1d4ae0d9..608c52bfcb4 100644
--- a/code/modules/hydroponics/hydroitemdefines.dm
+++ b/code/modules/hydroponics/hydroitemdefines.dm
@@ -120,6 +120,7 @@
hitsound = 'sound/weapons/bladeslice.ogg'
sharp = 1
edge = 1
+ var/extend = 1
/obj/item/weapon/scythe/suicide_act(mob/user)
user.visible_message("[user] is beheading \himself with the [src.name]! It looks like \he's trying to commit suicide.")
@@ -131,6 +132,64 @@
playsound(loc, pick('sound/misc/desceration-01.ogg','sound/misc/desceration-02.ogg','sound/misc/desceration-01.ogg'), 50, 1, -1)
return (BRUTELOSS)
+/obj/item/weapon/scythe/tele
+ icon_state = "tscythe0"
+ item_state = null //no sprite for folded version, like a tele-baton
+ name = "telescopic scythe"
+ desc = "A sharp and curved blade on a collapsable fibre metal handle, this tool is the pinnacle of covert reaping technology."
+ force = 3
+ sharp = 0
+ edge = 0
+ w_class = 2
+ extend = 0
+ slot_flags = SLOT_BELT
+ origin_tech = "materials=3;combat=3"
+ attack_verb = list("hit", "poked")
+ hitsound = "swing_hit"
+
+/obj/item/weapon/scythe/tele/attack_self(mob/user)
+ extend = !extend
+ if(extend)
+ to_chat(user, "With a flick of your wrist, you extend the scythe. It's reaping time!")
+ icon_state = "tscythe1"
+ item_state = "scythe0" //use the normal scythe in-hands
+ slot_flags = SLOT_BACK //won't fit on belt, but can be worn on belt when extended
+ w_class = 4 //won't fit in backpacks while extended
+ force = 15 //slightly better than normal scythe damage
+ attack_verb = list("chopped", "sliced", "cut", "reaped")
+ hitsound = 'sound/weapons/bladeslice.ogg'
+ //Extend sound (blade unsheath)
+ playsound(src.loc, 'sound/weapons/blade_unsheath.ogg', 50, 1) //Sound credit to Qat of Freesound.org
+ else
+ to_chat(user, "You collapse the scythe, folding it away for easy storage.")
+ icon_state = "tscythe0"
+ item_state = null //no sprite for folded version, like a tele-baton
+ slot_flags = SLOT_BELT //can be worn on belt again, but no longer makes sense to wear on the back
+ w_class = 2
+ force = 3
+ attack_verb = list("hit", "poked")
+ hitsound = "swing_hit"
+ //Collapse sound (blade sheath)
+ playsound(src.loc, 'sound/weapons/blade_sheath.ogg', 50, 1) //Sound credit to Q.K. of Freesound.org
+ sharp = extend
+ edge = extend
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ H.update_inv_l_hand()
+ H.update_inv_r_hand()
+ add_fingerprint(user)
+ if(!blood_DNA)
+ return
+ if(blood_overlay && (blood_DNA.len >= 1)) //updated blood overlay, if any
+ overlays.Cut() //this might delete other item overlays as well but eeeeeh
+
+ var/icon/I = new /icon(icon, icon_state)
+ I.Blend(new /icon('icons/effects/blood.dmi', rgb(255,255,255)), ICON_ADD)
+ I.Blend(new /icon('icons/effects/blood.dmi', "itemblood"), ICON_MULTIPLY)
+ blood_overlay = I
+ overlays += blood_overlay
+
+
// *************************************
// Nutrient defines for hydroponics
// *************************************
diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm
index 5eae76ea446..7e7aa825411 100644
--- a/code/modules/hydroponics/hydroponics.dm
+++ b/code/modules/hydroponics/hydroponics.dm
@@ -1,3 +1,5 @@
+#define HYDRO_CYCLES_PER_AGE 2 //Adjust this to adjust how many hydroponics cycles it takes to increase age. Positive integers only.
+
/obj/machinery/hydroponics
name = "hydroponics tray"
icon = 'icons/obj/hydroponics/equipment.dmi'
@@ -20,10 +22,12 @@
var/lastproduce = 0 //Last time it was harvested
var/lastcycle = 0 //Used for timing of cycles.
var/cycledelay = 200 //About 10 seconds / cycle
+ var/current_cycle = 0 //Used for tracking when to age
var/harvest = 0 //Ready to harvest?
var/obj/item/seeds/myseed = null //The currently planted seed
var/rating = 1
var/wrenchable = 1
+ var/lid_state = 0
var/recent_bee_visit = FALSE //Have we been visited by a bee recently, so bees dont overpollinate one plant
var/using_irrigation = FALSE //If the tray is connected to other trays via irrigation hoses
var/self_sustaining = FALSE //If the tray generates nutrients and water on its own
@@ -71,9 +75,7 @@
plant_hud_set_water()
/obj/machinery/hydroponics/Destroy()
- if(myseed)
- qdel(myseed)
- myseed = null
+ QDEL_NULL(myseed)
return ..()
/obj/machinery/hydroponics/constructable/attackby(obj/item/I, mob/user, params)
@@ -108,6 +110,20 @@
return connected
+/obj/machinery/hydroponics/AltClick()
+ if(wrenchable && !usr.stat && !usr.lying && Adjacent(usr))
+ toggle_lid(usr)
+ return
+ return ..()
+
+/obj/machinery/hydroponics/proc/toggle_lid(mob/living/user)
+ if(!user || user.stat || user.restrained())
+ return
+
+ lid_state = !lid_state
+ to_chat(user, "You [lid_state ? "close" : "open"] the tray's lid.")
+ update_icon()
+
/obj/machinery/hydroponics/bullet_act(obj/item/projectile/Proj) //Works with the Somatoray to modify plant variables.
if(!myseed)
@@ -136,7 +152,10 @@
lastcycle = world.time
if(myseed && !dead)
// Advance age
- age++
+ current_cycle++
+ if(current_cycle == HYDRO_CYCLES_PER_AGE)
+ age++
+ current_cycle = 0
if(age < myseed.maturation)
lastproduce = age
@@ -267,6 +286,9 @@
overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "gaia_blessing")
set_light(3)
+ if(lid_state)
+ overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "hydrocover")
+
update_icon_hoses()
if(myseed)
@@ -276,7 +298,7 @@
if(!self_sustaining)
if(myseed && myseed.get_gene(/datum/plant_gene/trait/glow))
var/datum/plant_gene/trait/glow/G = myseed.get_gene(/datum/plant_gene/trait/glow)
- set_light(G.get_lum(myseed))
+ set_light(G.glow_range(myseed), G.glow_power(myseed), G.glow_color)
else
set_light(0)
@@ -461,7 +483,7 @@
log_game("[key_name(user)] caused spiderling pests to spawn in a hydro tray")
visible_message("The pests seem to behave oddly...")
for(var/i in 1 to 3)
- var/obj/effect/spider/spiderling/S = new(get_turf(src))
+ var/obj/structure/spider/spiderling/S = new(get_turf(src))
S.grow_as = /mob/living/simple_animal/hostile/poison/giant_spider/hunter
else
to_chat(user, "The pests seem to behave oddly, but quickly settle down...")
@@ -850,8 +872,8 @@
if(!anchored && !isinspace())
user.visible_message("[user] begins to wrench [src] into place.", "You begin to wrench [src] in place...")
- playsound(loc, 'sound/items/Ratchet.ogg', 50, 1)
- if (do_after(user, 20, target = src))
+ playsound(loc, O.usesound, 50, 1)
+ if (do_after(user, 20 * O.toolspeed, target = src))
if(anchored)
return
anchored = 1
@@ -860,8 +882,8 @@
else if(anchored)
user.visible_message("[user] begins to unwrench [src].", \
"You begin to unwrench [src]...")
- playsound(loc, 'sound/items/Ratchet.ogg', 50, 1)
- if (do_after(user, 20, target = src))
+ playsound(loc, O.usesound, 50, 1)
+ if (do_after(user, 20 * O.toolspeed, target = src))
if(!anchored)
return
anchored = 0
@@ -870,7 +892,7 @@
else if(iswirecutter(O) && wrenchable)
using_irrigation = !using_irrigation
- playsound(src, 'sound/items/Wirecutter.ogg', 50, 1)
+ playsound(src, O.usesound, 50, 1)
user.visible_message("[user] [using_irrigation ? "" : "dis"]connects [src]'s irrigation hoses.", \
"You [using_irrigation ? "" : "dis"]connect [src]'s irrigation hoses.")
for(var/obj/machinery/hydroponics/h in range(1,src))
@@ -881,11 +903,11 @@
to_chat(user, "[src] doesn't have any plants or weeds!")
return
user.visible_message("[user] starts digging out [src]'s plants...", "You start digging out [src]'s plants...")
- playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1)
- if(!do_after(user, 50, target = src) || (!myseed && !weedlevel))
+ playsound(src, O.usesound, 50, 1)
+ if(!do_after(user, 25 * O.toolspeed, target = src) || (!myseed && !weedlevel))
return
user.visible_message("[user] digs out the plants in [src]!", "You dig out all of [src]'s plants!")
- playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1)
+ playsound(src, O.usesound, 50, 1)
if(myseed) //Could be that they're just using it as a de-weeder
age = 0
plant_health = 0
@@ -904,6 +926,9 @@
/obj/machinery/hydroponics/attack_hand(mob/user)
if(issilicon(user)) //How does AI know what plant is?
return
+ if(lid_state)
+ to_chat(user, "You can't reach the plant through the cover.")
+ return
if(harvest)
myseed.harvest(user)
else if(dead)
@@ -969,14 +994,14 @@
C.faction = list("plants")
///Diona Nymph Related Procs///
-/obj/machinery/hydroponics/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) //So nymphs can climb over top of trays.
- if(air_group || (height==0))
+/obj/machinery/hydroponics/CanPass(atom/movable/mover, turf/target, height=0) //So nymphs can climb over top of trays.
+ if(height==0)
return 1
if(istype(mover) && mover.checkpass(PASSTABLE))
return 1
else
- return 0
+ return ..()
/obj/machinery/hydroponics/attack_animal(mob/living/user)
if(istype(user, /mob/living/simple_animal/diona))
@@ -1013,4 +1038,6 @@
to_chat(user, "You clear up [src]!")
qdel(src)
else
- ..()
\ No newline at end of file
+ ..()
+
+#undef HYDRO_CYCLES_PER_AGE
\ No newline at end of file
diff --git a/code/modules/hydroponics/plant_genes.dm b/code/modules/hydroponics/plant_genes.dm
index ecf38424764..cfda1499555 100644
--- a/code/modules/hydroponics/plant_genes.dm
+++ b/code/modules/hydroponics/plant_genes.dm
@@ -263,23 +263,40 @@
/datum/plant_gene/trait/glow
// Makes plant glow. Makes plant in tray glow too.
- // Adds potency*rate luminosity to products.
+ // Adds 1 + potency*rate light range and potency*(rate + 0.01) light_power to products.
name = "Bioluminescence"
- rate = 0.1
+ rate = 0.03
examine_line = "It emits a soft glow."
trait_id = "glow"
+ var/glow_color = "#AAD84B"
-/datum/plant_gene/trait/glow/proc/get_lum(obj/item/seeds/S)
- return round(S.potency*rate)
+/datum/plant_gene/trait/glow/proc/glow_range(obj/item/seeds/S)
+ return 1.4 + S.potency*rate
+
+/datum/plant_gene/trait/glow/proc/glow_power(obj/item/seeds/S)
+ return max(S.potency*(rate + 0.01), 0.1)
/datum/plant_gene/trait/glow/on_new(obj/item/weapon/reagent_containers/food/snacks/grown/G, newloc)
..()
- G.set_light(get_lum(G.seed))
+ G.set_light(glow_range(G.seed), glow_power(G.seed), glow_color)
+
+/datum/plant_gene/trait/glow/shadow
+ //makes plant emit slightly purple shadows
+ //adds -potency*(rate*0.05) light power to products
+ name = "Shadow Emission"
+ rate = 0.04
+
+/datum/plant_gene/trait/glow/shadow/glow_power(obj/item/seeds/S)
+ return -max(S.potency*(rate*0.05), 0.075)
+
+/datum/plant_gene/trait/glow/red
+ name = "Red Electrical Glow"
+ glow_color = LIGHT_COLOR_RED
/datum/plant_gene/trait/glow/berry
name = "Strong Bioluminescence"
- rate = 0.2
-
+ rate = 0.05
+ glow_color = null
/datum/plant_gene/trait/teleport
// Makes plant teleport people when squashed or slipped on.
diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm
index d35621e4c59..9aa93f9f92b 100644
--- a/code/modules/hydroponics/seeds.dm
+++ b/code/modules/hydroponics/seeds.dm
@@ -68,6 +68,12 @@
for(var/reag_id in reagents_add)
genes += new /datum/plant_gene/reagent(reag_id, reagents_add[reag_id])
+/obj/item/seeds/Destroy()
+ for(var/thing in genes)
+ qdel(thing)
+ genes.Cut()
+ return ..()
+
/obj/item/seeds/proc/Copy()
var/obj/item/seeds/S = new type(null, 1)
// Copy all the stats
diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm
index bdd73533c82..bdbe222990a 100644
--- a/code/modules/karma/karma.dm
+++ b/code/modules/karma/karma.dm
@@ -1,8 +1,8 @@
proc/sql_report_karma(var/mob/spender, var/mob/receiver)
var/sqlspendername = sanitizeSQL(spender.name)
- var/sqlspenderkey = spender.key
+ var/sqlspenderkey = spender.ckey
var/sqlreceivername = sanitizeSQL(receiver.name)
- var/sqlreceiverkey = receiver.key
+ var/sqlreceiverkey = receiver.ckey
var/sqlreceiverrole = "None"
var/sqlreceiverspecial = "None"
@@ -24,7 +24,7 @@ proc/sql_report_karma(var/mob/spender, var/mob/receiver)
log_game("SQL ERROR during karma logging. Error : \[[err]\]\n")
- query = dbcon.NewQuery("SELECT * FROM [format_table_name("karmatotals")] WHERE byondkey='[receiver.key]'")
+ query = dbcon.NewQuery("SELECT * FROM [format_table_name("karmatotals")] WHERE byondkey='[receiver.ckey]'")
query.Execute()
var/karma
@@ -34,7 +34,7 @@ proc/sql_report_karma(var/mob/spender, var/mob/receiver)
karma = text2num(query.item[3])
if(karma == null)
karma = 1
- query = dbcon.NewQuery("INSERT INTO [format_table_name("karmatotals")] (byondkey, karma) VALUES ('[receiver.key]', [karma])")
+ query = dbcon.NewQuery("INSERT INTO [format_table_name("karmatotals")] (byondkey, karma) VALUES ('[receiver.ckey]', [karma])")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during karmatotal logging (adding new key). Error : \[[err]\]\n")
@@ -55,7 +55,7 @@ var/list/karma_spenders = list()
if(!ticker || !player_list.len || (ticker.current_state == GAME_STATE_PREGAME))
to_chat(src, "You can't award karma until the game has started.")
return 0
- if(client.karma_spent || (key in karma_spenders))
+ if(client.karma_spent || (ckey in karma_spenders))
to_chat(src, "You've already spent your karma for the round.")
return 0
return 1
@@ -70,7 +70,7 @@ var/list/karma_spenders = list()
if(!M.client)
to_chat(src, "That mob has no client connected at the moment.")
return 0
- if(key == M.key)
+ if(ckey == M.ckey)
to_chat(src, "You can't spend karma on yourself!")
return 0
if(client.address == M.client.address)
@@ -79,7 +79,7 @@ var/list/karma_spenders = list()
to_chat(src, "You can't spend karma on someone connected from the same IP.")
return 0
return 1
-
+
/mob/verb/spend_karma_list()
set name = "Award Karma"
@@ -118,8 +118,6 @@ var/list/karma_spenders = list()
if(!M)
to_chat(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
- if(!can_give_karma_to_mob(M))
- return
if(alert("Give [M.name] good karma?", "Karma", "Yes", "No") != "Yes")
return
if(!can_give_karma_to_mob(M))
@@ -128,7 +126,7 @@ var/list/karma_spenders = list()
M.client.karma += 1
to_chat(usr, "Good karma spent on [M.name].")
client.karma_spent = 1
- karma_spenders += key
+ karma_spenders += ckey
var/special_role = "None"
var/assigned_role = "None"
@@ -154,10 +152,10 @@ var/list/karma_spenders = list()
/client/proc/verify_karma()
var/currentkarma=0
if(!dbcon.IsConnected())
- to_chat(usr, "\red Unable to connect to karma database. Please try again later. ")
+ to_chat(usr, "Unable to connect to karma database. Please try again later. ")
return
else
- var/DBQuery/query = dbcon.NewQuery("SELECT karma, karmaspent FROM [format_table_name("karmatotals")] WHERE byondkey='[src.key]'")
+ var/DBQuery/query = dbcon.NewQuery("SELECT karma, karmaspent FROM [format_table_name("karmatotals")] WHERE byondkey='[src.ckey]'")
query.Execute()
var/totalkarma
@@ -258,7 +256,7 @@ You've gained [totalkarma] total karma in your time here. "}
return
/client/proc/DB_job_unlock(var/job,var/cost)
- var/DBQuery/query = dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.key]'")
+ var/DBQuery/query = dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.ckey]'")
query.Execute()
var/dbjob
@@ -267,7 +265,7 @@ You've gained [totalkarma] total karma in your time here. "}
dbckey = query.item[2]
dbjob = query.item[3]
if(!dbckey)
- query = dbcon.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, job) VALUES ('[usr.key]','[job]')")
+ query = dbcon.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, job) VALUES ('[usr.ckey]','[job]')")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during whitelist logging (adding new key). Error: \[[err]\]\n")
@@ -298,7 +296,7 @@ You've gained [totalkarma] total karma in your time here. "}
return
/client/proc/DB_species_unlock(var/species,var/cost)
- var/DBQuery/query = dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.key]'")
+ var/DBQuery/query = dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.ckey]'")
query.Execute()
var/dbspecies
@@ -307,7 +305,7 @@ You've gained [totalkarma] total karma in your time here. "}
dbckey = query.item[2]
dbspecies = query.item[4]
if(!dbckey)
- query = dbcon.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, species) VALUES ('[usr.key]','[species]')")
+ query = dbcon.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, species) VALUES ('[usr.ckey]','[species]')")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during whitelist logging (adding new key). Error : \[[err]\]\n")
@@ -338,7 +336,7 @@ You've gained [totalkarma] total karma in your time here. "}
return
/client/proc/karmacharge(var/cost,var/refund = 0)
- var/DBQuery/query = dbcon.NewQuery("SELECT * FROM [format_table_name("karmatotals")] WHERE byondkey='[usr.key]'")
+ var/DBQuery/query = dbcon.NewQuery("SELECT * FROM [format_table_name("karmatotals")] WHERE byondkey='[usr.ckey]'")
query.Execute()
while(query.NextRow())
@@ -347,7 +345,7 @@ You've gained [totalkarma] total karma in your time here. "}
spent -= cost
else
spent += cost
- query = dbcon.NewQuery("UPDATE [format_table_name("karmatotals")] SET karmaspent=[spent] WHERE byondkey='[usr.key]'")
+ query = dbcon.NewQuery("UPDATE [format_table_name("karmatotals")] SET karmaspent=[spent] WHERE byondkey='[usr.ckey]'")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during karmaspent updating (updating existing entry). Error: \[[err]\]\n")
@@ -380,10 +378,10 @@ You've gained [totalkarma] total karma in your time here. "}
else if(name == "Nanotrasen Recruiter")
cost = 10
else
- to_chat(usr, "\red That job is not refundable.")
+ to_chat(usr, "That job is not refundable.")
return
- var/DBQuery/query = dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.key]'")
+ var/DBQuery/query = dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.ckey]'")
query.Execute()
var/dbjob
@@ -401,7 +399,7 @@ You've gained [totalkarma] total karma in your time here. "}
else if(type == "species")
typelist = splittext(dbspecies,",")
else
- to_chat(usr, "\red Type [type] is not a valid column.")
+ to_chat(usr, "Type [type] is not a valid column.")
if(name in typelist)
typelist -= name
@@ -417,13 +415,13 @@ You've gained [totalkarma] total karma in your time here. "}
message_admins("[key_name(usr)] has been refunded [cost] karma for [type] [name].")
karmacharge(text2num(cost),1)
else
- to_chat(usr, "\red You have not bought [name].")
+ to_chat(usr, "You have not bought [name].")
else
- to_chat(usr, "\red Your ckey ([dbckey]) was not found.")
+ to_chat(usr, "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 [format_table_name("whitelist")] WHERE ckey='[usr.key]'")
+ var/DBQuery/query = dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.ckey]'")
query.Execute()
var/dbjob
diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm
index f2272c97e96..a32b31611cc 100644
--- a/code/modules/library/lib_items.dm
+++ b/code/modules/library/lib_items.dm
@@ -31,7 +31,7 @@
I.forceMove(src)
update_icon()
-/obj/structure/bookcase/attackby(obj/O as obj, mob/user as mob, params)
+/obj/structure/bookcase/attackby(obj/item/O as obj, mob/user as mob, params)
if(busy) //So that you can't mess with it while deconstructing
return 1
if(is_type_in_list(O, allowed_books))
@@ -51,11 +51,11 @@
else if(istype(O, /obj/item/weapon/wrench))
user.visible_message("[user] starts disassembling \the [src].", \
"You start disassembling \the [src].")
- playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(get_turf(src), O.usesound, 50, 1)
busy = 1
- if(do_after(user,50, target = src))
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 75, 1)
+ if(do_after(user, 50 * O.toolspeed, target = src))
+ playsound(get_turf(src), O.usesound, 75, 1)
user.visible_message("[user] disassembles \the [src].", \
"You disassemble \the [src].")
busy = 0
@@ -276,7 +276,7 @@
if(carved)
return 1
to_chat(user, "You begin to carve out [title].")
- if(do_after(user, 30, target = src))
+ if(do_after(user, 30 * W.toolspeed, target = src))
to_chat(user, "You carve out the pages from [title]! You didn't want to read it anyway.")
carved = 1
return 1
diff --git a/code/modules/lighting/lighting_corner.dm b/code/modules/lighting/lighting_corner.dm
index a464f5af2d0..907e7aab8b5 100644
--- a/code/modules/lighting/lighting_corner.dm
+++ b/code/modules/lighting/lighting_corner.dm
@@ -1,4 +1,4 @@
-/var/list/datum/lighting_corner/all_lighting_corners = list()
+/var/total_lighting_corners = 0
/var/datum/lighting_corner/dummy/dummy_lighting_corner = new
// Because we can control each corner of every lighting overlay.
// And corners get shared between multiple turfs (unless you're on the corners of the map, then 1 corner doesn't).
@@ -32,7 +32,7 @@
/datum/lighting_corner/New(var/turf/new_turf, var/diagonal)
. = ..()
- all_lighting_corners += src
+ total_lighting_corners++
masters[new_turf] = turn(diagonal, 180)
z = new_turf.z
diff --git a/code/modules/lighting/lighting_overlay.dm b/code/modules/lighting/lighting_overlay.dm
index b6e4b8b066b..6fe55eed0ff 100644
--- a/code/modules/lighting/lighting_overlay.dm
+++ b/code/modules/lighting/lighting_overlay.dm
@@ -1,4 +1,4 @@
-var/list/all_lighting_overlays = list() // Global list of lighting overlays.
+/var/total_lighting_overlays = 0
/atom/movable/lighting_overlay
name = ""
mouse_opacity = 0
@@ -21,7 +21,7 @@ var/list/all_lighting_overlays = list() // Global list of lighting overlays.
/atom/movable/lighting_overlay/New(var/atom/loc, var/no_update = FALSE)
. = ..()
verbs.Cut()
- global.all_lighting_overlays += src
+ total_lighting_overlays++
var/turf/T = loc //If this runtimes atleast we'll know what's creating overlays outside of turfs.
T.lighting_overlay = src
@@ -77,7 +77,7 @@ var/list/all_lighting_overlays = list() // Global list of lighting overlays.
return
/atom/movable/lighting_overlay/Destroy()
- global.all_lighting_overlays -= src
+ total_lighting_overlays--
global.lighting_update_overlays -= src
global.lighting_update_overlays_old -= src
diff --git a/code/modules/lighting/lighting_source.dm b/code/modules/lighting/lighting_source.dm
index 01f967a0544..d878d8c4b6e 100644
--- a/code/modules/lighting/lighting_source.dm
+++ b/code/modules/lighting/lighting_source.dm
@@ -1,4 +1,4 @@
-/var/list/datum/light_source/all_lighting_sources = list()
+/var/total_lighting_sources = 0
// This is where the fun begins.
// These are the main datums that emit light.
@@ -32,7 +32,7 @@
var/force_update
/datum/light_source/New(var/atom/owner, var/atom/top)
- all_lighting_sources += src
+ total_lighting_sources++
source_atom = owner // Set our new owner.
if(!source_atom.light_sources)
source_atom.light_sources = list()
@@ -62,7 +62,7 @@
// Kill ourselves.
/datum/light_source/proc/destroy()
- all_lighting_sources -= src
+ total_lighting_sources--
destroyed = TRUE
force_update()
if(source_atom)
diff --git a/code/modules/mining/coins.dm b/code/modules/mining/coins.dm
index 83f9c871f44..00ea7632900 100644
--- a/code/modules/mining/coins.dm
+++ b/code/modules/mining/coins.dm
@@ -134,7 +134,7 @@
"uranium" = /obj/item/clothing/gloves/ring/uranium)
var/typekey = typelist[cmineral]
if(ispath(typekey))
- to_chat(user, "\blue You make [src] into a ring.")
+ to_chat(user, "You make [src] into a ring.")
new typekey(get_turf(loc))
qdel(src)
else ..()
diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm
index 54ecf32cf74..d6c375c2832 100644
--- a/code/modules/mining/equipment_locker.dm
+++ b/code/modules/mining/equipment_locker.dm
@@ -112,8 +112,14 @@
return
if(panel_open)
if(istype(W, /obj/item/weapon/crowbar))
+ if(inserted_id)
+ inserted_id.forceMove(loc) //Prevents deconstructing the ORM from deleting whatever ID was inside it.
empty_content()
default_deconstruction_crowbar(W)
+ if(ismultitool(W))
+ input_dir = turn(input_dir, -90)
+ output_dir = turn(output_dir, -90)
+ to_chat(user, "You change [src]'s I/O settings, setting the input to [dir2text(input_dir)] and the output to [dir2text(output_dir)].")
return
if(default_unfasten_wrench(user, W))
return
@@ -139,11 +145,14 @@
qdel(O)//No refined type? Purge it.
return
-/obj/machinery/mineral/ore_redemption/attack_hand(user as mob)
+/obj/machinery/mineral/ore_redemption/attack_hand(mob/user)
if(..())
return
interact(user)
+/obj/machinery/mineral/ore_redemption/attack_ghost(mob/user)
+ interact(user)
+
/obj/machinery/mineral/ore_redemption/interact(mob/user)
user.set_machine(src)
@@ -194,7 +203,8 @@
/obj/machinery/mineral/ore_redemption/Topic(href, href_list)
if(..())
- return
+ return 1
+
if(href_list["choice"])
if(istype(inserted_id))
if(href_list["choice"] == "eject")
@@ -211,11 +221,12 @@
var/obj/item/weapon/card/id/I = usr.get_active_hand()
if(istype(I))
if(!usr.drop_item())
- return
+ return 1
I.loc = src
inserted_id = I
else
to_chat(usr, "No valid ID.")
+
if(href_list["release"])
if(check_access(inserted_id) || allowed(usr)) //Check the ID inside, otherwise check the user.
if(!(text2path(href_list["release"]) in stack_list)) return
@@ -230,6 +241,7 @@
stack_list -= text2path(href_list["release"])
else
to_chat(usr, "Required access not found.")
+
if(href_list["plasteel"])
if(check_access(inserted_id) || allowed(usr))
if(!(/obj/item/stack/sheet/metal in stack_list)) return
@@ -246,6 +258,7 @@
unload_mineral(plasteelout)
else
to_chat(usr, "Required access not found.")
+
if(href_list["plasglass"])
if(check_access(inserted_id) || allowed(usr))
if(!(/obj/item/stack/sheet/glass in stack_list)) return
@@ -263,7 +276,6 @@
else
to_chat(usr, "Required access not found.")
updateUsrDialog()
- return
/obj/machinery/mineral/ore_redemption/ex_act(severity, target)
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
@@ -294,6 +306,9 @@
/obj/machinery/mineral/ore_redemption/power_change()
..()
update_icon()
+ if(inserted_id && !powered())
+ visible_message("The ID slot indicator light flickers on \the [src] as it spits out a card before powering down.")
+ inserted_id.forceMove(loc)
/obj/machinery/mineral/ore_redemption/update_icon()
if(powered())
@@ -339,7 +354,7 @@
new /datum/data/mining_equipment("Lazarus Capsule", /obj/item/device/mobcapsule, 800),
new /datum/data/mining_equipment("Lazarus Capsule belt",/obj/item/weapon/storage/belt/lazarus, 200),
new /datum/data/mining_equipment("Jetpack", /obj/item/weapon/tank/jetpack/carbondioxide/mining, 2000),
- new /datum/data/mining_equipment("Space Cash", /obj/item/weapon/spacecash/c1000, 2000),
+ new /datum/data/mining_equipment("Space Cash", /obj/item/stack/spacecash/c1000, 2000),
new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/weapon/pickaxe/diamond, 2000),
new /datum/data/mining_equipment("Super Resonator", /obj/item/weapon/resonator/upgraded, 2500),
new /datum/data/mining_equipment("KA White Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer, 100),
@@ -377,19 +392,24 @@
/obj/machinery/mineral/equipment_vendor/power_change()
..()
update_icon()
+ if(inserted_id && !powered())
+ visible_message("The ID slot indicator light flickers on \the [src] as it spits out a card before powering down.")
+ inserted_id.forceMove(loc)
/obj/machinery/mineral/equipment_vendor/update_icon()
if(powered())
icon_state = initial(icon_state)
else
icon_state = "[initial(icon_state)]-off"
- return
-/obj/machinery/mineral/equipment_vendor/attack_hand(user as mob)
+/obj/machinery/mineral/equipment_vendor/attack_hand(mob/user)
if(..())
return
interact(user)
+/obj/machinery/mineral/equipment_vendor/attack_ghost(mob/user)
+ interact(user)
+
/obj/machinery/mineral/equipment_vendor/interact(mob/user)
user.set_machine(src)
@@ -407,11 +427,11 @@
var/datum/browser/popup = new(user, "miningvendor", "Mining Equipment Vendor", 400, 350)
popup.set_content(dat)
popup.open()
- return
/obj/machinery/mineral/equipment_vendor/Topic(href, href_list)
if(..())
- return
+ return 1
+
if(href_list["choice"])
if(istype(inserted_id))
if(href_list["choice"] == "eject")
@@ -427,24 +447,25 @@
inserted_id = I
else
to_chat(usr, "No valid ID.")
+
if(href_list["purchase"])
if(istype(inserted_id))
var/datum/data/mining_equipment/prize = locate(href_list["purchase"])
- if(!prize || !(prize in prize_list))
+ if(!prize || !(prize in prize_list) || prize.cost > inserted_id.mining_points)
return
- if(prize.cost > inserted_id.mining_points)
- else
- inserted_id.mining_points -= prize.cost
- new prize.equipment_path(src.loc)
- updateUsrDialog()
- return
-/obj/machinery/mineral/equipment_vendor/attackby(obj/item/I as obj, mob/user as mob, params)
+ inserted_id.mining_points -= prize.cost
+ new prize.equipment_path(src.loc)
+ updateUsrDialog()
+
+/obj/machinery/mineral/equipment_vendor/attackby(obj/item/I, mob/user, params)
if(default_deconstruction_screwdriver(user, "mining-open", "mining", I))
updateUsrDialog()
return
if(panel_open)
if(istype(I, /obj/item/weapon/crowbar))
+ if(inserted_id)
+ inserted_id.forceMove(loc) //Prevents deconstructing the ORM from deleting whatever ID was inside it.
default_deconstruction_crowbar(I)
return 1
if(istype(I, /obj/item/weapon/mining_voucher))
@@ -510,7 +531,7 @@
icon_state = "data"
var/points = 500
-/obj/item/weapon/card/mining_point_card/attackby(obj/item/I as obj, mob/user as mob, params)
+/obj/item/weapon/card/mining_point_card/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/card/id))
if(points)
var/obj/item/weapon/card/id/C = I
@@ -539,7 +560,7 @@
throw_range = 5
origin_tech = "bluespace=2"
-/obj/item/device/wormhole_jaunter/attack_self(mob/user as mob)
+/obj/item/device/wormhole_jaunter/attack_self(mob/user)
var/turf/device_turf = get_turf(user)
if(!device_turf||is_teleport_allowed(device_turf.z))
to_chat(user, "You're having difficulties getting the [src.name] to work.")
@@ -620,7 +641,7 @@
spawn(burst_time)
fieldsactive--
-/obj/item/weapon/resonator/attack_self(mob/user as mob)
+/obj/item/weapon/resonator/attack_self(mob/user)
if(burst_time == 50)
burst_time = 30
to_chat(user, "You set the resonator's fields to detonate after 3 seconds.")
@@ -709,7 +730,7 @@
icon_state = "implant"
max_w_class = 3
storage_slots = 2
- can_hold = list("/obj/item/weapon/mining_drone_cube","/obj/item/weapon/weldingtool/hugetank")
+ can_hold = list(/obj/item/weapon/mining_drone_cube, /obj/item/weapon/weldingtool/hugetank)
/obj/item/weapon/storage/box/drone_kit/New()
..()
diff --git a/code/modules/mining/lavaland/loot/tendril_loot.dm b/code/modules/mining/lavaland/loot/tendril_loot.dm
index ed8b400337a..dec8712eb74 100644
--- a/code/modules/mining/lavaland/loot/tendril_loot.dm
+++ b/code/modules/mining/lavaland/loot/tendril_loot.dm
@@ -33,7 +33,7 @@
if(bag)
bag.loc = user
bag.attackby(W, user, params)
-
+
/obj/item/device/shared_storage/attack_self(mob/living/carbon/user)
if(!iscarbon(user))
return
@@ -116,7 +116,7 @@
H.adjustBruteLoss(20)
H.emote("scream")
..()*/
-
+
//Boat
/obj/vehicle/lavaboat
@@ -183,7 +183,7 @@
generic_pixel_y = 2
generic_pixel_x = 1
vehicle_move_delay = 1
-
+
// Wisp Lantern
/obj/item/device/wisp_lantern
name = "spooky lantern"
@@ -238,16 +238,16 @@
layer = ABOVE_ALL_MOB_LAYER
light_power = 1
light_range = 7
-
+
//Red/Blue Cubes
-
+
/obj/item/device/warp_cube
name = "blue cube"
desc = "A mysterious blue cube."
icon = 'icons/obj/lavaland/artefacts.dmi'
icon_state = "blue_cube"
var/obj/item/device/warp_cube/linked
-
+
/obj/item/device/warp_cube/Destroy()
if(linked)
linked.linked = null
@@ -260,14 +260,14 @@
return
var/datum/effect/system/harmless_smoke_spread/smoke = new /datum/effect/system/harmless_smoke_spread()
- smoke.set_up(1, 0, user.loc)
+ smoke.set_up(1, 0, user.loc)
smoke.start()
user.forceMove(get_turf(linked))
feedback_add_details("warp_cube","[src.type]")
var/datum/effect/system/harmless_smoke_spread/smoke2 = new /datum/effect/system/harmless_smoke_spread()
- smoke2.set_up(1, 0, user.loc)
+ smoke2.set_up(1, 0, user.loc)
smoke2.start()
/obj/item/device/warp_cube/red
@@ -281,7 +281,7 @@
var/obj/item/device/warp_cube/blue = new(src.loc)
linked = blue
blue.linked = src
-
+
//Meat Hook
/obj/item/weapon/gun/magic/hook
@@ -329,9 +329,9 @@
L.forceMove(get_turf(firer))
/obj/item/projectile/hook/Destroy()
- qdel(chain)
+ QDEL_NULL(chain)
return ..()
-
+
//Immortality Talisman
/obj/item/device/immortality_talisman
diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm
index 3910baf10de..6c34b6e0570 100644
--- a/code/modules/mining/lavaland/necropolis_chests.dm
+++ b/code/modules/mining/lavaland/necropolis_chests.dm
@@ -40,8 +40,8 @@
if(10)
new /obj/item/ship_in_a_bottle(src)
if(11)
- new /obj/item/clothing/head/helmet/space/rig/ert/paranormal/berserker(src)
- new /obj/item/clothing/suit/space/rig/ert/paranormal/berserker(src)
+ new /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/berserker(src)
+ new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/berserker(src)
if(12)
new /obj/item/weapon/sord(src)
if(13)
@@ -66,7 +66,7 @@
new /obj/item/weapon/grenade/clusterbuster/inferno(src)
if(23)
new /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater/hell(src)
- new /obj/item/clothing/head/helmet/space/rig/ert/paranormal/inquisitor(src)
- new /obj/item/clothing/suit/space/rig/ert/paranormal/inquisitor(src)
+ new /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor(src)
+ new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor(src)
if(24)
new /obj/item/weapon/spellbook/oneuse/summonitem(src)
\ No newline at end of file
diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm
index c824934ee8b..212e8488ac8 100644
--- a/code/modules/mining/machine_processing.dm
+++ b/code/modules/mining/machine_processing.dm
@@ -297,24 +297,6 @@
else
on = 0
continue
- //THESE TWO ARE CODED FOR URIST TO USE WHEN HE GETS AROUND TO IT.
- //They were coded on 18 Feb 2012. If you're reading this in 2015, then firstly congratulations on the world not ending on 21 Dec 2012 and secondly, Urist is apparently VERY lazy. ~Errorage
- /*if(selected_glass == 0 && selected_gold == 0 && selected_silver == 0 && selected_diamond == 1 && selected_plasma == 0 && selected_uranium == 1 && selected_iron == 0 && selected_clown == 0 && selected_mime == 0)
- if(ore_uranium >= 2 && ore_diamond >= 1)
- ore_uranium -= 2
- ore_diamond -= 1
- generate_mineral(/obj/item/stack/sheet/mineral/adamantine)
- else
- on = 0
- continue
- if(selected_glass == 0 && selected_gold == 0 && selected_silver == 1 && selected_diamond == 0 && selected_plasma == 1 && selected_uranium == 0 && selected_iron == 0 && selected_clown == 0 && selected_mime == 0)
- if(ore_silver >= 1 && ore_plasma >= 3)
- ore_silver -= 1
- ore_plasma -= 3
- generate_mineral(/obj/item/stack/sheet/mineral/mythril)
- else
- on = 0
- continue*/
//if a non valid combination is selected
@@ -424,4 +406,4 @@
/obj/machinery/mineral/processing_unit/proc/generate_mineral(var/P)
var/O = new P(src)
- unload_mineral(O)
\ No newline at end of file
+ unload_mineral(O)
diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm
index defa8a930ff..2935ed25d04 100644
--- a/code/modules/mining/mine_items.dm
+++ b/code/modules/mining/mine_items.dm
@@ -89,6 +89,8 @@
sharp = 1
edge = 1
var/excavation_amount = 100
+ usesound = 'sound/effects/picaxe1.ogg'
+ toolspeed = 1
/obj/item/weapon/pickaxe/proc/playDigSound()
playsound(src, pick(digsound),20,1)
@@ -100,6 +102,16 @@
digspeed = 30 //mines faster than a normal pickaxe, bought from mining vendor
origin_tech = "materials=3;engineering=2"
desc = "A silver-plated pickaxe that mines slightly faster than standard-issue."
+ toolspeed = 0.75
+
+/obj/item/weapon/pickaxe/gold
+ name = "golden pickaxe"
+ icon_state = "gpickaxe"
+ item_state = "gpickaxe"
+ digspeed = 20
+ origin_tech = "materials=4;engineering=2"
+ desc = "A gold-plated pickaxe that mines faster than standard-issue."
+ toolspeed = 0.6
/obj/item/weapon/pickaxe/diamond
name = "diamond-tipped pickaxe"
@@ -108,6 +120,7 @@
digspeed = 20 //mines twice as fast as a normal pickaxe, bought from mining vendor
origin_tech = "materials=4;engineering=3"
desc = "A pickaxe with a diamond pick head. Extremely robust at cracking rock walls and digging up dirt."
+ toolspeed = 0.5
/obj/item/weapon/pickaxe/drill
name = "mining drill"
@@ -116,8 +129,10 @@
digspeed = 25 //available from roundstart, faster than a pickaxe.
digsound = list('sound/weapons/drill.ogg')
hitsound = 'sound/weapons/drill.ogg'
+ usesound = 'sound/weapons/drill.ogg'
origin_tech = "materials=2;powerstorage=3;engineering=2"
desc = "An electric mining drill for the especially scrawny."
+ toolspeed = 0.5
/obj/item/weapon/pickaxe/drill/cyborg
name = "cyborg mining drill"
@@ -130,6 +145,7 @@
digspeed = 10
origin_tech = "materials=6;powerstorage=4;engineering=5"
desc = "Yours is the drill that will pierce the heavens!"
+ toolspeed = 0.25
/obj/item/weapon/pickaxe/diamonddrill/traitor //Pocket-sized traitor diamond drill.
name = "supermatter drill"
@@ -142,6 +158,7 @@
name = "diamond-tipped cyborg mining drill" //To inherit the NODROP flag, and easier to change borg specific drill mechanics.
icon_state = "diamonddrill"
digspeed = 10
+ toolspeed = 0.25
/obj/item/weapon/pickaxe/drill/jackhammer
name = "sonic jackhammer"
@@ -151,23 +168,10 @@
origin_tech = "materials=3;powerstorage=2;engineering=2"
digsound = list('sound/weapons/sonic_jackhammer.ogg')
hitsound = 'sound/weapons/sonic_jackhammer.ogg'
+ usesound = 'sound/weapons/sonic_jackhammer.ogg'
desc = "Cracks rocks with sonic blasts, and doubles as a demolition power tool for smashing walls."
+ toolspeed = 0.1
-/obj/item/weapon/pickaxe/silver
- name = "silver pickaxe"
- icon_state = "spickaxe"
- item_state = "spickaxe"
- digspeed = 30
- origin_tech = "materials=3"
- desc = "This makes no metallurgic sense."
-
-/obj/item/weapon/pickaxe/gold
- name = "golden pickaxe"
- icon_state = "gpickaxe"
- item_state = "gpickaxe"
- digspeed = 20
- origin_tech = "materials=4"
- desc = "This makes no metallurgic sense."
/*****************************Shovel********************************/
/obj/item/weapon/shovel
@@ -184,6 +188,8 @@
materials = list(MAT_METAL=50)
origin_tech = "materials=1;engineering=1"
attack_verb = list("bashed", "bludgeoned", "thrashed", "whacked")
+ usesound = 'sound/effects/shovel_dig.ogg'
+ toolspeed = 1
/obj/item/weapon/shovel/spade
name = "spade"
@@ -193,6 +199,7 @@
force = 5.0
throwforce = 7.0
w_class = 2
+ toolspeed = 2
/**********************Mining car (Crate like thing, not the rail car)**************************/
@@ -219,6 +226,7 @@
/obj/item/device/mobcapsule/Destroy()
if(captured)
+ captured.ghostize()
qdel(captured)
captured = null
return ..()
@@ -393,10 +401,10 @@
/obj/item/device/gps/computer/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/wrench))
- playsound(loc, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(loc, W.usesound, 50, 1)
user.visible_message("[user] disassembles the gps.", \
"You start to disassemble the gps...", "You hear clanking and banging noises.")
- if(do_after(user, 20, target = src))
+ if(do_after(user, 20 * W.toolspeed, target = src))
new /obj/item/device/gps(loc)
qdel(src)
return ..()
@@ -471,10 +479,10 @@
/obj/structure/fans/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/wrench))
- playsound(loc, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(loc, W.usesound, 50, 1)
user.visible_message("[user] disassembles the fan.", \
"You start to disassemble the fan...", "You hear clanking and banging noises.")
- if(do_after(user, 20, target = src))
+ if(do_after(user, 20 * W.toolspeed, target = src))
deconstruct()
return ..()
@@ -522,10 +530,10 @@
/obj/structure/tubes/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/wrench))
- playsound(loc, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(loc, W.usesound, 50, 1)
user.visible_message("[user] disassembles [src].", \
"You start to disassemble [src]...", "You hear clanking and banging noises.")
- if(do_after(user, 20, target = src))
+ if(do_after(user, 20 * W.toolspeed, target = src))
new /obj/item/stack/rods(loc)
qdel(src)
return ..()
diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm
index 623192ff820..d57f509e13e 100644
--- a/code/modules/mining/mine_turfs.dm
+++ b/code/modules/mining/mine_turfs.dm
@@ -470,14 +470,14 @@ var/global/list/rockTurfEdgeCache = list(
src.gets_dug()
return
-/turf/simulated/floor/plating/airless/asteroid/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
+/turf/simulated/floor/plating/airless/asteroid/attackby(obj/item/weapon/W, mob/user, params)
//note that this proc does not call ..()
if(!W || !user)
return 0
if((istype(W, /obj/item/weapon/shovel)))
- var/turf/T = user.loc
- if(!( istype(T, /turf) ))
+ var/turf/T = get_turf(user)
+ if(!istype(T))
return
if(dug)
@@ -485,17 +485,15 @@ var/global/list/rockTurfEdgeCache = list(
return
to_chat(user, "You start digging...")
-
- sleep(20)
- if((user.loc == T && user.get_active_hand() == W))
+ if(do_after(user, 20 * W.toolspeed, target = src))
to_chat(user, "You dig a hole.")
gets_dug()
return
if((istype(W, /obj/item/weapon/pickaxe)))
var/obj/item/weapon/pickaxe/P = W
- var/turf/T = user.loc
- if(!( istype(T, /turf) ))
+ var/turf/T = get_turf(user)
+ if(!istype(T))
return
if(dug)
@@ -504,8 +502,7 @@ var/global/list/rockTurfEdgeCache = list(
to_chat(user, "You start digging...")
- sleep(P.digspeed)
- if((user.loc == T && user.get_active_hand() == W))
+ if(do_after(user, P.digspeed, target = src))
to_chat(user, "You dig a hole.")
gets_dug()
return
diff --git a/code/modules/mining/mint.dm b/code/modules/mining/mint.dm
index 95dc3a05f25..b460fc7d467 100644
--- a/code/modules/mining/mint.dm
+++ b/code/modules/mining/mint.dm
@@ -15,8 +15,6 @@
var/amt_uranium = 0
var/amt_clown = 0
var/amt_mime = 0
- var/amt_adamantine = 0
- var/amt_mythril = 0
var/newCoins = 0 //how many coins the machine made in it's last load
var/processing = 0
var/chosen = "metal" //which material will be used to make coins
@@ -53,7 +51,7 @@
qdel(O)
-/obj/machinery/mineral/mint/attack_hand(user as mob) //TODO: Adamantine coins! -Durandan
+/obj/machinery/mineral/mint/attack_hand(user as mob)
var/dat = "Coin Press "
@@ -99,11 +97,6 @@
dat += text("chosen")
else
dat += text("Choose")
- dat += text(" Adamantine inserted: [amt_adamantine] ")//I don't even know these color codes, so fuck it.
- if(chosen == "adamantine")
- dat += text("chosen")
- else
- dat += text("Choose")
dat += text("
Will produce [coinsToProduce] [chosen] coins if enough materials are available. ")
//dat += text("The dial which controls the number of conins to produce seems to be stuck. A technician has already been dispatched to fix this.")
@@ -199,22 +192,6 @@
newCoins++
src.updateUsrDialog()
sleep(5)
- if("adamantine")
- while(amt_adamantine > 0 && coinsToProduce > 0)
- create_coins(/obj/item/weapon/coin/adamantine)
- amt_adamantine -= 20
- coinsToProduce--
- newCoins++
- src.updateUsrDialog()
- sleep(5)
- if("mythril")
- while(amt_adamantine > 0 && coinsToProduce > 0)
- create_coins(/obj/item/weapon/coin/mythril)
- amt_mythril -= 20
- coinsToProduce--
- newCoins++
- src.updateUsrDialog()
- sleep(5)
icon_state = "coinpress0"
processing = 0
coinsToProduce = temp_coins
@@ -229,4 +206,4 @@
if(!M)
M = new /obj/item/weapon/moneybag(src)
unload_mineral(M)
- O.loc = M
\ No newline at end of file
+ O.loc = M
diff --git a/code/modules/mining/ore.dm b/code/modules/mining/ore.dm
index 9e4d268281c..cc50f46b9e5 100644
--- a/code/modules/mining/ore.dm
+++ b/code/modules/mining/ore.dm
@@ -62,7 +62,7 @@
points = 1
refined_type = /obj/item/stack/sheet/glass
materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
-
+
/obj/item/weapon/ore/glass/basalt
name = "volcanic ash"
icon_state = "volcanic_sand"
@@ -163,8 +163,7 @@
var/datum/wires/explosive/gibtonite/wires
/obj/item/weapon/twohanded/required/gibtonite/Destroy()
- qdel(wires)
- wires = null
+ QDEL_NULL(wires)
return ..()
/obj/item/weapon/twohanded/required/gibtonite/attackby(obj/item/I, mob/user, params)
@@ -193,7 +192,11 @@
return
..()
-/obj/item/weapon/twohanded/required/gibtonite/attack_self(user)
+/obj/item/weapon/twohanded/required/gibtonite/attack_ghost(mob/user)
+ if(wires)
+ wires.Interact(user)
+
+/obj/item/weapon/twohanded/required/gibtonite/attack_self(mob/user)
if(wires)
wires.Interact(user)
else
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index d84e434456d..b7dc83c149d 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -99,7 +99,7 @@ var/list/image/ghost_darkness_images = list() //this is a list of images for thi
updateallghostimages()
return ..()
-/mob/dead/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+/mob/dead/CanPass(atom/movable/mover, turf/target, height=0)
return 1
@@ -169,7 +169,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
else
var/response
var/alertmsg = "Are you -sure- you want to ghost?\n([warningmsg]. If you ghost now, you probably won't be able to rejoin the round! You can't change your mind, so choose wisely!)"
- response = alert(src, alertmsg,"Are you sure you want to ghost?","Ghost","Stay in body")
+ response = alert(src, alertmsg,"Are you sure you want to ghost?","Stay in body","Ghost")
if(response != "Ghost")
return //didn't want to ghost after-all
resting = 1
@@ -308,7 +308,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set name = "Toggle AntagHUD"
set desc = "Toggles AntagHUD allowing you to see who is the antagonist"
if(!config.antag_hud_allowed && !client.holder)
- to_chat(src, "\red Admins have disabled this for this round.")
+ to_chat(src, "Admins have disabled this for this round.")
return
if(!client)
return
@@ -462,11 +462,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/memory()
set hidden = 1
- to_chat(src, "\red You are dead! You have no mind to store memory!")
+ to_chat(src, "You are dead! You have no mind to store memory!")
/mob/dead/observer/add_memory()
set hidden = 1
- to_chat(src, "\red You are dead! You have no mind to store memory!")
+ to_chat(src, "You are dead! You have no mind to store memory!")
/mob/dead/observer/verb/analyze_air()
set name = "Analyze Air"
@@ -485,9 +485,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
to_chat(src, "Results:")
if(abs(pressure - ONE_ATMOSPHERE) < 10)
- to_chat(src, "\blue Pressure: [round(pressure,0.1)] kPa")
+ to_chat(src, "Pressure: [round(pressure,0.1)] kPa")
else
- to_chat(src, "\red Pressure: [round(pressure,0.1)] kPa")
+ to_chat(src, "Pressure: [round(pressure,0.1)] kPa")
if(total_moles)
var/o2_concentration = environment.oxygen/total_moles
var/n2_concentration = environment.nitrogen/total_moles
@@ -496,28 +496,28 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/unknown_concentration = 1-(o2_concentration+n2_concentration+co2_concentration+plasma_concentration)
if(abs(n2_concentration - N2STANDARD) < 20)
- to_chat(src, "\blue Nitrogen: [round(n2_concentration*100)]% ([round(environment.nitrogen,0.01)] moles)")
+ to_chat(src, "Nitrogen: [round(n2_concentration*100)]% ([round(environment.nitrogen,0.01)] moles)")
else
- to_chat(src, "\red Nitrogen: [round(n2_concentration*100)]% ([round(environment.nitrogen,0.01)] moles)")
+ to_chat(src, "Nitrogen: [round(n2_concentration*100)]% ([round(environment.nitrogen,0.01)] moles)")
if(abs(o2_concentration - O2STANDARD) < 2)
- to_chat(src, "\blue Oxygen: [round(o2_concentration*100)]% ([round(environment.oxygen,0.01)] moles)")
+ to_chat(src, "Oxygen: [round(o2_concentration*100)]% ([round(environment.oxygen,0.01)] moles)")
else
- to_chat(src, "\red Oxygen: [round(o2_concentration*100)]% ([round(environment.oxygen,0.01)] moles)")
+ to_chat(src, "Oxygen: [round(o2_concentration*100)]% ([round(environment.oxygen,0.01)] moles)")
if(co2_concentration > 0.01)
- to_chat(src, "\red CO2: [round(co2_concentration*100)]% ([round(environment.carbon_dioxide,0.01)] moles)")
+ to_chat(src, "CO2: [round(co2_concentration*100)]% ([round(environment.carbon_dioxide,0.01)] moles)")
else
- to_chat(src, "\blue CO2: [round(co2_concentration*100)]% ([round(environment.carbon_dioxide,0.01)] moles)")
+ to_chat(src, "CO2: [round(co2_concentration*100)]% ([round(environment.carbon_dioxide,0.01)] moles)")
if(plasma_concentration > 0.01)
- to_chat(src, "\red Plasma: [round(plasma_concentration*100)]% ([round(environment.toxins,0.01)] moles)")
+ to_chat(src, "Plasma: [round(plasma_concentration*100)]% ([round(environment.toxins,0.01)] moles)")
if(unknown_concentration > 0.01)
- to_chat(src, "\red Unknown: [round(unknown_concentration*100)]% ([round(unknown_concentration*total_moles,0.01)] moles)")
+ to_chat(src, "Unknown: [round(unknown_concentration*100)]% ([round(unknown_concentration*total_moles,0.01)] moles)")
- to_chat(src, "\blue Temperature: [round(environment.temperature-T0C,0.1)]°C")
- to_chat(src, "\blue Heat Capacity: [round(environment.heat_capacity(),0.1)]")
+ to_chat(src, "Temperature: [round(environment.temperature-T0C,0.1)]°C")
+ to_chat(src, "Heat Capacity: [round(environment.heat_capacity(),0.1)]")
/mob/dead/observer/verb/view_manifest()
set name = "View Crew Manifest"
@@ -657,6 +657,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return TRUE
return FALSE
+
+/mob/dead/observer/incapacitated()
+ return TRUE
//this is a mob verb instead of atom for performance reasons
//see /mob/verb/examinate() in mob.dm for more info
diff --git a/code/modules/mob/dead/observer/say.dm b/code/modules/mob/dead/observer/say.dm
index fb5b7735633..82e8c620192 100644
--- a/code/modules/mob/dead/observer/say.dm
+++ b/code/modules/mob/dead/observer/say.dm
@@ -8,7 +8,7 @@
if(src.client)
if(src.client.prefs.muted & MUTE_DEADCHAT)
- to_chat(src, "\red You cannot talk in deadchat (muted).")
+ to_chat(src, "You cannot talk in deadchat (muted).")
return
if(src.client.handle_spam_prevention(message,MUTE_DEADCHAT))
@@ -30,10 +30,19 @@
if(src.client)
if(src.client.prefs.muted & MUTE_DEADCHAT)
- to_chat(src, "\red You cannot emote in deadchat (muted).")
+ to_chat(src, "You cannot emote in deadchat (muted).")
return
if(src.client.handle_spam_prevention(message, MUTE_DEADCHAT))
return
. = src.emote_dead(message)
+
+/mob/dead/observer/handle_track(var/message, var/verb = "says", var/datum/language/language, var/mob/speaker = null, var/speaker_name, var/atom/follow_target, var/hard_to_hear)
+ return "[speaker_name] ([ghost_follow_link(follow_target, ghost=src)])"
+
+/mob/dead/observer/handle_speaker_name(var/mob/speaker = null, var/vname, var/hard_to_hear)
+ var/speaker_name = ..()
+ if(speaker && (speaker_name != speaker.real_name) && !isAI(speaker)) //Announce computer and various stuff that broadcasts doesn't use it's real name but AI's can't pretend to be other mobs.
+ speaker_name = "[speaker.real_name] ([speaker_name])"
+ return speaker_name
\ No newline at end of file
diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm
index be6fa4a6c39..4a340c1bb24 100644
--- a/code/modules/mob/emote.dm
+++ b/code/modules/mob/emote.dm
@@ -13,6 +13,16 @@
return 0 // Proceed with emote
//--FalseIncarnate
+/mob/proc/handle_emote_param(var/target, var/not_self, var/vicinity, var/return_mob) //Only returns not null if the target param is valid.
+ var/view_vicinity = vicinity ? vicinity : null //not_self means we'll only return if target is valid and not us
+ if(target) //vicinity is the distance passed to the view proc.
+ for(var/mob/A in view(view_vicinity, null)) //if set, return_mob will cause this proc to return the mob instead of just its name if the target is valid.
+ if(target == A.name && (!not_self || (not_self && target != name)))
+ if(return_mob)
+ return A
+ else
+ return target
+
// All mobs should have custom emote, really..
/mob/proc/custom_emote(var/m_type=1,var/message = null)
@@ -86,16 +96,16 @@
/mob/proc/emote_dead(var/message)
if(client.prefs.muted & MUTE_DEADCHAT)
- to_chat(src, "\red You cannot send deadchat emotes (muted).")
+ to_chat(src, "You cannot send deadchat emotes (muted).")
return
if(!(client.prefs.toggles & CHAT_DEAD))
- to_chat(src, "\red You have deadchat muted.")
+ to_chat(src, "You have deadchat muted.")
return
if(!src.client.holder)
if(!config.dsay_allowed)
- to_chat(src, "\red Deadchat is globally muted")
+ to_chat(src, "Deadchat is globally muted")
return
diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm
index f158534475e..568033f3606 100644
--- a/code/modules/mob/hear_say.dm
+++ b/code/modules/mob/hear_say.dm
@@ -117,65 +117,8 @@
if(hard_to_hear)
message = stars(message)
- var/speaker_name = "unknown"
- if(speaker)
- speaker_name = speaker.name
-
- if(vname)
- speaker_name = vname
- if(hard_to_hear)
- speaker_name = "unknown"
-
- var/changed_voice
-
- if(isAI(src) && !hard_to_hear)
- var/jobname // the mob's "job"
- var/mob/living/carbon/human/impersonating //The crewmember being impersonated, if any.
-
- if(ishuman(speaker))
- var/mob/living/carbon/human/H = speaker
-
- var/obj/item/weapon/card/id/id = H.wear_id
- if((istype(id) && id.is_untrackable()) && H.HasVoiceChanger())
- changed_voice = 1
- var/mob/living/carbon/human/I = locate(speaker_name)
- if(I)
- impersonating = I
- jobname = impersonating.get_assignment()
- else
- jobname = "Unknown"
- else
- jobname = H.get_assignment()
-
- else if(iscarbon(speaker)) // Nonhuman carbon mob
- jobname = "No ID"
- else if(isAI(speaker))
- jobname = "AI"
- else if(isrobot(speaker))
- jobname = "Cyborg"
- else if(ispAI(speaker))
- jobname = "Personal AI"
- else if(isAutoAnnouncer(speaker))
- var/mob/living/automatedannouncer/AA = speaker
- jobname = AA.role
- else
- jobname = "Unknown"
-
- if(changed_voice)
- if(impersonating)
- track = "[speaker_name] ([jobname])"
- else
- track = "[speaker_name] ([jobname])"
- else
- if(istype(follow_target, /mob/living/simple_animal/bot))
- track = "[speaker_name] ([jobname])"
- else
- track = "[speaker_name] ([jobname])"
-
- if(isobserver(src))
- if(speaker && (speaker_name != speaker.real_name) && !isAI(speaker)) //Announce computer and various stuff that broadcasts doesn't use it's real name but AI's can't pretend to be other mobs.
- speaker_name = "[speaker.real_name] ([speaker_name])"
- track = "[speaker_name] ([ghost_follow_link(follow_target, ghost=src)])"
+ var/speaker_name = handle_speaker_name(speaker, vname, hard_to_hear)
+ track = handle_track(message, verb, language, speaker, speaker_name, follow_target, hard_to_hear)
var/formatted
if(language)
@@ -190,6 +133,22 @@
else
to_chat(src, "[part_a][speaker_name][part_b][formatted]")
+/mob/proc/handle_speaker_name(var/mob/speaker = null, var/vname, var/hard_to_hear)
+ var/speaker_name = "unknown"
+ if(speaker)
+ speaker_name = speaker.name
+
+ if(vname)
+ speaker_name = vname
+
+ if(hard_to_hear)
+ speaker_name = "unknown"
+
+ return speaker_name
+
+/mob/proc/handle_track(var/message, var/verb = "says", var/datum/language/language, var/mob/speaker = null, var/speaker_name, var/atom/follow_target, var/hard_to_hear)
+ return
+
/mob/proc/hear_signlang(var/message, var/verb = "gestures", var/datum/language/language, var/mob/speaker = null)
if(!client)
return
diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm
index 2b495f02062..61bd133efef 100644
--- a/code/modules/mob/language.dm
+++ b/code/modules/mob/language.dm
@@ -494,11 +494,10 @@
ask_verb = "sings"
exclaim_verb = "sings"
colour = "alien"
- key = "x"
+ key = "bo"
flags = RESTRICTED | HIVEMIND
/datum/language/corticalborer/broadcast(mob/living/speaker, message, speaker_mask)
-
var/mob/living/simple_animal/borer/B
if(iscarbon(speaker))
diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm
index ca520ba9289..b5fa736dfc3 100644
--- a/code/modules/mob/living/carbon/alien/alien.dm
+++ b/code/modules/mob/living/carbon/alien/alien.dm
@@ -220,7 +220,7 @@
threatcount += 4
//Mindshield implants imply trustworthyness
- if(isloyal(src))
+ if(ismindshielded(src))
threatcount -= 1
return threatcount
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
index 2644ef8a306..8d8f8894234 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
@@ -73,7 +73,7 @@
if(powerc(250))
adjustToxLoss(-250)
- to_chat(src, "\green You begin to evolve!")
+ to_chat(src, "You begin to evolve!")
for(var/mob/O in viewers(src, null))
O.show_message(text("[src] begins to twist and contort!"), 1)
var/mob/living/carbon/alien/humanoid/sentinel/praetorian/new_xeno = new(loc)
diff --git a/code/modules/mob/living/carbon/alien/humanoid/empress.dm b/code/modules/mob/living/carbon/alien/humanoid/empress.dm
index d50befa47f0..287974b610f 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/empress.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/empress.dm
@@ -85,6 +85,6 @@
if(powerc(250,1))//Can't plant eggs on spess tiles. That's silly.
adjustPlasma(-250)
for(var/mob/O in viewers(src, null))
- O.show_message(text("\green [src] has laid an egg!"), 1)
+ O.show_message(text("[src] has laid an egg!"), 1)
new /obj/structure/alien/egg(loc)
return
diff --git a/code/modules/mob/living/carbon/alien/larva/emote.dm b/code/modules/mob/living/carbon/alien/larva/emote.dm
index 01d834b07cf..d3140e4a969 100644
--- a/code/modules/mob/living/carbon/alien/larva/emote.dm
+++ b/code/modules/mob/living/carbon/alien/larva/emote.dm
@@ -15,7 +15,7 @@
return
if(src.client)
if(client.prefs.muted & MUTE_IC)
- to_chat(src, "\red You cannot send IC messages (muted).")
+ to_chat(src, "You cannot send IC messages (muted).")
return
if(src.client.handle_spam_prevention(message,MUTE_IC))
return
diff --git a/code/modules/mob/living/carbon/alien/larva/powers.dm b/code/modules/mob/living/carbon/alien/larva/powers.dm
index c02c141c456..b3df2879f8f 100644
--- a/code/modules/mob/living/carbon/alien/larva/powers.dm
+++ b/code/modules/mob/living/carbon/alien/larva/powers.dm
@@ -15,7 +15,7 @@
to_chat(O, text("[] scurries to the ground!", src))
else
layer = MOB_LAYER
- to_chat(src, text("\green You have stopped hiding."))
+ to_chat(src, text("You have stopped hiding."))
for(var/mob/O in oviewers(src, null))
if((O.client && !( O.blinded )))
to_chat(O, text("[] slowly peaks up from the ground...", src))
@@ -29,15 +29,15 @@
return
if(handcuffed || legcuffed)
- to_chat(src, "\red You cannot evolve when you are cuffed.")
+ to_chat(src, "You cannot evolve when you are cuffed.")
if(amount_grown >= max_grown) //TODO ~Carn
//green is impossible to read, so i made these blue and changed the formatting slightly
to_chat(src, "You are growing into a beautiful alien! It is time to choose a caste.")
- to_chat(src, "\blue There are three to choose from:")
- to_chat(src, "Hunters \blue are strong and agile, able to hunt away from the hive and rapidly move through ventilation shafts. Hunters generate plasma slowly and have low reserves.")
- to_chat(src, "Sentinels \blue are tasked with protecting the hive and are deadly up close and at a range. They are not as physically imposing nor fast as the hunters.")
- to_chat(src, "Drones \blue are the working class, offering the largest plasma storage and generation. They are the only caste which may evolve again, turning into the dreaded alien queen.")
+ to_chat(src, "There are three to choose from:")
+ to_chat(src, "Huntersare strong and agile, able to hunt away from the hive and rapidly move through ventilation shafts. Hunters generate plasma slowly and have low reserves.")
+ to_chat(src, "Sentinelsare tasked with protecting the hive and are deadly up close and at a range. They are not as physically imposing nor fast as the hunters.")
+ to_chat(src, "Dronesare the working class, offering the largest plasma storage and generation. They are the only caste which may evolve again, turning into the dreaded alien queen.")
var/alien_caste = alert(src, "Please choose which alien caste you shall belong to.",,"Hunter","Sentinel","Drone")
var/mob/living/carbon/alien/humanoid/new_xeno
diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm
index 6ea16fc24a1..98d1bec775c 100644
--- a/code/modules/mob/living/carbon/alien/special/facehugger.dm
+++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm
@@ -17,7 +17,8 @@ var/const/MAX_ACTIVE_TIME = 400
w_class = 1 //note: can be picked up by aliens unlike most other items of w_class below 4
throw_range = 5
tint = 3
- flags = MASKCOVERSMOUTH | MASKCOVERSEYES | AIRTIGHT
+ flags = AIRTIGHT
+ flags_cover = MASKCOVERSMOUTH | MASKCOVERSEYES
layer = MOB_LAYER
var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case
@@ -126,7 +127,7 @@ var/const/MAX_ACTIVE_TIME = 400
"[src] leaps at [M]'s face!")
if(ishuman(M))
var/mob/living/carbon/human/H = M
- if(H.head && H.head.flags & HEADCOVERSMOUTH)
+ if(H.head && H.head.flags_cover & HEADCOVERSMOUTH)
H.visible_message("[src] smashes against [H]'s [H.head]!", \
"[src] smashes against [H]'s [H.head]!")
Die()
@@ -236,7 +237,7 @@ var/const/MAX_ACTIVE_TIME = 400
var/mob/living/carbon/C = M
if(ishuman(C))
var/mob/living/carbon/human/H = C
- if(H.head && H.head.flags & HEADCOVERSMOUTH)
+ if(H.head && H.head.flags_cover & HEADCOVERSMOUTH)
return 0
return 1
return 0
diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm
index f495e5b7f75..15c52d2693c 100644
--- a/code/modules/mob/living/carbon/brain/MMI.dm
+++ b/code/modules/mob/living/carbon/brain/MMI.dm
@@ -167,12 +167,8 @@
if(isrobot(loc))
var/mob/living/silicon/robot/borg = loc
borg.mmi = null
- if(brainmob)
- qdel(brainmob)
- brainmob = null
- if(held_brain)
- qdel(held_brain)
- held_brain = null
+ QDEL_NULL(brainmob)
+ QDEL_NULL(held_brain)
return ..()
/obj/item/device/mmi/syndie
diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm
index e8afbb0360b..655ad111cf1 100644
--- a/code/modules/mob/living/carbon/brain/brain.dm
+++ b/code/modules/mob/living/carbon/brain/brain.dm
@@ -82,6 +82,17 @@ I'm using this for Stat to give it a more nifty interface to work with
/mob/living/carbon/brain/proc/has_synthetic_assistance()
return (container && istype(container, /obj/item/device/mmi)) || in_contents_of(/obj/mecha)
+/mob/living/carbon/brain/proc/get_race()
+ if(container)
+ var/obj/item/device/mmi/M = container
+ if(istype(M) && M.held_brain)
+ return M.held_brain.dna.get_species_name()
+ else
+ return "Artificial Life"
+ if(istype(loc, /obj/item/organ/internal/brain))
+ var/obj/item/organ/internal/brain/B = loc
+ return B.dna.get_species_name()
+
/mob/living/carbon/brain/Stat()
..()
if(has_synthetic_assistance())
diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm
index 064605001dd..56a98142f80 100644
--- a/code/modules/mob/living/carbon/brain/brain_item.dm
+++ b/code/modules/mob/living/carbon/brain/brain_item.dm
@@ -73,7 +73,7 @@
var/mob/living/simple_animal/borer/borer = owner.has_brain_worms()
if(borer)
- borer.detatch() //Should remove borer if the brain is removed - RR
+ borer.detach() //Should remove borer if the brain is removed - RR
if(owner.mind && !non_primary)//don't transfer if the owner does not have a mind.
B.transfer_identity(user)
@@ -123,7 +123,5 @@
icon_state = "scroll"
/obj/item/organ/internal/brain/Destroy() //copypasted from MMIs.
- if(brainmob)
- qdel(brainmob)
- brainmob = null
+ QDEL_NULL(brainmob)
return ..()
diff --git a/code/modules/mob/living/carbon/brain/death.dm b/code/modules/mob/living/carbon/brain/death.dm
index 255f3c03897..d6a07d48f7e 100644
--- a/code/modules/mob/living/carbon/brain/death.dm
+++ b/code/modules/mob/living/carbon/brain/death.dm
@@ -2,7 +2,7 @@
if(stat == DEAD) return
if(!gibbed && container && istype(container, /obj/item/device/mmi))//If not gibbed but in a container.
for(var/mob/O in viewers(container, null))
- O.show_message(text("[]'s MMI flatlines!", src), 1, "\red You hear something flatline.", 2)
+ O.show_message(text("[]'s MMI flatlines!", src), 1, "You hear something flatline.", 2)
container.icon_state = "mmi_dead"
stat = DEAD
diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm
index 4e2c7acb2b2..565dd250fd8 100644
--- a/code/modules/mob/living/carbon/brain/posibrain.dm
+++ b/code/modules/mob/living/carbon/brain/posibrain.dm
@@ -98,7 +98,7 @@
var/turf/T = get_turf_or_move(src.loc)
for(var/mob/M in viewers(T))
- M.show_message("\blue The positronic brain chimes quietly.")
+ M.show_message("The positronic brain chimes quietly.")
icon_state = "posibrain-occupied"
/obj/item/device/mmi/posibrain/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer.
@@ -109,7 +109,7 @@
var/turf/T = get_turf_or_move(src.loc)
for(var/mob/M in viewers(T))
- M.show_message("\blue The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?")
+ M.show_message("The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?")
/obj/item/device/mmi/posibrain/Topic(href,href_list)
if("signup" in href_list)
@@ -122,22 +122,22 @@
to_chat(O, "Not looking for a ghost, yet.")
return
if(!istype(O))
- to_chat(O, "\red Error.")
+ to_chat(O, "Error.")
return
if(O in ghost_volunteers)
- to_chat(O, "\blue Removed from registration list.")
+ to_chat(O, "Removed from registration list.")
ghost_volunteers.Remove(O)
return
if(!check_observer(O))
- to_chat(O, "\red You cannot be \a [src].")
+ to_chat(O, "You cannot be \a [src].")
return
if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
- to_chat(O, "\red Upon using the antagHUD you forfeited the ability to join the round.")
+ to_chat(O, "Upon using the antagHUD you forfeited the ability to join the round.")
return
if(jobban_isbanned(O, "Cyborg") || jobban_isbanned(O,"nonhumandept"))
- to_chat(O, "\red You are job banned from this role.")
+ to_chat(O, "You are job banned from this role.")
return
- to_chat(O., "\blue You've been added to the list of ghosts that may become this [src]. Click again to unvolunteer.")
+ to_chat(O., "You've been added to the list of ghosts that may become this [src]. Click again to unvolunteer.")
ghost_volunteers.Add(O)
@@ -196,7 +196,7 @@
playsound(get_turf(src), 'sound/items/posiping.ogg', 80, 0)
var/turf/T = get_turf_or_move(src.loc)
for(var/mob/M in viewers(T))
- M.show_message("\blue The positronic brain pings softly.")
+ M.show_message("The positronic brain pings softly.")
/obj/item/device/mmi/posibrain/ipc
desc = "A cube of shining metal, four inches to a side and covered in shallow grooves. The speaker switch is set to 'off'."
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 0756ba600ba..93f2d4aeb35 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -56,7 +56,7 @@
last_stomach_attack = world.time
for(var/mob/M in hearers(4, src))
if(M.client)
- M.show_message(text("\red You hear something rumbling inside [src]'s stomach..."), 2)
+ M.show_message(text("You hear something rumbling inside [src]'s stomach..."), 2)
var/obj/item/I = user.get_active_hand()
if(I && I.force)
@@ -76,7 +76,7 @@
for(var/mob/M in viewers(user, null))
if(M.client)
- M.show_message(text("\red [user] attacks [src]'s stomach wall with the [I.name]!"), 2)
+ M.show_message(text("[user] attacks [src]'s stomach wall with the [I.name]!"), 2)
playsound(user.loc, 'sound/effects/attackblob.ogg', 50, 1)
if(prob(src.getBruteLoss() - 50))
@@ -143,16 +143,14 @@
return 0
if(NO_SHOCK in mutations) //shockproof
return 0
-
+ if(tesla_shock && tesla_ignore)
+ return FALSE
shock_damage *= siemens_coeff
if(shock_damage<1 && !override)
return 0
if(reagents.has_reagent("teslium"))
shock_damage *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging!
- take_overall_damage(0,shock_damage)
- //src.burn_skin(shock_damage)
- //src.adjustFireLoss(shock_damage) //burn_skin will do this for us
- //src.updatehealth()
+ take_overall_damage(0,shock_damage, used_weapon = "Electrocution")
visible_message(
"[src] was shocked by \the [source]!", \
"You feel a powerful shock coursing through your body!", \
@@ -217,8 +215,8 @@
if(src == M && istype(src, /mob/living/carbon/human))
var/mob/living/carbon/human/H = src
src.visible_message( \
- text("\blue [src] examines [].",src.gender==MALE?"himself":"herself"), \
- "\blue You check yourself for injuries." \
+ text("[src] examines [].",src.gender==MALE?"himself":"herself"), \
+ "You check yourself for injuries." \
)
for(var/obj/item/organ/external/org in H.organs)
@@ -247,7 +245,7 @@
status = "weirdly shapen."
if(status == "")
status = "OK"
- src.show_message(text("\t []My [] is [].",status=="OK"?"\blue ":"\red ",org.name,status),1)
+ src.show_message(text("\t []My [] is [].",status=="OK"?"":"",org.name,status),1)
if(staminaloss)
if(staminaloss > 30)
to_chat(src, "You're completely exhausted.")
@@ -936,7 +934,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
/mob/living/carbon/proc/can_eat(flags = 255)
return 1
-/mob/living/carbon/proc/eat(var/obj/item/weapon/reagent_containers/food/toEat, mob/user)
+/mob/living/carbon/proc/eat(var/obj/item/weapon/reagent_containers/food/toEat, mob/user, var/bitesize_override)
if(!istype(toEat))
return 0
var/fullness = nutrition + 10
@@ -953,7 +951,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
else
if(!forceFed(toEat, user, fullness))
return 0
- consume(toEat)
+ consume(toEat, bitesize_override)
score_foodeaten++
return 1
@@ -1006,7 +1004,8 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
/*TO DO - If/when stomach organs are introduced, override this at the human level sending the item to the stomach
so that different stomachs can handle things in different ways VB*/
-/mob/living/carbon/proc/consume(var/obj/item/weapon/reagent_containers/food/toEat)
+/mob/living/carbon/proc/consume(var/obj/item/weapon/reagent_containers/food/toEat, var/bitesize_override)
+ var/this_bite = bitesize_override ? bitesize_override : toEat.bitesize
if(!toEat.reagents)
return
if(satiety > -200)
@@ -1014,9 +1013,9 @@ so that different stomachs can handle things in different ways VB*/
if(toEat.consume_sound)
playsound(loc, toEat.consume_sound, rand(10,50), 1)
if(toEat.reagents.total_volume)
- var/fraction = min(toEat.bitesize/toEat.reagents.total_volume, 1)
+ var/fraction = min(this_bite/toEat.reagents.total_volume, 1)
toEat.reagents.reaction(src, toEat.apply_type, fraction)
- toEat.reagents.trans_to(src, toEat.bitesize*toEat.transfer_efficiency)
+ toEat.reagents.trans_to(src, this_bite*toEat.transfer_efficiency)
/mob/living/carbon/get_access()
. = ..()
diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm
index ad1ab28c435..3cedf2d1f3f 100644
--- a/code/modules/mob/living/carbon/human/appearance.dm
+++ b/code/modules/mob/living/carbon/human/appearance.dm
@@ -16,7 +16,7 @@
/mob/living/carbon/human/proc/change_gender(var/new_gender, var/update_dna = 1)
var/obj/item/organ/external/head/H = organs_by_name["head"]
- if(gender == new_gender)
+ if(gender == new_gender || (gender == PLURAL && species.has_gender))
return
gender = new_gender
@@ -488,4 +488,4 @@
valid_alt_heads += alternate_head
- return valid_alt_heads
\ No newline at end of file
+ return valid_alt_heads
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index 89c35870cad..2300f25768e 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -114,7 +114,7 @@
B = I
if(B)
if(B.controlling && B.host == src)
- B.detatch()
+ B.detach()
verbs -= /mob/living/carbon/proc/release_control
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index ac1d98e848f..e88468e2018 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -53,6 +53,19 @@
if(!found_slime_bodypart) //Everyone else fails, skip the emote attempt
return
+
+ if("clack", "clacks")
+ if(species.name == "Kidan") //Only Kidan can clack and rightfully so.
+ on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm'
+ else //Everyone else fails, skip the emote attempt
+ return
+
+ if("click", "clicks")
+ if(species.name == "Kidan") //Only Kidan can click and rightfully so.
+ on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm'
+ else //Everyone else fails, skip the emote attempt
+ return
+
if("scream", "screams")
on_CD = handle_emote_CD(50) //longer cooldown
if("fart", "farts", "flip", "flips", "snap", "snaps")
@@ -72,128 +85,73 @@
if("me") //OKAY SO RANT TIME, THIS FUCKING HAS TO BE HERE OR A SHITLOAD OF THINGS BREAK
return custom_emote(m_type, message) //DO YOU KNOW WHY SHIT BREAKS? BECAUSE SO MUCH OLDCODE CALLS mob.emote("me",1,"whatever_the_fuck_it_wants_to_emote")
//WHO THE FUCK THOUGHT THAT WAS A GOOD FUCKING IDEA!?!?
-
if("ping", "pings")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param) //Check to see if the param is valid (mob with the param name is in view).
- if(param)
- message = "[src] pings at [param]."
- else
- message = "[src] pings."
+ message = "[src] pings[M ? " at [M]" : ""]."
playsound(loc, 'sound/machines/ping.ogg', 50, 0)
m_type = 2
if("buzz2")
- message = "[src] emits an irritated buzzing sound."
+ var/M = handle_emote_param(param)
+
+ message = "[src] emits an irritated buzzing sound[M ? " at [M]" : ""]."
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
m_type = 2
if("buzz", "buzzes")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] buzzes at [param]."
- else
- message = "[src] buzzes."
+ message = "[src] buzzes[M ? " at [M]" : ""]."
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
m_type = 2
if("beep", "beeps")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] beeps at [param]."
- else
- message = "[src] beeps."
+ message = "[src] beeps[M ? " at [M]" : ""]."
playsound(loc, 'sound/machines/twobeep.ogg', 50, 0)
m_type = 2
if("drone", "drones", "hum", "hums", "rumble", "rumbles")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] drones at [param]."
- else
- message = "[src] rumbles."
+ message = "[src] [M ? "drones at [M]" : "rumbles"]."
playsound(loc, 'sound/voice/DraskTalk.ogg', 50, 0)
m_type = 2
if("squish", "squishes")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] squishes at [param]."
- else
- message = "[src] squishes."
+ message = "[src] squishes[M ? " at [M]" : ""]."
playsound(loc, 'sound/effects/slime_squish.ogg', 50, 0) //Credit to DrMinky (freesound.org) for the sound.
m_type = 2
- if("yes")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ if("clack", "clacks")
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] emits an affirmative blip at [param]."
- else
- message = "[src] emits an affirmative blip."
+ message = "[src] clacks their mandibles[M ? " at [M]" : ""]."
+ playsound(loc, 'sound/effects/Kidanclack.ogg', 50, 0) //Credit to DrMinky (freesound.org) for the sound.
+ m_type = 2
+
+ if("click", "clicks")
+ var/M = handle_emote_param(param)
+
+ message = "[src] clicks their mandibles[M ? " at [M]" : ""]."
+ playsound(loc, 'sound/effects/Kidanclack2.ogg', 50, 0) //Credit to DrMinky (freesound.org) for the sound.
+ m_type = 2
+
+ if("yes")
+ var/M = handle_emote_param(param)
+
+ message = "[src] emits an affirmative blip[M ? " at [M]" : ""]."
playsound(loc, 'sound/machines/synth_yes.ogg', 50, 0)
m_type = 2
if("no")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] emits a negative blip at [param]."
- else
- message = "[src] emits a negative blip."
+ message = "[src] emits a negative blip[M ? " at [M]" : ""]."
playsound(loc, 'sound/machines/synth_no.ogg', 50, 0)
m_type = 2
@@ -225,12 +183,12 @@
if(!restrained())
message = "[src] is strumming the air and headbanging like a safari chimp."
m_type = 1
-
+
if("dance")
if(!restrained())
message = "[src] dances around happily."
m_type = 1
-
+
if("jump")
if(!restrained())
message = "[src] jumps!"
@@ -246,36 +204,16 @@
if("bow", "bows")
if(!buckled)
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] bows to [param]."
- else
- message = "[src] bows."
+ message = "[src] bows[M ? " to [M]" : ""]."
m_type = 1
if("salute", "salutes")
if(!buckled)
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] salutes to [param]."
- else
- message = "[src] salutes."
+ message = "[src] salutes[M ? " to [M]" : ""]."
m_type = 1
if("choke", "chokes")
@@ -414,11 +352,15 @@
m_type = 2
if("frown", "frowns")
- message = "[src] frowns."
+ var/M = handle_emote_param(param)
+
+ message = "[src] frowns[M ? " at [M]" : ""]."
m_type = 1
if("nod", "nods")
- message = "[src] nods."
+ var/M = handle_emote_param(param)
+
+ message = "[src] nods[M ? " at [M]" : ""]."
m_type = 1
if("blush", "blushes")
@@ -426,7 +368,9 @@
m_type = 1
if("wave", "waves")
- message = "[src] waves."
+ var/M = handle_emote_param(param)
+
+ message = "[src] waves[M ? " at [M]" : ""]."
m_type = 1
if("quiver", "quivers")
@@ -462,56 +406,27 @@
m_type = 2
if("glare", "glares")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] glares at [param]."
- else
- message = "[src] glares."
+ message = "[src] glares[M ? " at [M]" : ""]."
m_type = 1
if("stare", "stares")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] stares at [param]."
- else
- message = "[src] stares."
+ message = "[src] stares[M ? " at [M]" : ""]."
m_type = 1
if("look", "looks")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
+ var/M = handle_emote_param(param)
- if(!M)
- param = null
-
- if(param)
- message = "[src] looks at [param]."
- else
- message = "[src] looks."
+ message = "[src] looks[M ? " at [M]" : ""]."
m_type = 1
if("grin", "grins")
- message = "[src] grins."
+ var/M = handle_emote_param(param)
+
+ message = "[src] grins[M ? " at [M]" : ""]."
m_type = 1
if("cry", "cries")
@@ -527,24 +442,26 @@
m_type = 2
if("sigh", "sighs")
+ var/M = handle_emote_param(param)
if(miming)
- message = "[src] sighs."
+ message = "[src] sighs[M ? " at [M]" : ""]."
m_type = 1
else
if(!muzzled)
- message = "[src] sighs."
+ message = "[src] sighs[M ? " at [M]" : ""]."
m_type = 2
else
- message = "[src] makes a weak noise."
+ message = "[src] makes a weak noise"
m_type = 2
if("laugh", "laughs")
+ var/M = handle_emote_param(param)
if(miming)
- message = "[src] acts out a laugh."
+ message = "[src] acts out a laugh[M ? " at [M]" : ""]."
m_type = 1
else
if(!muzzled)
- message = "[src] laughs."
+ message = "[src] laughs[M ? " at [M]" : ""]."
m_type = 2
else
message = "[src] makes a noise."
@@ -557,11 +474,12 @@
m_type = 1
if("grumble", "grumbles")
+ var/M = handle_emote_param(param)
if(miming)
- message = "[src] grumbles!"
+ message = "[src] grumbles[M ? " at [M]" : ""]!"
m_type = 1
if(!muzzled)
- message = "[src] grumbles!"
+ message = "[src] grumbles[M ? " at [M]" : ""]!"
m_type = 2
else
message = "[src] makes a noise."
@@ -622,7 +540,9 @@
m_type = 1
if("shake", "shakes")
- message = "[src] shakes \his head."
+ var/M = handle_emote_param(param, 1) //Check to see if the param is valid (mob with the param name is in view) but exclude ourselves.
+
+ message = "[src] shakes \his head[M ? " at [M]" : ""]."
m_type = 1
if("shrug", "shrugs")
@@ -640,7 +560,9 @@
m_type = 1
if("smile", "smiles")
- message = "[src] smiles."
+ var/M = handle_emote_param(param, 1)
+
+ message = "[src] smiles[M ? " at [M]" : ""]."
m_type = 1
if("shiver", "shivers")
@@ -704,7 +626,9 @@
m_type = 2
if("wink", "winks")
- message = "[src] winks."
+ var/M = handle_emote_param(param, 1)
+
+ message = "[src] winks[M ? " at [M]" : ""]."
m_type = 1
if("yawn", "yawns")
@@ -724,14 +648,7 @@
if("hug", "hugs")
m_type = 1
if(!restrained())
- var/M = null
- if(param)
- for(var/mob/A in view(1, null))
- if(param == A.name)
- M = A
- break
- if(M == src)
- M = null
+ var/M = handle_emote_param(param, 1, 1) //Check to see if the param is valid (mob with the param name is in view) but exclude ourselves and only check mobs in our immediate vicinity (1 tile distance).
if(M)
message = "[src] hugs [M]."
@@ -741,14 +658,7 @@
if("handshake")
m_type = 1
if(!restrained() && !r_hand)
- var/mob/M = null
- if(param)
- for(var/mob/A in view(1, null))
- if(param == A.name)
- M = A
- break
- if(M == src)
- M = null
+ var/mob/M = handle_emote_param(param, 1, 1, 1) //Check to see if the param is valid (mob with the param name is in view) but exclude ourselves, only check mobs in our immediate vicinity (1 tile distance) and return the whole mob instead of just its name.
if(M)
if(M.canmove && !M.r_hand && !M.restrained())
@@ -759,12 +669,8 @@
if("dap", "daps")
m_type = 1
if(!restrained())
- var/M = null
- if(param)
- for(var/mob/A in view(1, null))
- if(param == A.name)
- M = A
- break
+ var/M = handle_emote_param(param, null, 1)
+
if(M)
message = "[src] gives daps to [M]."
else
@@ -773,27 +679,23 @@
if("slap", "slaps")
m_type = 1
if(!restrained())
- var/M = null
- if(param)
- for(var/mob/A in view(1, null))
- if(param == A.name)
- M = A
- break
+ var/M = handle_emote_param(param, null, 1)
+
if(M)
message = "[src] slaps [M] across the face. Ouch!"
- playsound(loc, 'sound/effects/snap.ogg', 50, 1)
else
message = "[src] slaps \himself!"
- playsound(loc, 'sound/effects/snap.ogg', 50, 1)
adjustFireLoss(4)
+ playsound(loc, 'sound/effects/snap.ogg', 50, 1)
if("scream", "screams")
+ var/M = handle_emote_param(param)
if(miming)
- message = "[src] acts out a scream!"
+ message = "[src] acts out a scream[M ? " at [M]" : ""]!"
m_type = 1
else
if(!muzzled)
- message = "[src] [species.scream_verb]!"
+ message = "[src] [species.scream_verb][M ? " at [M]" : ""]!"
m_type = 2
if(gender == FEMALE)
playsound(loc, "[species.female_scream_sound]", 80, 1, 0, pitch = get_age_pitch())
@@ -801,10 +703,9 @@
playsound(loc, "[species.male_scream_sound]", 80, 1, 0, pitch = get_age_pitch()) //default to male screams if no gender is present.
else
- message = "[src] makes a very loud noise."
+ message = "[src] makes a very loud noise[M ? " at [M]" : ""]."
m_type = 2
-
if("snap", "snaps")
if(prob(95))
m_type = 2
@@ -822,13 +723,14 @@
to_chat(usr, "You need at least one hand in good working order to snap your fingers.")
return
- message = "[src] snaps \his fingers."
+ var/M = handle_emote_param(param)
+
+ message = "[src] snaps \his fingers[M ? " at [M]" : ""]."
playsound(loc, 'sound/effects/fingersnap.ogg', 50, 1, -3)
else
message = "[src] snaps \his fingers right off!"
playsound(loc, 'sound/effects/snap.ogg', 50, 1)
-
// Needed for M_TOXIC_FART
if("fart", "farts")
if(reagents.has_reagent("simethicone"))
@@ -836,11 +738,11 @@
// playsound(loc, 'sound/effects/fart.ogg', 50, 1, -3) //Admins still vote no to fun
if(locate(/obj/item/weapon/storage/bible) in get_turf(src))
to_chat(viewers(src), "[src] farts on the Bible!")
- to_chat(viewers(src), "A mysterious force smites [src]!")
- var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
- s.set_up(3, 1, src)
- s.start()
- gib()
+ var/image/cross = image('icons/obj/storage.dmi',"bible")
+ var/adminbfmessage = "\blue [bicon(cross)] Bible Fart: [key_name(src, 1)] (?) (PP) (VV) (SM) ([admin_jump_link(src)]) (CA) (SMITE):"
+ for(var/client/X in admins)
+ if(check_rights(R_EVENT,0,X.mob))
+ to_chat(X, adminbfmessage)
else if(TOXIC_FARTS in mutations)
message = "[src] unleashes a [pick("horrible","terrible","foul","disgusting","awful")] fart."
else if(SUPER_FART in mutations)
@@ -877,13 +779,9 @@
to_chat(src, emotelist)
else
- to_chat(src, "\blue Unusable emote '[act]'. Say *help for a list.")
+ to_chat(src, "Unusable emote '[act]'. Say *help for a list.")
-
-
-
-
- if(message) //Humans are special fucking snowflakes and have 735 lines of emotes, they get to handle their own emotes, not call the parent
+ if(message) //Humans are special fucking snowflakes and have 800 lines of emotes, they get to handle their own emotes, not call the parent.
log_emote("[name]/[key] : [message]")
//Hearing gasp and such every five seconds is not good emotes were not global for a reason.
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 453402ec7e3..93d9a49d6df 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -33,7 +33,7 @@
var/msg = "*---------*\nThis is "
- if(skipjumpsuit && skipface) //big suits/masks/helmets make it hard to tell their gender
+ if((skipjumpsuit && skipface)) //big suits/masks/helmets make it hard to tell their gender
t_He = "They"
t_his = "their"
t_him = "them"
@@ -51,6 +51,12 @@
t_He = "She"
t_his = "her"
t_him = "her"
+ if(PLURAL)
+ t_He = "They"
+ t_his = "their"
+ t_him = "them"
+ t_has = "have"
+ t_is = "are"
msg += "[name]"
@@ -494,7 +500,8 @@
msg += "Medical records:\[View\]\[Add comment\]\n"
- if(print_flavor_text()) msg += "[print_flavor_text()]\n"
+ if(print_flavor_text() && !skipface)
+ msg += "[print_flavor_text()]\n"
msg += "*---------*"
if(pose)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 7e54aebf396..65cdd7c24d9 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -52,7 +52,7 @@
UpdateAppearance()
/mob/living/carbon/human/OpenCraftingMenu()
- handcrafting.craft(src)
+ handcrafting.ui_interact(src)
/mob/living/carbon/human/prepare_data_huds()
//Update med hud images...
@@ -747,7 +747,11 @@
var/obj/item/clothing/suit/S = wear_suit
if(S.siemens_coefficient <= 0)
total_coeff -= 0.95
+ else if(S.siemens_coefficient == (-1))
+ total_coeff -= 1
siemens_coeff = total_coeff
+ if(tesla_ignore)
+ siemens_coeff = 0
else if(!safety)
var/gloves_siemens_coeff = 1
var/species_siemens_coeff = 1
@@ -872,7 +876,7 @@
sec_hud_set_security_status()
if(!modified)
- to_chat(usr, "\red Unable to locate a data core entry for this person.")
+ to_chat(usr, "Unable to locate a data core entry for this person.")
if(href_list["secrecord"])
if(hasHUD(usr,"security"))
@@ -902,7 +906,7 @@
read = 1
if(!read)
- to_chat(usr, "\red Unable to locate a data core entry for this person.")
+ to_chat(usr, "Unable to locate a data core entry for this person.")
if(href_list["secrecordComment"])
if(hasHUD(usr,"security"))
@@ -923,16 +927,15 @@
if(R.fields["id"] == E.fields["id"])
if(hasHUD(usr,"security"))
read = 1
- var/counter = 1
- while(R.fields[text("com_[]", counter)])
- to_chat(usr, text("[]", R.fields[text("com_[]", counter)]))
- counter++
- if(counter == 1)
- to_chat(usr, "No comment found")
+ if(length(R.fields["comments"]))
+ for(var/c in R.fields["comments"])
+ to_chat(usr, c)
+ else
+ to_chat(usr, "No comment found")
to_chat(usr, "\[Add comment\]")
if(!read)
- to_chat(usr, "\red Unable to locate a data core entry for this person.")
+ to_chat(usr, "Unable to locate a data core entry for this person.")
if(href_list["secrecordadd"])
if(hasHUD(usr,"security"))
@@ -950,21 +953,18 @@
for(var/datum/data/record/R in data_core.security)
if(R.fields["id"] == E.fields["id"])
if(hasHUD(usr,"security"))
- var/t1 = sanitize(copytext(input("Add Comment:", "Sec. records", null, null) as message,1,MAX_MESSAGE_LEN))
- if( !(t1) || usr.stat || usr.restrained() || !(hasHUD(usr,"security")) )
+ var/t1 = copytext(trim(sanitize(input("Add Comment:", "Sec. records", null, null) as message)), 1, MAX_MESSAGE_LEN)
+ if(!t1 || usr.stat || usr.restrained() || !hasHUD(usr, "security"))
return
- var/counter = 1
- while(R.fields[text("com_[]", counter)])
- counter++
- if(istype(usr,/mob/living/carbon/human))
+ if(ishuman(usr))
var/mob/living/carbon/human/U = usr
- R.fields[text("com_[counter]")] = text("Made by [U.get_authentification_name()] ([U.get_assignment()]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year] [t1]")
- if(istype(usr,/mob/living/silicon/robot))
+ R.fields["comments"] += "Made by [U.get_authentification_name()] ([U.get_assignment()]) on [current_date_string] [worldtime2text()] [t1]"
+ if(isrobot(usr))
var/mob/living/silicon/robot/U = usr
- R.fields[text("com_[counter]")] = text("Made by [U.name] ([U.modtype] [U.braintype]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year] [t1]")
- if(istype(usr,/mob/living/silicon/ai))
+ R.fields["comments"] += "Made by [U.name] ([U.modtype] [U.braintype]) on [current_date_string] [worldtime2text()] [t1]"
+ if(isAI(usr))
var/mob/living/silicon/ai/U = usr
- R.fields[text("com_[counter]")] = text("Made by [U.name] (artificial intelligence) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year] [t1]")
+ R.fields["comments"] += "Made by [U.name] (artificial intelligence) on [current_date_string] [worldtime2text()] [t1]"
if(href_list["medical"])
if(hasHUD(usr,"medical"))
@@ -997,7 +997,7 @@
sec_hud_set_security_status()
if(!modified)
- to_chat(usr, "\red Unable to locate a data core entry for this person.")
+ to_chat(usr, "Unable to locate a data core entry for this person.")
if(href_list["medrecord"])
if(hasHUD(usr,"medical"))
@@ -1028,7 +1028,7 @@
read = 1
if(!read)
- to_chat(usr, "\red Unable to locate a data core entry for this person.")
+ to_chat(usr, "Unable to locate a data core entry for this person.")
if(href_list["medrecordComment"])
if(hasHUD(usr,"medical"))
@@ -1049,16 +1049,15 @@
if(R.fields["id"] == E.fields["id"])
if(hasHUD(usr,"medical"))
read = 1
- var/counter = 1
- while(R.fields[text("com_[]", counter)])
- to_chat(usr, text("[]", R.fields[text("com_[]", counter)]))
- counter++
- if(counter == 1)
- to_chat(usr, "No comment found")
+ if(length(R.fields["comments"]))
+ for(var/c in R.fields["comments"])
+ to_chat(usr, c)
+ else
+ to_chat(usr, "No comment found")
to_chat(usr, "\[Add comment\]")
if(!read)
- to_chat(usr, "\red Unable to locate a data core entry for this person.")
+ to_chat(usr, "Unable to locate a data core entry for this person.")
if(href_list["medrecordadd"])
if(hasHUD(usr,"medical"))
@@ -1076,18 +1075,15 @@
for(var/datum/data/record/R in data_core.medical)
if(R.fields["id"] == E.fields["id"])
if(hasHUD(usr,"medical"))
- var/t1 = sanitize(copytext(input("Add Comment:", "Med. records", null, null) as message,1,MAX_MESSAGE_LEN))
- if( !(t1) || usr.stat || usr.restrained() || !(hasHUD(usr,"medical")) )
+ var/t1 = copytext(trim(sanitize(input("Add Comment:", "Med. records", null, null) as message)), 1, MAX_MESSAGE_LEN)
+ if(!t1 || usr.stat || usr.restrained() || !hasHUD(usr, "medical"))
return
- var/counter = 1
- while(R.fields[text("com_[]", counter)])
- counter++
- if(istype(usr,/mob/living/carbon/human))
+ if(ishuman(usr))
var/mob/living/carbon/human/U = usr
- R.fields[text("com_[counter]")] = text("Made by [U.get_authentification_name()] ([U.get_assignment()]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year] [t1]")
- if(istype(usr,/mob/living/silicon/robot))
+ R.fields["comments"] += "Made by [U.get_authentification_name()] ([U.get_assignment()]) on [current_date_string] [worldtime2text()] [t1]"
+ if(isrobot(usr))
var/mob/living/silicon/robot/U = usr
- R.fields[text("com_[counter]")] = text("Made by [U.name] ([U.modtype] [U.braintype]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year] [t1]")
+ R.fields["comments"] += "Made by [U.name] ([U.modtype] [U.braintype]) on [current_date_string] [worldtime2text()] [t1]"
if(href_list["lookitem"])
var/obj/item/I = locate(href_list["lookitem"])
@@ -1176,7 +1172,7 @@
/mob/living/carbon/human/proc/play_xylophone()
if(!src.xylophone)
- visible_message("\red [src] begins playing his ribcage like a xylophone. It's quite spooky.","\blue You begin to play a spooky refrain on your ribcage.","\red You hear a spooky xylophone melody.")
+ visible_message("[src] begins playing his ribcage like a xylophone. It's quite spooky.","You begin to play a spooky refrain on your ribcage.","You hear a spooky xylophone melody.")
var/song = pick('sound/effects/xylophone1.ogg','sound/effects/xylophone2.ogg','sound/effects/xylophone3.ogg')
playsound(loc, song, 50, 1, -1)
xylophone = 1
@@ -1464,16 +1460,16 @@
if(usr == src)
self = 1
if(!self)
- usr.visible_message("\blue [usr] kneels down, puts \his hand on [src]'s wrist and begins counting their pulse.",\
+ usr.visible_message("[usr] kneels down, puts \his hand on [src]'s wrist and begins counting their pulse.",\
"You begin counting [src]'s pulse")
else
- usr.visible_message("\blue [usr] begins counting their pulse.",\
+ usr.visible_message("[usr] begins counting their pulse.",\
"You begin counting your pulse.")
if(src.pulse)
- to_chat(usr, "\blue [self ? "You have a" : "[src] has a"] pulse! Counting...")
+ to_chat(usr, "[self ? "You have a" : "[src] has a"] pulse! Counting...")
else
- to_chat(usr, "\red [src] has no pulse!")//it is REALLY UNLIKELY that a dead person would check his own pulse
+ to_chat(usr, "[src] has no pulse!")//it is REALLY UNLIKELY that a dead person would check his own pulse
return
@@ -1483,10 +1479,11 @@
if(usr.l_move_time >= time) //checks if our mob has moved during the sleep()
to_chat(usr, "You moved while counting. Try again.")
else
- to_chat(usr, "\blue [self ? "Your" : "[src]'s"] pulse is [src.get_pulse(GETPULSE_HAND)].")
+ to_chat(usr, "[self ? "Your" : "[src]'s"] pulse is [src.get_pulse(GETPULSE_HAND)].")
/mob/living/carbon/human/proc/set_species(var/new_species, var/default_colour, var/delay_icon_update = 0)
var/datum/species/oldspecies = species
+ var/datum/species/NS = all_species[new_species]
if(!dna)
if(!new_species)
new_species = "Human"
@@ -1506,6 +1503,8 @@
if(species.default_language)
remove_language(species.default_language)
+ if(gender == PLURAL && NS.has_gender)
+ change_gender(pick(MALE,FEMALE))
species.handle_pre_change(src)
species = all_species[new_species]
@@ -1770,7 +1769,7 @@
if(status_flags & LEAPING) status_flags &= ~LEAPING
if(!src.Adjacent(T))
- to_chat(src, "\red You miss!")
+ to_chat(src, "You miss!")
return
T.Weaken(5)
@@ -1783,7 +1782,7 @@
var/use_hand = "left"
if(l_hand)
if(r_hand)
- to_chat(src, "\red You need to have one hand free to grab someone.")
+ to_chat(src, "You need to have one hand free to grab someone.")
return
else
use_hand = "right"
@@ -1809,16 +1808,16 @@
return
if(!canmove)
- to_chat(src, "\red You cannot do that in your current state.")
+ to_chat(src, "You cannot do that in your current state.")
return
var/obj/item/weapon/grab/G = locate() in src
if(!G || !istype(G))
- to_chat(src, "\red You are not grabbing anyone.")
+ to_chat(src, "You are not grabbing anyone.")
return
if(G.state < GRAB_AGGRESSIVE)
- to_chat(src, "\red You must have an aggressive grab to gut your prey!")
+ to_chat(src, "You must have an aggressive grab to gut your prey!")
return
last_special = world.time + 50
@@ -1892,12 +1891,12 @@
threatcount += 2
//Check for dresscode violations
- if(istype(head, /obj/item/clothing/head/wizard) || istype(head, /obj/item/clothing/head/helmet/space/rig/wizard))
+ if(istype(head, /obj/item/clothing/head/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/wizard))
threatcount += 2
//Mindshield implants imply slight trustworthiness
- if(isloyal(src))
+ if(ismindshielded(src))
threatcount -= 1
//Agent cards lower threatlevel.
diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm
index a8e075f2433..99df89de5c7 100644
--- a/code/modules/mob/living/carbon/human/human_attackhand.dm
+++ b/code/modules/mob/living/carbon/human/human_attackhand.dm
@@ -4,7 +4,7 @@
return
if(frozen)
- to_chat(M, "\red Do not touch Admin-Frozen people.")
+ to_chat(M, "Do not touch Admin-Frozen people.")
return
var/mob/living/carbon/human/H = M
@@ -75,10 +75,10 @@
if(!check_has_mouth())
to_chat(H, "They don't have a mouth, you cannot perform CPR!")
return
- if((M.head && (M.head.flags & HEADCOVERSMOUTH)) || (M.wear_mask && (M.wear_mask.flags & MASKCOVERSMOUTH) && !M.wear_mask.mask_adjusted))
+ if((M.head && (M.head.flags_cover & HEADCOVERSMOUTH)) || (M.wear_mask && (M.wear_mask.flags_cover & MASKCOVERSMOUTH) && !M.wear_mask.mask_adjusted))
to_chat(M, "Remove your mask!")
return 0
- if((head && (head.flags & HEADCOVERSMOUTH)) || (wear_mask && (wear_mask.flags & MASKCOVERSMOUTH) && !wear_mask.mask_adjusted))
+ if((head && (head.flags_cover & HEADCOVERSMOUTH)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && !wear_mask.mask_adjusted))
to_chat(M, "Remove his mask!")
return 0
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index 4cf009ec44f..1f8d86c6c15 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -88,19 +88,19 @@
return amount
-/mob/living/carbon/human/adjustBruteLoss(amount)
+/mob/living/carbon/human/adjustBruteLoss(amount, damage_source)
if(species)
amount = amount * species.brute_mod
if(amount > 0)
- take_overall_damage(amount, 0)
+ take_overall_damage(amount, 0, used_weapon = damage_source)
else
heal_overall_damage(-amount, 0)
-/mob/living/carbon/human/adjustFireLoss(amount)
+/mob/living/carbon/human/adjustFireLoss(amount, damage_source)
if(species)
amount = amount * species.burn_mod
if(amount > 0)
- take_overall_damage(0, amount)
+ take_overall_damage(0, amount, used_weapon = damage_source)
else
heal_overall_damage(0, -amount)
@@ -394,4 +394,4 @@ This function restores all organs.
// Will set our damageoverlay icon to the next level, which will then be set back to the normal level the next mob.Life().
updatehealth()
- return 1
\ No newline at end of file
+ return 1
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 7685e5ab898..029c207a2d8 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -178,12 +178,12 @@ emp_act
if(!istype(affecting))
return
if(!(affecting.status & ORGAN_ROBOT))
- to_chat(user, "\red That limb isn't robotic.")
+ to_chat(user, "That limb isn't robotic.")
return
if(affecting.sabotaged)
- to_chat(user, "\red [src]'s [affecting.name] is already sabotaged!")
+ to_chat(user, "[src]'s [affecting.name] is already sabotaged!")
else
- to_chat(user, "\red You sneakily slide the card into the dataport on [src]'s [affecting.name] and short out the safeties.")
+ to_chat(user, "You sneakily slide the card into the dataport on [src]'s [affecting.name] and short out the safeties.")
affecting.sabotaged = 1
return 1
@@ -200,7 +200,7 @@ emp_act
src.reagents.trans_to (newmeat, round ((src.reagents.total_volume) / 3, 1))
src.loc.add_blood(src)
--src.meatleft
- to_chat(user, "\red You hack off a chunk of meat from [src.name]")
+ to_chat(user, "You hack off a chunk of meat from [src.name]")
if(!src.meatleft)
src.create_attack_log("Was chopped up into meat by [key_name(user)]")
user.create_attack_log("Chopped up [key_name(src)] into meat")
@@ -345,7 +345,7 @@ emp_act
return
var/hit_area = affecting.name
- src.visible_message("\red [src] has been hit in the [hit_area] by [I].")
+ src.visible_message("[src] has been hit in the [hit_area] by [I].")
var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].", I.armour_penetration) //I guess "melee" is the best fit here
apply_damage(throw_damage, dtype, zone, armor, is_sharp(I), has_edge(I), I)
@@ -378,7 +378,7 @@ emp_act
var/momentum = speed/2
var/dir = get_dir(I.throw_source, src)
- visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!")
+ visible_message("[src] staggers under the impact!","You stagger under the impact!")
src.throw_at(get_edge_target_turf(src,dir),1,momentum)
if(!W || !src) return
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 63378d1a776..15f9b6d112e 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -1,7 +1,7 @@
var/global/default_martial_art = new/datum/martial_art
/mob/living/carbon/human
- hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,SPECIALROLE_HUD,NATIONS_HUD)
+ hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPMINDSHIELD_HUD,IMPCHEM_HUD,IMPTRACK_HUD,SPECIALROLE_HUD,NATIONS_HUD)
//Marking colour and style
var/list/m_colours = DEFAULT_MARKING_COLOURS //All colours set to #000000.
diff --git a/code/modules/mob/living/carbon/human/interactive/functions.dm b/code/modules/mob/living/carbon/human/interactive/functions.dm
index 272b95d3577..ad4d8226c4a 100644
--- a/code/modules/mob/living/carbon/human/interactive/functions.dm
+++ b/code/modules/mob/living/carbon/human/interactive/functions.dm
@@ -86,7 +86,7 @@
custom_emote(1, "[src]'s chest opens up, revealing a large mass of explosives and tangled wires!")
if(inactivity_period <= 0)
inactivity_period = 9999 // technically infinite
- if(do_after(src, 60, target=traitorTarget))
+ if(do_after(src, 60, target = traitorTarget))
custom_emote(1, "A fire bursts from [src]'s eyes, igniting white hot and consuming their body in a flaming explosion!")
explosion(src, 6, 6, 6)
else
diff --git a/code/modules/mob/living/carbon/human/interactive/interactive.dm b/code/modules/mob/living/carbon/human/interactive/interactive.dm
index fa8de8e2b87..de0a0b77e3f 100644
--- a/code/modules/mob/living/carbon/human/interactive/interactive.dm
+++ b/code/modules/mob/living/carbon/human/interactive/interactive.dm
@@ -132,7 +132,6 @@
job = myjob.title
mind.assigned_role = job
myjob.equip(src)
- myjob.apply_fingerprints(T)
/mob/living/carbon/human/interactive/proc/reset()
walk(src, 0)
@@ -193,7 +192,6 @@
for(var/obj/item/W in T)
qdel(W)
T.myjob.equip(T)
- T.myjob.apply_fingerprints(T)
T.doSetup(alt_title)
var/shouldDoppel = input("Do you want the SNPC to disguise themself as a crewmember?") as anything in list("Yes", "No")
@@ -633,8 +631,6 @@
AL.wires.UpdatePulsed(AIRLOCK_WIRE_DOOR_BOLTS)
if(!AL.wires.IsIndexCut(AIRLOCK_WIRE_MAIN_POWER1))
AL.wires.CutWireIndex(AIRLOCK_WIRE_MAIN_POWER1)
- if(!AL.wires.IsIndexCut(AIRLOCK_WIRE_MAIN_POWER2))
- AL.wires.CutWireIndex(AIRLOCK_WIRE_MAIN_POWER2)
if(prob(mistake_chance) && !AL.wires.IsIndexCut(AIRLOCK_WIRE_SAFETY))
AL.wires.CutWireIndex(AIRLOCK_WIRE_SAFETY)
if(prob(mistake_chance) && !AL.wires.IsIndexCut(AIRLOCK_WIRE_ELECTRIFY))
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index c375d718e3d..93887e8542f 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -615,3 +615,17 @@
return 1
return 0 //Unsupported slot
+
+/mob/living/carbon/human/proc/equipOutfit(outfit, visualsOnly = FALSE)
+ var/datum/outfit/O = null
+
+ if(ispath(outfit))
+ O = new outfit
+ else
+ O = outfit
+ if(!istype(O))
+ return 0
+ if(!O)
+ return 0
+
+ return O.equip(src, visualsOnly)
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index b2e609c92f2..c7018183da3 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -958,13 +958,6 @@
adjustToxLoss(-3)
lastpuke = 0
- //0.1% chance of playing a scary sound to someone who's in complete darkness
- if(isturf(loc) && rand(1,1000) == 1)
- var/turf/currentTurf = loc
- var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in currentTurf
- if(L && L.lum_r + L.lum_g + L.lum_b == 0)
- playsound_local(src,pick(scarySounds),50, 1, -1)
-
/mob/living/carbon/human/handle_changeling()
if(mind)
if(mind.changeling)
@@ -1102,7 +1095,7 @@
if(istype(loc,/obj/item/bodybag))
return
var/obj/item/clothing/mask/M = H.wear_mask
- if(M && (M.flags & MASKCOVERSMOUTH))
+ if(M && (M.flags_cover & MASKCOVERSMOUTH))
return
if(H.species && H.species.flags & NO_BREATHE)
return //no puking if you can't smell!
@@ -1188,7 +1181,8 @@
else
AdjustLoseBreath(2, bound_lower = 0, bound_upper = 3)
adjustOxyLoss(5)
- adjustBruteLoss(1)
+ Paralyse(4)
+ adjustBruteLoss(2)
diff --git a/code/modules/mob/living/carbon/human/species/abductor.dm b/code/modules/mob/living/carbon/human/species/abductor.dm
index 4690529524f..8e9c61992aa 100644
--- a/code/modules/mob/living/carbon/human/species/abductor.dm
+++ b/code/modules/mob/living/carbon/human/species/abductor.dm
@@ -18,7 +18,7 @@
"eyes" = /obj/item/organ/internal/eyes/abductor //3 darksight.
)
- flags = HAS_LIPS | NO_BLOOD | NO_BREATHE
+ flags = HAS_LIPS | NO_BLOOD | NO_BREATHE | NOGUNS
oxy_mod = 0
@@ -27,11 +27,14 @@
dietflags = DIET_OMNI
reagent_tag = PROCESS_ORG
blood_color = "#FF5AFF"
+ female_scream_sound = 'sound/goonstation/voice/male_scream.ogg'
+ female_cough_sounds = list('sound/effects/mob_effects/m_cougha.ogg','sound/effects/mob_effects/m_coughb.ogg', 'sound/effects/mob_effects/m_coughc.ogg')
+ female_sneeze_sound = 'sound/effects/mob_effects/sneeze.ogg' //Abductors always scream like guys
-/datum/species/abductor/can_understand(var/mob/other) //Abductors can understand everyone, but they can only speak over their mindlink to another team-member
+/datum/species/abductor/can_understand(mob/other) //Abductors can understand everyone, but they can only speak over their mindlink to another team-member
return 1
-/datum/species/abductor/handle_post_spawn(var/mob/living/carbon/human/H)
+/datum/species/abductor/handle_post_spawn(mob/living/carbon/human/H)
H.gender = NEUTER
if(H.mind)
H.mind.abductor = new /datum/abductor
diff --git a/code/modules/mob/living/carbon/human/species/apollo.dm b/code/modules/mob/living/carbon/human/species/apollo.dm
index 4c871405c8d..4fcedc1844a 100644
--- a/code/modules/mob/living/carbon/human/species/apollo.dm
+++ b/code/modules/mob/living/carbon/human/species/apollo.dm
@@ -66,21 +66,21 @@
M.visible_message("[M] begins to violently pull off [H]'s antennae.")
to_chat(H, "[M] grips your antennae and starts violently pulling!")
- do_after(H, 250, target = src)
- if(p_loc == M.loc && p_loc_m == H.loc)
- var/obj/item/organ/internal/wryn/hivenode/node = new /obj/item/organ/internal/wryn/hivenode
- H.remove_language("Wryn Hivemind")
- node.remove(H)
- node.loc = M.loc
- to_chat(M, "You hear a loud crunch as you mercilessly pull off [H]'s antennae.")
- to_chat(H, "You hear a loud crunch as your antennae is ripped off your head by [M].")
- to_chat(H, "It's so quiet...")
- head_organ.h_style = "Bald"
- H.update_hair()
+ if(do_after(H, 250, target = src))
+ if(p_loc == M.loc && p_loc_m == H.loc)
+ var/obj/item/organ/internal/wryn/hivenode/node = new /obj/item/organ/internal/wryn/hivenode
+ H.remove_language("Wryn Hivemind")
+ node.remove(H)
+ node.loc = M.loc
+ to_chat(M, "You hear a loud crunch as you mercilessly pull off [H]'s antennae.")
+ to_chat(H, "You hear a loud crunch as your antennae is ripped off your head by [M].")
+ to_chat(H, "It's so quiet...")
+ head_organ.h_style = "Bald"
+ H.update_hair()
- M.create_attack_log("removed antennae [H.name] ([H.ckey])")
- H.create_attack_log("Has had their antennae removed by [M.name] ([M.ckey])")
- msg_admin_attack("[key_name(M)] removed [key_name(H)]'s antennae")
+ M.create_attack_log("removed antennae [H.name] ([H.ckey])")
+ H.create_attack_log("Has had their antennae removed by [M.name] ([M.ckey])")
+ msg_admin_attack("[key_name(M)] removed [key_name(H)]'s antennae")
return 0
/datum/species/nucleation
@@ -122,7 +122,7 @@
/datum/species/nucleation/handle_death(var/mob/living/carbon/human/H)
var/turf/T = get_turf(H)
- H.visible_message("\red[H]'s body explodes, leaving behind a pile of microscopic crystals!")
+ H.visible_message("[H]'s body explodes, leaving behind a pile of microscopic crystals!")
explosion(T, 0, 0, 2, 2) // Create a small explosion burst upon death
// new /obj/item/weapon/shard/supermatter( T )
qdel(H)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species/plasmaman.dm b/code/modules/mob/living/carbon/human/species/plasmaman.dm
index 05f24facc65..ae236b1ebd4 100644
--- a/code/modules/mob/living/carbon/human/species/plasmaman.dm
+++ b/code/modules/mob/living/carbon/human/species/plasmaman.dm
@@ -15,6 +15,7 @@
butt_sprite = "plasma"
breath_type = "plasma"
+ poison_type = null //Certainly isn't plasma.
heat_level_1 = 350 // Heat damage level 1 above this point.
heat_level_2 = 400 // Heat damage level 2 above this point.
@@ -33,20 +34,21 @@
message = replacetext(message, "s", stutter("ss"))
return message
-/datum/species/plasmaman/equip(var/mob/living/carbon/human/H)
+/datum/species/plasmaman/after_equip_job(datum/job/J, mob/living/carbon/human/H)
+ var/assigned_role = H.mind && H.mind.assigned_role ? H.mind.assigned_role : "Civilian"
// Unequip existing suits and hats.
H.unEquip(H.wear_suit)
H.unEquip(H.head)
- if(H.mind.assigned_role != "Clown")
+ if(assigned_role != "Clown")
H.unEquip(H.wear_mask)
H.equip_or_collect(new /obj/item/clothing/mask/breath(H), slot_wear_mask)
- var/suit=/obj/item/clothing/suit/space/eva/plasmaman
- var/helm=/obj/item/clothing/head/helmet/space/eva/plasmaman
+ var/suit=/obj/item/clothing/suit/space/eva/plasmaman/assistant
+ var/helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/assistant
var/tank_slot = slot_s_store
var/tank_slot_name = "suit storage"
- switch(H.mind.assigned_role)
+ switch(assigned_role)
if("Scientist","Geneticist","Roboticist")
suit=/obj/item/clothing/suit/space/eva/plasmaman/science
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/science
@@ -54,8 +56,8 @@
suit=/obj/item/clothing/suit/space/eva/plasmaman/science/rd
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/science/rd
if("Station Engineer", "Mechanic")
- suit=/obj/item/clothing/suit/space/eva/plasmaman/engineer/
- helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/engineer/
+ suit=/obj/item/clothing/suit/space/eva/plasmaman/engineer
+ helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/engineer
if("Chief Engineer")
suit=/obj/item/clothing/suit/space/eva/plasmaman/engineer/ce
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/engineer/ce
@@ -63,11 +65,11 @@
suit=/obj/item/clothing/suit/space/eva/plasmaman/atmostech
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/atmostech
if("Detective")
- suit=/obj/item/clothing/suit/space/eva/plasmaman/security/
- helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security/
+ suit=/obj/item/clothing/suit/space/eva/plasmaman/security
+ helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security
if("Warden","Security Officer","Security Pod Pilot")
- suit=/obj/item/clothing/suit/space/eva/plasmaman/security/
- helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security/
+ suit=/obj/item/clothing/suit/space/eva/plasmaman/security
+ helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security
H.equip_or_collect(new /obj/item/weapon/gun/energy/gun/advtaser(H), slot_in_backpack)
if("Internal Affairs Agent")
suit=/obj/item/clothing/suit/space/eva/plasmaman/lawyer
@@ -127,8 +129,10 @@
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/mime
H.equip_or_collect(new suit(H), slot_wear_suit)
H.equip_or_collect(new helm(H), slot_head)
- H.equip_or_collect(new/obj/item/weapon/tank/plasma/plasmaman(H), tank_slot) // Bigger plasma tank from Raggy.
- to_chat(H, "You are now running on plasma internals from the [H.s_store] in your [tank_slot_name]. You must breathe plasma in order to survive, and are extremely flammable.")
+ H.equip_or_collect(new /obj/item/weapon/tank/plasma/plasmaman(H), tank_slot) // Bigger plasma tank from Raggy.
+ H.equip_or_collect(new /obj/item/weapon/plasmensuit_cartridge(H), slot_in_backpack)
+ H.equip_or_collect(new /obj/item/weapon/plasmensuit_cartridge(H), slot_in_backpack) //Two refill cartridges for their suit. Can fit in boxes.
+ to_chat(H, "You are now running on plasma internals from the [H.s_store] in your [tank_slot_name]. You must breathe plasma in order to survive, and are extremely flammable.")
H.internal = H.get_item_by_slot(tank_slot)
H.update_internals_hud_icon(1)
@@ -206,10 +210,10 @@
return 1 //godmode
if(breath.temperature < cold_level_1)
if(prob(20))
- to_chat(src, "\red You feel your face freezing and an icicle forming in your lungs!")
+ to_chat(src, "You feel your face freezing and an icicle forming in your lungs!")
else if(breath.temperature > heat_level_1)
if(prob(20))
- to_chat(src, "\red You feel your face burning and a searing heat in your lungs!")
+ to_chat(src, "You feel your face burning and a searing heat in your lungs!")
switch(breath.temperature)
if(-INFINITY to cold_level_3)
@@ -235,10 +239,29 @@
if(heat_level_3 to INFINITY)
H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Heat")
H.fire_alert = max(H.fire_alert, 2)
-
- if(!istype(H.wear_suit, /obj/item/clothing/suit/space/eva/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/eva/plasmaman))
- to_chat(H, "Your body reacts with the atmosphere and bursts into flame!")
- H.adjust_fire_stacks(0.5)
- H.IgniteMob()
-
return 1
+
+/datum/species/plasmaman/handle_life(var/mob/living/carbon/human/H)
+ if(!istype(H.wear_suit, /obj/item/clothing/suit/space/eva/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/eva/plasmaman))
+ var/datum/gas_mixture/environment = H.loc.return_air()
+ if(environment && environment.oxygen && environment.oxygen >= OXYCONCEN_PLASMEN_IGNITION) //Plasmamen so long as there's enough oxygen (0.5 moles, same as it takes to burn gaseous plasma).
+ H.adjust_fire_stacks(0.5)
+ if(!H.on_fire && H.fire_stacks > 0)
+ H.visible_message("[H]'s body reacts with the atmosphere and bursts into flames!","Your body reacts with the atmosphere and bursts into flame!")
+ H.IgniteMob()
+ else
+ if(H.on_fire && H.fire_stacks > 0)
+ var/obj/item/clothing/suit/space/eva/plasmaman/P = H.wear_suit
+ if(istype(P))
+ P.Extinguish(H)
+ H.update_fire()
+
+/datum/species/plasmaman/handle_reagents(var/mob/living/carbon/human/H, var/datum/reagent/R)
+ if(R.id == "plasma")
+ H.adjustBruteLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER)
+ H.adjustFireLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER)
+ H.adjustPlasma(20)
+ H.reagents.remove_reagent(R.id, REAGENTS_METABOLISM)
+ return 0 //Handling reagent removal on our own. Prevents plasma from dealing toxin damage to Plasmamen.
+
+ return ..()
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index 54f68f2b101..54550a0f560 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -110,6 +110,7 @@
var/show_ssd = 1
var/virus_immune
var/can_revive_by_healing // Determines whether or not this species can be revived by simply healing them
+ var/has_gender = TRUE
//Death vars.
var/death_message = "seizes up and falls limp, their eyes dead and lifeless..."
@@ -439,7 +440,10 @@
/datum/species/proc/say_filter(mob/M, message, datum/language/speaking)
return message
-/datum/species/proc/equip(var/mob/living/carbon/human/H)
+/datum/species/proc/before_equip_job(datum/job/J, mob/living/carbon/human/H, visualsOnly = FALSE)
+ return
+
+/datum/species/proc/after_equip_job(datum/job/J, mob/living/carbon/human/H, visualsOnly = FALSE)
return
/datum/species/proc/can_understand(var/mob/other)
@@ -524,9 +528,9 @@
H.healths.icon_state = "health7"
else
switch(H.hal_screwyhud)
- if(1) H.healths.icon_state = "health6"
- if(2) H.healths.icon_state = "health7"
- if(5) H.healths.icon_state = "health0"
+ if(SCREWYHUD_CRIT) H.healths.icon_state = "health6"
+ if(SCREWYHUD_DEAD) H.healths.icon_state = "health7"
+ if(SCREWYHUD_HEALTHY) H.healths.icon_state = "health0"
else
switch(100 - ((flags & NO_PAIN) ? 0 : H.traumatic_shock) - H.staminaloss)
if(100 to INFINITY) H.healths.icon_state = "health0"
diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm
index fcdd8ac40ea..10e39022315 100644
--- a/code/modules/mob/living/carbon/human/species/station.dm
+++ b/code/modules/mob/living/carbon/human/species/station.dm
@@ -56,7 +56,8 @@
reagent_tag = PROCESS_ORG
base_color = "#066000"
//Default styles for created mobs.
- default_hair = "Unathi Horns"
+ default_headacc = "Simple"
+ default_headacc_colour = "#404040"
butt_sprite = "unathi"
has_organ = list(
@@ -214,6 +215,9 @@
dietflags = DIET_HERB
flesh_color = "#8CD7A3"
blood_color = "#1D2CBF"
+ base_color = "#38b661" //RGB: 56, 182, 97.
+ default_hair_colour = "#38b661"
+ eyes = "skrell_eyes_s"
//Default styles for created mobs.
default_hair = "Skrell Male Tentacles"
reagent_tag = PROCESS_ORG
@@ -257,6 +261,8 @@
smell.
Most humans will never meet a Vox raider, instead learning of this insular species through \
dealing with their traders and merchants; those that do rarely enjoy the experience."
+ brute_mod = 1.2 //20% more brute damage. Fragile bird bones.
+
warning_low_pressure = 50
hazard_low_pressure = 0
@@ -343,13 +349,13 @@
newname += pick(vox_name_syllables)
return capitalize(newname)
-/datum/species/vox/equip(var/mob/living/carbon/human/H)
- if(H.mind.assigned_role != "Clown" && H.mind.assigned_role != "Mime")
+/datum/species/vox/after_equip_job(datum/job/J, mob/living/carbon/human/H)
+ if(!H.mind || !H.mind.assigned_role || H.mind.assigned_role != "Clown" && H.mind.assigned_role != "Mime")
H.unEquip(H.wear_mask)
H.unEquip(H.l_hand)
H.equip_or_collect(new /obj/item/clothing/mask/breath/vox(H), slot_wear_mask)
- var/tank_pref = H.client.prefs.speciesprefs
+ var/tank_pref = H.client && H.client.prefs ? H.client.prefs.speciesprefs : null
if(tank_pref)//Diseasel, here you go
H.equip_or_collect(new /obj/item/weapon/tank/nitrogen(H), slot_l_hand)
else
@@ -365,7 +371,7 @@
..()
/datum/species/vox/updatespeciescolor(var/mob/living/carbon/human/H, var/owner_sensitive = 1) //Handling species-specific skin-tones for the Vox race.
- if(H.species.name == "Vox") //Making sure we don't break Armalis.
+ if(H.species.bodyflags & HAS_ICON_SKIN_TONE) //Making sure we don't break Armalis.
var/new_icobase = 'icons/mob/human_races/vox/r_vox.dmi' //Default Green Vox.
var/new_deform = 'icons/mob/human_races/vox/r_def_vox.dmi' //Default Green Vox.
switch(H.s_tone)
@@ -395,6 +401,14 @@
H.change_icobase(new_icobase, new_deform, owner_sensitive) //Update the icobase/deform of all our organs, but make sure we don't mess with frankenstein limbs in doing so.
H.update_dna()
+/datum/species/vox/handle_reagents(var/mob/living/carbon/human/H, var/datum/reagent/R)
+ if(R.id == "oxygen") //Armalis are above such petty things.
+ H.adjustToxLoss(1*REAGENTS_EFFECT_MULTIPLIER) //Same as plasma.
+ H.reagents.remove_reagent(R.id, REAGENTS_METABOLISM)
+ return 0 //Handling reagent removal on our own.
+
+ return ..()
+
/datum/species/vox/armalis/handle_post_spawn(var/mob/living/carbon/human/H)
H.verbs += /mob/living/carbon/human/proc/leap
H.verbs += /mob/living/carbon/human/proc/gut
@@ -427,7 +441,8 @@
breath_type = "nitrogen"
poison_type = "oxygen"
- flags = NO_SCAN | NO_BLOOD | HAS_TAIL | NO_PAIN | IS_WHITELISTED
+ flags = NO_SCAN | NO_BLOOD | NO_PAIN | IS_WHITELISTED
+ bodyflags = HAS_TAIL
dietflags = DIET_OMNI //should inherit this from vox, this is here just in case
blood_color = "#2299FC"
@@ -455,6 +470,9 @@
"is holding their breath!",
"is huffing oxygen!")
+/datum/species/vox/armalis/handle_reagents() //Skip the Vox oxygen reagent toxicity. Armalis are above such things.
+ return 1
+
/datum/species/kidan
name = "Kidan"
name_plural = "Kidan"
@@ -468,12 +486,14 @@
brute_mod = 0.8
flags = IS_WHITELISTED
- clothing_flags = HAS_SOCKS
- bodyflags = FEET_CLAWS
- eyes = "kidan_eyes"
+ clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
+ bodyflags = FEET_CLAWS | HAS_HEAD_ACCESSORY
+ eyes = "kidan_eyes_s"
dietflags = DIET_HERB
blood_color = "#FB9800"
reagent_tag = PROCESS_ORG
+ //Default styles for created mobs.
+ default_headacc = "Normal Antennae"
butt_sprite = "kidan"
has_organ = list(
@@ -492,6 +512,8 @@
"is attempting to bite their antenna off!",
"is jamming their claws into their eye sockets!",
"is twisting their own neck!",
+ "is cracking their exoskeleton!",
+ "is stabbing themselves with their mandibles!",
"is holding their breath!")
/datum/species/slime
@@ -728,7 +750,7 @@
genemutcheck(C,REMOTETALKBLOCK,null,MUTCHK_FORCED)
..()
-/datum/species/grey/equip(var/mob/living/carbon/human/H)
+/datum/species/grey/after_equip_job(datum/job/J, mob/living/carbon/human/H)
var/speech_pref = H.client.prefs.speciesprefs
if(speech_pref)
H.mind.speech_span = "wingdings"
@@ -887,6 +909,7 @@
default_hair = "Blue IPC Screen"
virus_immune = 1
can_revive_by_healing = 1
+ has_gender = FALSE
reagent_tag = PROCESS_SYN
male_scream_sound = 'sound/goonstation/voice/robot_scream.ogg'
female_scream_sound = 'sound/goonstation/voice/robot_scream.ogg'
@@ -899,7 +922,8 @@
has_organ = list(
"brain" = /obj/item/organ/internal/brain/mmi_holder/posibrain,
"cell" = /obj/item/organ/internal/cell,
- "optics" = /obj/item/organ/internal/eyes/optical_sensor //Default darksight of 2.
+ "optics" = /obj/item/organ/internal/eyes/optical_sensor, //Default darksight of 2.
+ "charger" = /obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord
)
vision_organ = /obj/item/organ/internal/eyes/optical_sensor
diff --git a/code/modules/mob/living/carbon/human/status_procs.dm b/code/modules/mob/living/carbon/human/status_procs.dm
index 5ca23f89f4f..5f74f202603 100644
--- a/code/modules/mob/living/carbon/human/status_procs.dm
+++ b/code/modules/mob/living/carbon/human/status_procs.dm
@@ -13,7 +13,7 @@
amount = amount * species.stun_mod
..()
-/mob/living/carbon/human/SetSleeping(amount, updating = 1)
+/mob/living/carbon/human/SetSleeping(amount, updating = 1, no_alert = FALSE)
if(species)
amount = amount * species.stun_mod
..()
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index d24471dc7e2..4c0088e0157 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -638,7 +638,7 @@ var/global/list/damage_icon_parts = list()
if(w_uniform.flags_size & ONESIZEFITSALL)
standing.icon = 'icons/mob/uniform_fat.dmi'
else
- to_chat(src, "\red You burst out of \the [w_uniform]!")
+ to_chat(src, "You burst out of \the [w_uniform]!")
unEquip(w_uniform)
return
else
@@ -957,7 +957,7 @@ var/global/list/damage_icon_parts = list()
if(wear_suit.flags_size & ONESIZEFITSALL)
standing = image("icon" = 'icons/mob/suit_fat.dmi', "icon_state" = "[wear_suit.icon_state]")
else
- to_chat(src, "\red You burst out of \the [wear_suit]!")
+ to_chat(src, "You burst out of \the [wear_suit]!")
unEquip(wear_suit)
return
else
@@ -1202,7 +1202,7 @@ var/global/list/damage_icon_parts = list()
var/icon/tail_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[tail]_s")
if(species.bodyflags & HAS_SKIN_COLOR)
tail_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
- if(tail_marking_icon)
+ if(tail_marking_icon && !tail_marking_style.tails_allowed)
tail_s.Blend(tail_marking_icon, ICON_OVERLAY)
if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this)
// Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway.
@@ -1270,7 +1270,7 @@ var/global/list/damage_icon_parts = list()
var/icon/tailw_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[tail]w_s")
if(species.bodyflags & HAS_SKIN_COLOR)
tailw_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
- if(tail_marking_icon)
+ if(tail_marking_icon && !tail_marking_style.tails_allowed)
tailw_s.Blend(tail_marking_icon, ICON_OVERLAY)
if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this)
// Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway.
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 91661304144..da764cafda3 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -345,7 +345,7 @@
if(..())
handle_dreams()
adjustStaminaLoss(-10)
- if(prob(10) && health && !hal_crit)
+ if(prob(10) && health && hal_screwyhud != SCREWYHUD_CRIT)
spawn(0)
emote("snore")
// Keep SSD people asleep
diff --git a/code/modules/mob/living/carbon/slime/emote.dm b/code/modules/mob/living/carbon/slime/emote.dm
index c77d5e24a65..b4a6eb140f0 100644
--- a/code/modules/mob/living/carbon/slime/emote.dm
+++ b/code/modules/mob/living/carbon/slime/emote.dm
@@ -14,7 +14,7 @@
return
if(src.client)
if(client.prefs.muted & MUTE_IC)
- to_chat(src, "\red You cannot send IC messages (muted).")
+ to_chat(src, "You cannot send IC messages (muted).")
return
if(src.client.handle_spam_prevention(message,MUTE_IC))
return
@@ -62,7 +62,7 @@
to_chat(src, "Help for slime emotes. You can use these emotes with say \"*emote\":\n\nbounce, custom, jiggle, light, moan, shiver, sway, twitch, vibrate")
else
- to_chat(src, "\blue Unusable emote '[act]'. Say *help for a list.")
+ to_chat(src, "Unusable emote '[act]'. Say *help for a list.")
if((message && src.stat == 0))
if(m_type & 1)
for(var/mob/O in viewers(src, null))
diff --git a/code/modules/mob/living/carbon/slime/powers.dm b/code/modules/mob/living/carbon/slime/powers.dm
index 38a4a310b41..95359f7d573 100644
--- a/code/modules/mob/living/carbon/slime/powers.dm
+++ b/code/modules/mob/living/carbon/slime/powers.dm
@@ -27,7 +27,7 @@
if(met.Victim == M && met != src)
to_chat(src, "The [met.name] is already feeding on this subject...")
return
- to_chat(src, "\blue I have latched onto the subject and begun feeding...")
+ to_chat(src, "I have latched onto the subject and begun feeding...")
to_chat(M, "The [src.name] has latched onto your head!")
Feedon(M)
diff --git a/code/modules/mob/living/carbon/slime/slime.dm b/code/modules/mob/living/carbon/slime/slime.dm
index 4952a4bd61b..003cd4a079e 100644
--- a/code/modules/mob/living/carbon/slime/slime.dm
+++ b/code/modules/mob/living/carbon/slime/slime.dm
@@ -371,7 +371,7 @@
visible_message("[src] has been touched with the stun gloves by [M]!")
return
else
- to_chat(M, "\red Not enough charge! ")
+ to_chat(M, "Not enough charge! ")
return
*/
diff --git a/code/modules/mob/living/carbon/superheroes.dm b/code/modules/mob/living/carbon/superheroes.dm
index fac41aa66f7..ce9fe15ae6e 100644
--- a/code/modules/mob/living/carbon/superheroes.dm
+++ b/code/modules/mob/living/carbon/superheroes.dm
@@ -14,15 +14,19 @@
assign_genes(H)
assign_spells(H)
equip(H)
+ fixflags(H)
assign_id(H)
/datum/superheroes/proc/equip(var/mob/living/carbon/human/H)
H.rename_character(H.real_name, name)
- for(var/obj/item/W in H)
- if(istype(W,/obj/item/organ)) continue
+ for(var/obj/item/W in H.get_all_slots())
H.unEquip(W)
H.equip_to_slot_or_del(new /obj/item/device/radio/headset(H), slot_l_ear)
+/datum/superheroes/proc/fixflags(var/mob/living/carbon/human/H)
+ for(var/obj/item/W in H.get_all_slots())
+ W.flags |= NODROP
+
/datum/superheroes/proc/assign_genes(var/mob/living/carbon/human/H)
if(default_genes.len)
for(var/gene in default_genes)
@@ -42,14 +46,17 @@
W.registered_name = H.real_name
W.access = list(access_maint_tunnels)
if(class == "Superhero")
- W.name = "[H.real_name]'s ID Card (Superhero)"
W.assignment = "Superhero"
+ W.rank = "Superhero"
ticker.mode.superheroes += H.mind
else if(class == "Supervillain")
- W.name = "[H.real_name]'s ID Card (Supervillain)"
W.assignment = "Supervillain"
+ W.rank = "Supervillain"
ticker.mode.supervillains += H.mind
-
+ W.icon_state = "lifetimeid"
+ W.SetOwnerInfo(H)
+ W.UpdateName()
+ W.flags |= NODROP
H.equip_to_slot_or_del(W, slot_wear_id)
H.regenerate_icons()
@@ -66,8 +73,8 @@
..()
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black/greytide(H), slot_shoes)
- H.equip_to_slot_or_del(new /obj/item/clothing/under/owl/super_hero(H), slot_w_uniform)
- H.equip_to_slot_or_del(new /obj/item/clothing/suit/toggle/owlwings/super_hero(H), slot_wear_suit)
+ H.equip_to_slot_or_del(new /obj/item/clothing/under/owl(H), slot_w_uniform)
+ H.equip_to_slot_or_del(new /obj/item/clothing/suit/toggle/owlwings(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/owl_mask/super_hero(H), slot_wear_mask)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/bluespace/owlman(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/glasses/night(H), slot_glasses)
@@ -84,15 +91,13 @@
/datum/superheroes/griffin/equip(var/mob/living/carbon/human/H)
..()
- H.equip_to_slot_or_del(new /obj/item/clothing/shoes/griffin/super_hero(H), slot_shoes)
- H.equip_to_slot_or_del(new /obj/item/clothing/under/griffin/super_hero(H), slot_w_uniform)
- H.equip_to_slot_or_del(new /obj/item/clothing/suit/toggle/owlwings/griffinwings/super_hero(H), slot_wear_suit)
- H.equip_to_slot_or_del(new /obj/item/clothing/head/griffin/super_hero(H), slot_head)
+ H.equip_to_slot_or_del(new /obj/item/clothing/shoes/griffin(H), slot_shoes)
+ H.equip_to_slot_or_del(new /obj/item/clothing/under/griffin(H), slot_w_uniform)
+ H.equip_to_slot_or_del(new /obj/item/clothing/suit/toggle/owlwings/griffinwings(H), slot_wear_suit)
+ H.equip_to_slot_or_del(new /obj/item/clothing/head/griffin/(H), slot_head)
var/obj/item/weapon/implant/freedom/L = new/obj/item/weapon/implant/freedom(H)
- L.imp_in = H
- L.implanted = 1
- return 1
+ L.implant(H, H)
/datum/superheroes/lightnian
@@ -189,7 +194,7 @@
to_chat(target, "You feel yourself agreeing with [user], and a surge of loyalty begins building.")
target.Weaken(12)
sleep(20)
- if(isloyal(target))
+ if(ismindshielded(target))
to_chat(user, "They are enslaved by Nanotrasen. You feel their interest in your cause wane and disappear.")
user.visible_message("[user] stops talking for a moment, then moves back away from [target].")
to_chat(target, "Your mindshield implant activates, protecting you from conversion.")
@@ -217,18 +222,20 @@
target.s_tone = 35
// No `update_dna=0` here because the character is being over-written
target.change_eye_color(1,1,1)
- for(var/obj/item/W in target)
- if(istype(W,/obj/item/organ)) continue
+ for(var/obj/item/W in target.get_all_slots())
target.unEquip(W)
target.rename_character(target.real_name, "Generic Henchman ([rand(1, 1000)])")
target.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey/greytide(target), slot_w_uniform)
target.equip_to_slot_or_del(new /obj/item/clothing/shoes/black/greytide(target), slot_shoes)
target.equip_to_slot_or_del(new /obj/item/weapon/storage/toolbox/mechanical/greytide(target), slot_l_hand)
- var/obj/item/weapon/card/id/syndicate/W = new(target)
- W.registered_name = target.real_name
- W.access = list(access_maint_tunnels)
- W.name = "[target.real_name]'s ID Card (Greyshirt)"
- W.assignment = "Greyshirt"
- target.equip_to_slot_or_del(W, slot_wear_id)
target.equip_to_slot_or_del(new /obj/item/device/radio/headset(target), slot_l_ear)
+ var/obj/item/weapon/card/id/syndicate/W = new(target)
+ W.icon_state = "lifetimeid"
+ W.access = list(access_maint_tunnels)
+ W.assignment = "Greyshirt"
+ W.rank = "Greyshirt"
+ W.flags |= NODROP
+ W.SetOwnerInfo(target)
+ W.UpdateName()
+ target.equip_to_slot_or_del(W, slot_wear_id)
target.regenerate_icons()
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 6f4ad8840c7..525559e8e6c 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -471,7 +471,7 @@
var/obj/item/weapon/grab/G = pick(M.grabbed_by)
if(istype(G, /obj/item/weapon/grab))
for(var/mob/O in viewers(M, null))
- O.show_message(text("\red [] has been pulled from []'s grip by []", G.affecting, G.assailant, src), 1)
+ O.show_message(text("[] has been pulled from []'s grip by []", G.affecting, G.assailant, src), 1)
//G = null
qdel(G)
else
@@ -847,7 +847,7 @@
return tally
/mob/living/proc/can_use_guns(var/obj/item/weapon/gun/G)
- if(G.trigger_guard != TRIGGER_GUARD_ALLOW_ALL && !IsAdvancedToolUser())
+ if(G.trigger_guard != TRIGGER_GUARD_ALLOW_ALL && !IsAdvancedToolUser() && !issmall(src))
to_chat(src, "You don't have the dexterity to do this!")
return 0
return 1
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 609d166183d..bdca022648e 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -81,7 +81,7 @@
var/throw_damage = I.throwforce*(speed/5)
- src.visible_message("\red [src] has been hit by [I].")
+ src.visible_message("[src] has been hit by [I].")
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].", I.armour_penetration)
apply_damage(throw_damage, dtype, zone, armor, is_sharp(I), has_edge(I), I)
@@ -102,7 +102,7 @@
var/momentum = speed/2
var/dir = get_dir(I.throw_source, src)
- visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!")
+ visible_message("[src] staggers under the impact!","You stagger under the impact!")
src.throw_at(get_edge_target_turf(src,dir),1,momentum)
if(!W || !src) return
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index 23b7abe06d3..397ce90af6c 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -56,4 +56,6 @@
var/obj/effect/proc_holder/ranged_ability //Any ranged ability the mob has, as a click override
+ var/tesla_ignore = FALSE
+
var/list/say_log = list() //a log of what we've said, plain text, no spans or junk, essentially just each individual "message"
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 1e34b43e583..81664f631d4 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -331,7 +331,7 @@ proc/get_radio_key_from_channel(var/channel)
else //everything else failed, emote is probably invalid
if(act == "help") return //except help, because help is handled individually
- to_chat(src, "\blue Unusable emote '[act]'. Say *help for a list.")
+ to_chat(src, "Unusable emote '[act]'. Say *help for a list.")
/mob/living/whisper(message as text)
message = trim_strip_html_properly(message)
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 3235c6899c1..06021939ac9 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -246,7 +246,7 @@ var/list/ai_verbs_default = list(
ai_list -= src
shuttle_caller_list -= src
shuttle_master.autoEvac()
- qdel(eyeobj) // No AI, no Eye
+ QDEL_NULL(eyeobj) // No AI, no Eye
malfhack = null
return ..()
@@ -299,22 +299,59 @@ var/list/ai_verbs_default = list(
for(var/i = 1 to Entry.len)
Entry[i] = trim(Entry[i])
- if(Entry.len < 2)
+ if(Entry.len < 2 || Entry[1] != "ai") //ignore incorrectly formatted entries or entries that aren't marked for AI
continue
- if(Entry.len < 3 && Entry[1] == ckey && Entry[2] == real_name)
- custom_sprite = 1 //They're in the list? Custom sprite time
- icon = 'icons/mob/custom-synthetic.dmi'
+ if(Entry[2] == ckey) //They're in the list? Custom sprite time, var and icon change required
+ custom_sprite = 1
+ var/display_choices = list(
+ "Monochrome",
+ "Blue",
+ "Clown",
+ "Inverted",
+ "Text",
+ "Smiley",
+ "Angry",
+ "Dorf",
+ "Matrix",
+ "Bliss",
+ "Firewall",
+ "Green",
+ "Red",
+ "Static",
+ "Triumvirate",
+ "Triumvirate Static",
+ "Red October",
+ "Sparkles",
+ "ANIMA",
+ "President",
+ "NT",
+ "NT2",
+ "Rainbow",
+ "Angel",
+ "Heartline",
+ "Hades",
+ "Helios",
+ "Syndicat Meow",
+ "Too Deep",
+ "Goon",
+ "Murica",
+ "Fuzzy",
+ "Glitchman",
+ "House",
+ "Database"
+ )
+ if(custom_sprite)
+ display_choices += "Custom"
//if(icon_state == initial(icon_state))
var/icontype = ""
- if(custom_sprite == 1)
- icontype = ("Custom")//automagically selects custom sprite if one is available
- else
- icontype = input("Select an icon!", "AI", null, null) in list("Monochrome", "Blue", "Clown", "Inverted", "Text", "Smiley", "Angry", "Dorf", "Matrix", "Bliss", "Firewall", "Green", "Red", "Static", "Triumvirate", "Triumvirate Static", "Red October", "Sparkles", "ANIMA", "President", "NT", "NT2", "Rainbow", "Angel", "Heartline", "Hades", "Helios", "Syndicat Meow", "Too Deep", "Goon", "Murica", "Fuzzy", "Glitchman", "House", "Database")
+ icontype = input("Select an icon!", "AI", null, null) in display_choices
+ icon = 'icons/mob/AI.dmi' //reset this in case we were on a custom sprite and want to change to a standard one
switch(icontype)
if("Custom")
+ icon = 'icons/mob/custom_synthetic/custom-synthetic.dmi' //set this here so we can use the custom_sprite
icon_state = "[ckey]-ai"
if("Clown")
icon_state = "ai-clown"
@@ -618,9 +655,10 @@ var/list/ai_verbs_default = list(
sleep(40)
continue
- return
-
- return
+ else if(href_list["open"])
+ var/mob/target = locate(href_list["open"]) in mob_list
+ if(target)
+ open_nearest_door(target)
/mob/living/silicon/ai/bullet_act(var/obj/item/projectile/Proj)
..(Proj)
@@ -799,7 +837,7 @@ var/list/ai_verbs_default = list(
if(network in C.network)
U.eyeobj.setLoc(get_turf(C))
break
- to_chat(src, "\blue Switched to [network] camera network.")
+ to_chat(src, "Switched to [network] camera network.")
//End of code by Mord_Sith
@@ -858,10 +896,10 @@ var/list/ai_verbs_default = list(
for(var/i = 1 to Entry.len)
Entry[i] = trim(Entry[i])
- if(Entry.len < 3)
+ if(Entry.len < 2 || Entry[1] != "hologram")
continue
- if (Entry[1] == ckey && Entry[2] == real_name && Entry[3] == "Hologram") //Custom holograms
+ if (Entry[2] == ckey) //Custom holograms
custom_hologram = 1 // option is given in hologram menu
var/input
@@ -970,10 +1008,10 @@ var/list/ai_verbs_default = list(
if("ancient machine")
holo_icon = getHologramIcon(icon('icons/mob/ancient_machine.dmi', "ancient_machine"))
if("custom")
- if("[ckey]-ai-holo" in icon_states('icons/mob/custom-synthetic.dmi'))
- holo_icon = getHologramIcon(icon('icons/mob/custom-synthetic.dmi', "[ckey]-ai-holo"))
- else if("[ckey]-ai-holo" in icon_states('icons/mob/custom-synthetic64.dmi'))
- holo_icon = getHologramIcon(icon('icons/mob/custom-synthetic64.dmi', "[ckey]-ai-holo"))
+ if("[ckey]-ai-holo" in icon_states('icons/mob/custom_synthetic/custom-synthetic.dmi'))
+ holo_icon = getHologramIcon(icon('icons/mob/custom_synthetic/custom-synthetic.dmi', "[ckey]-ai-holo"))
+ else if("[ckey]-ai-holo" in icon_states('icons/mob/custom_synthetic/custom-synthetic64.dmi'))
+ holo_icon = getHologramIcon(icon('icons/mob/custom_synthetic/custom-synthetic64.dmi', "[ckey]-ai-holo"))
else
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo1"))
@@ -985,7 +1023,7 @@ var/list/ai_verbs_default = list(
var/obj/machinery/power/apc/apc = loc
if(!istype(apc))
- to_chat(src, "\blue You are already in your Main Core.")
+ to_chat(src, "You are already in your Main Core.")
return
apc.malfvacate()
@@ -1060,19 +1098,19 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/wrench))
if(anchored)
- user.visible_message("\blue \The [user] starts to unbolt \the [src] from the plating...")
- if(!do_after(user,40, target = src))
- user.visible_message("\blue \The [user] decides not to unbolt \the [src].")
+ user.visible_message("\The [user] starts to unbolt \the [src] from the plating...")
+ if(!do_after(user, 40 * W.toolspeed, target = src))
+ user.visible_message("\The [user] decides not to unbolt \the [src].")
return
- user.visible_message("\blue \The [user] finishes unfastening \the [src]!")
+ user.visible_message("\The [user] finishes unfastening \the [src]!")
anchored = 0
return
else
- user.visible_message("\blue \The [user] starts to bolt \the [src] to the plating...")
- if(!do_after(user,40, target = src))
- user.visible_message("\blue \The [user] decides not to bolt \the [src].")
+ user.visible_message("\The [user] starts to bolt \the [src] to the plating...")
+ if(!do_after(user, 40 * W.toolspeed, target = src))
+ user.visible_message("\The [user] decides not to bolt \the [src].")
return
- user.visible_message("\blue \The [user] finishes fastening down \the [src]!")
+ user.visible_message("\The [user] finishes fastening down \the [src]!")
anchored = 1
return
else
@@ -1092,52 +1130,6 @@ var/list/ai_verbs_default = list(
aiRadio.interact(src)
-/mob/living/silicon/ai/proc/open_nearest_door(mob/living/target)
- if(!istype(target))
- return
- spawn(0)
- if(ishuman(target))
- var/mob/living/carbon/human/H = target
- var/obj/item/weapon/card/id/id = H.wear_id
- if(istype(id) && id.is_untrackable())
- to_chat(src, "Unable to locate an airlock")
- return
- if(H.digitalcamo)
- to_chat(src, "Unable to locate an airlock")
- return
- if(!near_camera(target))
- to_chat(src, "Target is not near any active cameras.")
- return
- var/obj/machinery/door/airlock/tobeopened
- var/dist = -1
- for(var/obj/machinery/door/airlock/D in range(3,target))
- if(!D.density)
- continue
- if(dist < 0)
- dist = get_dist(D, target)
-// to_chat(world, dist)
- tobeopened = D
- else
- if(dist > get_dist(D, target))
- dist = get_dist(D, target)
-// to_chat(world, dist)
- tobeopened = D
-// to_chat(world, "found [tobeopened.name] closer")
- else
-// to_chat(world, "[D.name] not close enough | [get_dist(D, target)] | [dist]")
- if(tobeopened)
- switch(alert(src, "Do you want to open \the [tobeopened] for [target]?","Doorknob_v2a.exe","Yes","No"))
- if("Yes")
- var/nhref = "src=[tobeopened.UID()];aiEnable=7"
- tobeopened.Topic(nhref, params2list(nhref), tobeopened, 1)
- to_chat(src, "\blue You've opened \the [tobeopened] for [target].")
- if("No")
- to_chat(src, "\red You deny the request.")
- else
- to_chat(src, "\red You've failed to open an airlock for [target]")
- return
-
-
/mob/living/silicon/ai/proc/check_unable(flags = 0)
if(stat == DEAD)
to_chat(usr, "You are dead!")
@@ -1234,3 +1226,37 @@ var/list/ai_verbs_default = list(
view_core() //A BYOND bug requires you to be viewing your core before your verbs update
verbs += /mob/living/silicon/ai/proc/choose_modules
malf_picker = new /datum/module_picker
+
+/mob/living/silicon/ai/proc/open_nearest_door(mob/living/target)
+ if(!istype(target))
+ return
+
+ if(target && target.can_track())
+ var/obj/machinery/door/airlock/A = null
+
+ var/dist = -1
+ for(var/obj/machinery/door/airlock/D in range(3, target))
+ if(!D.density)
+ continue
+
+ var/curr_dist = get_dist(D, target)
+
+ if(dist < 0)
+ dist = curr_dist
+ A = D
+ else if(dist > curr_dist)
+ dist = curr_dist
+ A = D
+
+ if(istype(A))
+ switch(alert(src, "Do you want to open \the [A] for [target]?", "Doorknob_v2a.exe", "Yes", "No"))
+ if("Yes")
+ A.AIShiftClick()
+ to_chat(src, "You open \the [A] for [target].")
+ else
+ to_chat(src, "You deny the request.")
+ else
+ to_chat(src, "Unable to locate an airlock near [target].")
+
+ else
+ to_chat(src, "Target is not on or near any active cameras on the station.")
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm
index 94814045871..c710e4c12db 100644
--- a/code/modules/mob/living/silicon/ai/life.dm
+++ b/code/modules/mob/living/silicon/ai/life.dm
@@ -42,7 +42,6 @@
var/area/my_area = get_area(src)
if(!lacks_power())
-
if(aiRestorePowerRoutine == 2)
to_chat(src, "Alert cancelled. Power has been restored without our assistance.")
aiRestorePowerRoutine = 0
@@ -53,8 +52,6 @@
aiRestorePowerRoutine = 0
clear_fullscreen("blind")
update_sight()
-
-
else
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
@@ -74,6 +71,8 @@
if(!lacks_power())
to_chat(src, "Alert cancelled. Power has been restored without our assistance.")
aiRestorePowerRoutine = 0
+ clear_fullscreen("blind")
+ update_sight()
return
to_chat(src, "Fault confirmed: missing external power. Shutting down main control system to save power.")
sleep(20)
@@ -112,6 +111,7 @@
to_chat(src, "Alert cancelled. Power has been restored without our assistance.")
aiRestorePowerRoutine = 0
clear_fullscreen("blind")
+ update_sight()
return
switch(PRP)
diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm
index 2a3b39c1c9b..ccd0f652b68 100644
--- a/code/modules/mob/living/silicon/ai/say.dm
+++ b/code/modules/mob/living/silicon/ai/say.dm
@@ -1,3 +1,70 @@
+/*
+ * AI Saycode
+ */
+
+
+/mob/living/silicon/ai/handle_track(var/message, var/verb = "says", var/datum/language/language, var/mob/speaker = null, var/speaker_name, var/atom/follow_target, var/hard_to_hear)
+ if(hard_to_hear)
+ return
+
+ var/jobname // the mob's "job"
+ var/mob/living/carbon/human/impersonating //The crewmember being impersonated, if any.
+ var/changed_voice
+
+ if(ishuman(speaker))
+ var/mob/living/carbon/human/H = speaker
+
+ var/obj/item/weapon/card/id/id = H.wear_id
+ if((istype(id) && id.is_untrackable()) && H.HasVoiceChanger())
+ changed_voice = 1
+ var/mob/living/carbon/human/I = locate(speaker_name)
+ if(I)
+ impersonating = I
+ jobname = impersonating.get_assignment()
+ else
+ jobname = "Unknown"
+ else
+ jobname = H.get_assignment()
+
+ else if(iscarbon(speaker)) // Nonhuman carbon mob
+ jobname = "No ID"
+ else if(isAI(speaker))
+ jobname = "AI"
+ else if(isrobot(speaker))
+ jobname = "Cyborg"
+ else if(ispAI(speaker))
+ jobname = "Personal AI"
+ else if(isAutoAnnouncer(speaker))
+ var/mob/living/automatedannouncer/AA = speaker
+ jobname = AA.role
+ else
+ jobname = "Unknown"
+
+ var/track = ""
+ var/mob/mob_to_track = null
+ if(changed_voice)
+ if(impersonating)
+ mob_to_track = impersonating
+ else
+ track = "[speaker_name] ([jobname])"
+ else
+ if(istype(follow_target, /mob/living/simple_animal/bot))
+ track = "[speaker_name] ([jobname])"
+ else
+ mob_to_track = speaker
+
+ if(mob_to_track)
+ track = "[speaker_name] ([jobname])"
+ track += "\[OPEN\]"
+
+ return track
+
+
+
+/*
+ * AI VOX Announcements
+ */
+
var/announcing_vox = 0 // Stores the time of the last announcement
var/const/VOX_CHANNEL = 200
var/const/VOX_DELAY = 100
diff --git a/code/modules/mob/living/silicon/emote.dm b/code/modules/mob/living/silicon/emote.dm
index 9e95b9cefaa..3385c4ce622 100644
--- a/code/modules/mob/living/silicon/emote.dm
+++ b/code/modules/mob/living/silicon/emote.dm
@@ -26,97 +26,51 @@
switch(act)
if("ping","pings")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] pings at [param]."
- else
- message = "[src] pings."
+ message = "[src] pings[M ? " at [M]" : ""]."
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
m_type = 2
if("buzz","buzzs","buzzes")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] buzzes at [param]."
- else
- message = "[src] buzzes."
+ message = "[src] buzzes[M ? " at [M]" : ""]."
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
m_type = 2
if("beep","beeps")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] beeps at [param]."
- else
- message = "[src] beeps."
+ message = "[src] beeps[M ? " at [M]" : ""]."
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
m_type = 2
if("yes")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] emits an affirmative blip at [param]."
- else
- message = "[src] emits an affirmative blip."
+ message = "[src] emits an affirmative blip[M ? " at [M]" : ""]."
playsound(src.loc, 'sound/machines/synth_yes.ogg', 50, 0)
m_type = 2
if("no")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] emits a negative blip at [param]."
- else
- message = "[src] emits a negative blip."
+ message = "[src] emits a negative blip[M ? " at [M]" : ""]."
playsound(src.loc, 'sound/machines/synth_no.ogg', 50, 0)
m_type = 2
if("scream", "screams")
- message = "[src] screams!"
+ var/M = handle_emote_param(param)
+
+ message = "[src] screams[M ? " at [M]" : ""]!"
playsound(src.loc, 'sound/goonstation/voice/robot_scream.ogg', 80, 0)
m_type = 2
if("buzz2")
- message = "[src] emits an irritated buzzing sound."
+ var/M = handle_emote_param(param)
+
+ message = "[src] emits an irritated buzzing sound[M ? " at [M]" : ""]."
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0)
m_type = 2
@@ -124,4 +78,4 @@
if("help")
to_chat(src, "yes, no, beep, ping, buzz, scream, buzz2")
- ..(act, m_type, message)
\ No newline at end of file
+ ..(act, m_type, message)
diff --git a/code/modules/mob/living/silicon/pai/life.dm b/code/modules/mob/living/silicon/pai/life.dm
index c0e4c2f275b..ec40dff7739 100644
--- a/code/modules/mob/living/silicon/pai/life.dm
+++ b/code/modules/mob/living/silicon/pai/life.dm
@@ -14,7 +14,7 @@
if(get_dist(src, cable) > 1)
var/turf/T = get_turf_or_move(loc)
for(var/mob/M in viewers(T))
- M.show_message("\red The data cable rapidly retracts back into its spool.", 3, "\red You hear a click and the sound of wire spooling rapidly.", 2)
+ M.show_message("The data cable rapidly retracts back into its spool.", 3, "You hear a click and the sound of wire spooling rapidly.", 2)
qdel(src.cable)
cable = null
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 125eb110c66..5218d399007 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -81,6 +81,7 @@
var/translator_on = 0 // keeps track of the translator module
var/current_pda_messaging = null
+ var/custom_sprite = 0
/mob/living/silicon/pai/New(var/obj/item/device/paicard)
loc = paicard
@@ -172,7 +173,7 @@
if(prob(20))
var/turf/T = get_turf_or_move(loc)
for(var/mob/M in viewers(T))
- M.show_message("\red A shower of sparks spray from [src]'s inner workings.", 3, "\red You hear and smell the ozone hiss of electrical sparks being expelled violently.", 2)
+ M.show_message("A shower of sparks spray from [src]'s inner workings.", 3, "You hear and smell the ozone hiss of electrical sparks being expelled violently.", 2)
return death(0)
switch(pick(1,2,3))
@@ -241,7 +242,7 @@
if(I_HELP)
for(var/mob/O in viewers(src, null))
if((O.client && !( O.blinded )))
- O.show_message(text("\blue [M] caresses [src]'s casing with its scythe like arm."), 1)
+ O.show_message(text("[M] caresses [src]'s casing with its scythe like arm."), 1)
else //harm
M.do_attack_animation(src)
@@ -319,7 +320,7 @@
cameralist[C.network] = C.network
network = input(usr, "Which network would you like to view?") as null|anything in cameralist
- to_chat(src, "\blue Switched to [network] camera network.")
+ to_chat(src, "Switched to [network] camera network.")
//End of code by Mord_Sith
*/
@@ -394,17 +395,47 @@
set category = "pAI Commands"
set name = "Choose Chassis"
+ var/list/my_choices = list()
var/choice
var/finalized = "No"
+
+ //check for custom_sprite
+ if(!custom_sprite)
+ var/file = file2text("config/custom_sprites.txt")
+ var/lines = splittext(file, "\n")
+
+ for(var/line in lines)
+ // split & clean up
+ var/list/Entry = splittext(line, ":")
+ for(var/i = 1 to Entry.len)
+ Entry[i] = trim(Entry[i])
+
+ if(Entry.len < 2 || Entry[1] != "pai") //ignore incorrectly formatted entries or entries that aren't marked for pAI
+ continue
+
+ if(Entry[2] == ckey) //They're in the list? Custom sprite time, var and icon change required
+ custom_sprite = 1
+ my_choices["Custom"] = "[ckey]-pai"
+
+ my_choices = possible_chassis.Copy()
+ if(custom_sprite)
+ my_choices["Custom"] = "[ckey]-pai"
+
+ if(loc == card) //don't let them continue in card form, since they won't be able to actually see their new mobile form sprite.
+ to_chat(src, "You must be in your mobile form to reconfigure your chassis.")
+ return
+
while(finalized == "No" && client)
-
- choice = input(usr,"What would you like to use for your mobile chassis icon? This decision can only be made once.") as null|anything in possible_chassis
+ choice = input(usr,"What would you like to use for your mobile chassis icon? This decision can only be made once.") as null|anything in my_choices
if(!choice) return
-
- icon_state = possible_chassis[choice]
+ if(choice == "Custom")
+ icon = 'icons/mob/custom_synthetic/custom-synthetic.dmi'
+ else
+ icon = 'icons/mob/pai.dmi'
+ icon_state = my_choices[choice]
finalized = alert("Look at your sprite. Is this what you wish to use?",,"No","Yes")
- chassis = possible_chassis[choice]
+ chassis = my_choices[choice]
verbs -= /mob/living/silicon/pai/proc/choose_chassis
/mob/living/silicon/pai/proc/choose_verbs()
@@ -562,15 +593,23 @@
// Handle being picked up.
-/mob/living/silicon/pai/get_scooped(var/mob/living/carbon/grabber)
+/mob/living/silicon/pai/get_scooped(mob/living/carbon/grabber)
var/obj/item/weapon/holder/H = ..()
if(!istype(H))
return
if(resting)
icon_state = "[chassis]"
resting = 0
- H.icon_state = "pai-[icon_state]"
- H.item_state = "pai-[icon_state]"
+ if(custom_sprite)
+ H.icon = 'icons/mob/custom_synthetic/custom-synthetic.dmi'
+ H.icon_override = 'icons/mob/custom_synthetic/custom_head.dmi'
+ H.lefthand_file = 'icons/mob/custom_synthetic/custom_lefthand.dmi'
+ H.righthand_file = 'icons/mob/custom_synthetic/custom_righthand.dmi'
+ H.icon_state = "[icon_state]"
+ H.item_state = "[icon_state]_hand"
+ else
+ H.icon_state = "pai-[icon_state]"
+ H.item_state = "pai-[icon_state]"
grabber.put_in_active_hand(H)//for some reason unless i call this it dosen't work
grabber.update_inv_l_hand()
grabber.update_inv_r_hand()
diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm
index fdc1ace289c..4c52f2f415d 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone.dm
@@ -15,7 +15,7 @@
req_access = list(access_engine, access_robotics)
ventcrawler = 2
magpulse = 1
-
+
default_language = "Drone"
// We need to keep track of a few module items so we don't need to do list operations
@@ -23,7 +23,7 @@
var/obj/item/stack/sheet/metal/cyborg/stack_metal = null
var/obj/item/stack/sheet/wood/stack_wood = null
var/obj/item/stack/sheet/glass/cyborg/stack_glass = null
- var/obj/item/stack/sheet/mineral/plastic/cyborg/stack_plastic = null
+ var/obj/item/stack/sheet/plastic/stack_plastic = null
var/obj/item/weapon/matter_decompiler/decompiler = null
//Used for self-mailing.
@@ -43,7 +43,7 @@
remove_language("Galactic Common")
add_language("Drone Talk", 1)
add_language("Drone", 1)
-
+
// Disable the microphone wire on Drones
if(radio)
radio.wires.CutWireIndex(WIRE_TRANSMIT)
@@ -70,7 +70,7 @@
stack_metal = locate(/obj/item/stack/sheet/metal/cyborg) in src.module
stack_wood = locate(/obj/item/stack/sheet/wood) in src.module
stack_glass = locate(/obj/item/stack/sheet/glass/cyborg) in src.module
- stack_plastic = locate(/obj/item/stack/sheet/mineral/plastic/cyborg) in src.module
+ stack_plastic = locate(/obj/item/stack/sheet/plastic) in src.module
//Grab decompiler.
decompiler = locate(/obj/item/weapon/matter_decompiler) in src.module
@@ -115,7 +115,7 @@
/mob/living/silicon/robot/drone/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/borg/upgrade/))
- to_chat(user, "\red The maintenance drone chassis not compatible with \the [W].")
+ to_chat(user, "The maintenance drone chassis not compatible with \the [W].")
return
else if(istype(W, /obj/item/weapon/crowbar))
@@ -127,20 +127,20 @@
if(stat == 2)
if(!config.allow_drone_spawn || emagged || health < -35) //It's dead, Dave.
- to_chat(user, "\red The interface is fried, and a distressing burned smell wafts from the robot's interior. You're not rebooting this one.")
+ to_chat(user, "The interface is fried, and a distressing burned smell wafts from the robot's interior. You're not rebooting this one.")
return
if(!allowed(usr))
- to_chat(user, "\red Access denied.")
+ to_chat(user, "Access denied.")
return
var/delta = (world.time / 10) - last_reboot
if(reboot_cooldown > delta)
var/cooldown_time = round(reboot_cooldown - ((world.time / 10) - last_reboot), 1)
- to_chat(usr, "\red The reboot system is currently offline. Please wait another [cooldown_time] seconds.")
+ to_chat(usr, "The reboot system is currently offline. Please wait another [cooldown_time] seconds.")
return
- user.visible_message("\red \the [user] swipes \his ID card through \the [src], attempting to reboot it.", "\red You swipe your ID card through \the [src], attempting to reboot it.")
+ user.visible_message("\the [user] swipes \his ID card through \the [src], attempting to reboot it.", "You swipe your ID card through \the [src], attempting to reboot it.")
last_reboot = world.time / 10
var/drones = 0
for(var/mob/living/silicon/robot/drone/D in world)
@@ -151,7 +151,7 @@
return
else
- user.visible_message("\red \the [user] swipes \his ID card through \the [src], attempting to shut it down.", "\red You swipe your ID card through \the [src], attempting to shut it down.")
+ user.visible_message("\the [user] swipes \his ID card through \the [src], attempting to shut it down.", "You swipe your ID card through \the [src], attempting to shut it down.")
if(emagged)
return
@@ -159,7 +159,7 @@
if(allowed(usr))
shut_down()
else
- to_chat(user, "\red Access denied.")
+ to_chat(user, "Access denied.")
return
@@ -167,7 +167,7 @@
/mob/living/silicon/robot/drone/emag_act(user as mob)
if(!client || stat == 2)
- to_chat(user, "\red There's not much point subverting this heap of junk.")
+ to_chat(user, "There's not much point subverting this heap of junk.")
return
if(!ishuman(user))
@@ -175,12 +175,12 @@
var/mob/living/carbon/human/H = user
if(emagged)
- to_chat(src, "\red [user] attempts to load subversive software into you, but your hacked subroutined ignore the attempt.")
- to_chat(user, "\red You attempt to subvert [src], but the sequencer has no effect.")
+ to_chat(src, "[user] attempts to load subversive software into you, but your hacked subroutined ignore the attempt.")
+ to_chat(user, "You attempt to subvert [src], but the sequencer has no effect.")
return
- to_chat(user, "\red You swipe the sequencer across [src]'s interface and watch its eyes flicker.")
- to_chat(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.")
+ to_chat(user, "You swipe the sequencer across [src]'s interface and watch its eyes flicker.")
+ to_chat(src, "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.")
@@ -197,7 +197,7 @@
to_chat(src, "Obey these laws:")
laws.show_laws(src)
- to_chat(src, "\red \b ALERT: [H.real_name] is your new master. Obey your new laws and his commands.")
+ to_chat(src, "ALERT: [H.real_name] is your new master. Obey your new laws and his commands.")
return
//DRONE LIFE/DEATH
@@ -236,18 +236,18 @@
/mob/living/silicon/robot/drone/proc/law_resync()
if(stat != 2)
if(emagged)
- to_chat(src, "\red You feel something attempting to modify your programming, but your hacked subroutines are unaffected.")
+ to_chat(src, "You feel something attempting to modify your programming, but your hacked subroutines are unaffected.")
else
- to_chat(src, "\red A reset-to-factory directive packet filters through your data connection, and you obediently modify your programming to suit it.")
+ to_chat(src, "A reset-to-factory directive packet filters through your data connection, and you obediently modify your programming to suit it.")
full_law_reset()
show_laws()
/mob/living/silicon/robot/drone/proc/shut_down()
if(stat != 2)
if(emagged)
- to_chat(src, "\red You feel a system kill order percolate through your tiny brain, but it doesn't seem like a good idea to you.")
+ to_chat(src, "You feel a system kill order percolate through your tiny brain, but it doesn't seem like a good idea to you.")
else
- to_chat(src, "\red You feel a system kill order percolate through your tiny brain, and you obediently destroy yourself.")
+ to_chat(src, "You feel a system kill order percolate through your tiny brain, and you obediently destroy yourself.")
death()
/mob/living/silicon/robot/drone/proc/full_law_reset()
@@ -281,7 +281,7 @@
if(!player) return
- src.ckey = player.ckey
+ ckey = player.ckey
if(player.mob && player.mob.mind)
player.mob.mind.transfer_to(src)
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm
index d450d508bd3..f9c711b4b17 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm
@@ -10,13 +10,13 @@
mail_destination = 0
return
- to_chat(src, "\blue You configure your internal beacon, tagging yourself for delivery to '[tag]'.")
+ to_chat(src, "You configure your internal beacon, tagging yourself for delivery to '[tag]'.")
mail_destination = TAGGERLOCATIONS.Find(tag)
//Auto flush if we use this verb inside a disposal chute.
var/obj/machinery/disposal/D = src.loc
if(istype(D))
- to_chat(src, "\blue \The [D] acknowledges your signal.")
+ to_chat(src, "\The [D] acknowledges your signal.")
D.flush_count = D.flush_every_ticks
return
@@ -28,10 +28,10 @@
if(layer != TURF_LAYER+0.2)
layer = TURF_LAYER+0.2
- to_chat(src, text("\blue You are now hiding."))
+ to_chat(src, text("You are now hiding."))
else
layer = MOB_LAYER
- to_chat(src, text("\blue You have stopped hiding."))
+ to_chat(src, text("You have stopped hiding."))
/mob/living/silicon/robot/drone/verb/light()
set name = "Light On/Off"
@@ -47,4 +47,55 @@
if(M.a_intent == I_HELP)
get_scooped(M)
- ..()
\ No newline at end of file
+ ..()
+
+/mob/living/silicon/robot/drone/verb/customize()
+ set name = "Customize Chassis"
+ set desc = "Reconfigure your chassis into a customized version."
+ set category = "Drone"
+
+ if(!custom_sprite) //Check to see if custom sprite time, checking the appopriate file to change a var
+ var/file = file2text("config/custom_sprites.txt")
+ var/lines = splittext(file, "\n")
+
+ for(var/line in lines)
+ // split & clean up
+ var/list/Entry = splittext(line, ":")
+ for(var/i = 1 to Entry.len)
+ Entry[i] = trim(Entry[i])
+
+ if(Entry.len < 2 || Entry[1] != "drone")
+ continue
+
+ if (Entry[2] == ckey) //Custom holograms
+ custom_sprite = 1 // option is given in hologram menu
+
+ if(!custom_sprite)
+ to_chat(src, "Error 404: Custom chassis not found. Revoking customization option.")
+ else
+ icon = 'icons/mob/custom_synthetic/custom-synthetic.dmi'
+ icon_state = "[ckey]-drone"
+ to_chat(src, "You reconfigure your chassis and improve the station through your new aesthetics.")
+ verbs -= /mob/living/silicon/robot/drone/verb/customize
+
+/mob/living/silicon/robot/drone/get_scooped(mob/living/carbon/grabber)
+ var/obj/item/weapon/holder/H = ..()
+ if(!istype(H))
+ return
+ if(resting)
+ resting = 0
+ if(custom_sprite)
+ H.icon = 'icons/mob/custom_synthetic/custom-synthetic.dmi'
+ H.icon_override = 'icons/mob/custom_synthetic/custom_head.dmi'
+ H.lefthand_file = 'icons/mob/custom_synthetic/custom_lefthand.dmi'
+ H.righthand_file = 'icons/mob/custom_synthetic/custom_righthand.dmi'
+ H.icon_state = "[icon_state]"
+ H.item_state = "[icon_state]_hand"
+ else
+ H.icon_state = "drone"
+ H.item_state = "drone"
+ grabber.put_in_active_hand(H)//for some reason unless i call this it dosen't work
+ grabber.update_inv_l_hand()
+ grabber.update_inv_r_hand()
+
+ return H
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_console.dm b/code/modules/mob/living/silicon/robot/drone/drone_console.dm
index b46f5899561..056a65a8e66 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_console.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_console.dm
@@ -20,7 +20,7 @@
return
if(!allowed(user))
- to_chat(user, "\red Access denied.")
+ to_chat(user, "Access denied.")
return
interact(user)
@@ -54,7 +54,7 @@
return
if(!allowed(usr))
- to_chat(usr, "\red Access denied.")
+ to_chat(usr, "Access denied.")
return
if((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
@@ -69,11 +69,11 @@
return
drone_call_area = t_area
- to_chat(usr, "\blue You set the area selector to [drone_call_area].")
+ to_chat(usr, "You set the area selector to [drone_call_area].")
else if(href_list["ping"])
- to_chat(usr, "\blue You issue a maintenance request for all active drones, highlighting [drone_call_area].")
+ to_chat(usr, "You issue a maintenance request for all active drones, highlighting [drone_call_area].")
for(var/mob/living/silicon/robot/drone/D in world)
if(D.client && D.stat == 0)
to_chat(D, "-- Maintenance drone presence requested in: [drone_call_area].")
@@ -83,7 +83,7 @@
var/mob/living/silicon/robot/drone/D = locate(href_list["resync"])
if(D.stat != 2)
- to_chat(usr, "\red You issue a law synchronization directive for the drone.")
+ to_chat(usr, "You issue a law synchronization directive for the drone.")
D.law_resync()
else if(href_list["shutdown"])
@@ -91,7 +91,7 @@
var/mob/living/silicon/robot/drone/D = locate(href_list["shutdown"])
if(D.stat != 2)
- to_chat(usr, "\red You issue a kill command for the unfortunate drone.")
+ to_chat(usr, "You issue a kill command for the unfortunate drone.")
message_admins("[key_name_admin(usr)] issued kill order for drone [key_name_admin(D)] from control console.")
log_game("[key_name(usr)] issued kill order for [key_name(src)] from control console.")
D.shut_down()
@@ -100,16 +100,16 @@
if(dronefab)
return
- for(var/obj/machinery/drone_fabricator/fab in oview(3,src))
+ for(var/obj/machinery/drone_fabricator/fab in get_area(src))
if(fab.stat & NOPOWER)
continue
dronefab = fab
- to_chat(usr, "\blue Drone fabricator located.")
+ to_chat(usr, "Drone fabricator located.")
return
- to_chat(usr, "\red Unable to locate drone fabricator.")
+ to_chat(usr, "Unable to locate drone fabricator.")
else if(href_list["toggle_fab"])
@@ -118,10 +118,10 @@
if(get_dist(src,dronefab) > 3)
dronefab = null
- to_chat(usr, "\red Unable to locate drone fabricator.")
+ to_chat(usr, "Unable to locate drone fabricator.")
return
dronefab.produce_drones = !dronefab.produce_drones
- to_chat(usr, "\blue You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator.")
+ to_chat(usr, "You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator.")
src.updateUsrDialog()
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm
index 3df660dc117..7148f780ff3 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm
@@ -12,6 +12,7 @@
/obj/item/weapon/firealarm_electronics,
/obj/item/weapon/airalarm_electronics,
/obj/item/weapon/airlock_electronics,
+ /obj/item/weapon/firelock_electronics,
/obj/item/weapon/intercom_electronics,
/obj/item/weapon/apc_electronics,
/obj/item/weapon/stock_parts,
@@ -26,7 +27,8 @@
/obj/item/weapon/camera_assembly,
/obj/item/weapon/tank,
/obj/item/weapon/circuitboard,
- /obj/item/stack/tile/light
+ /obj/item/stack/tile/light,
+ /obj/item/weapon/ore/bluespace_crystal
)
//Item currently being held.
@@ -45,6 +47,10 @@
/obj/item/weapon/card/id
)
+/obj/item/weapon/gripper/New()
+ ..()
+ can_hold = typecacheof(can_hold)
+
/obj/item/weapon/gripper/attack_self(mob/user as mob)
if(wrapped)
wrapped.attack_self(user)
@@ -118,10 +124,9 @@
//Check if the item is blacklisted.
var/grab = 0
- for(var/typepath in can_hold)
- if(istype(I,typepath))
+ if(can_hold.len)
+ if(is_type_in_typecache(I, can_hold))
grab = 1
- break
//We can grab the item, finally.
if(grab)
@@ -200,7 +205,7 @@
to_chat(D, "You begin decompiling the other drone.")
- if(!do_after(D,50, target = target))
+ if(!do_after(D, 50, target = target))
to_chat(D, "You need to remain still while decompiling such a large object.")
return
@@ -224,7 +229,7 @@
//Different classes of items give different commodities.
if(istype(W,/obj/item/weapon/cigbutt))
stored_comms["plastic"]++
- else if(istype(W,/obj/effect/spider/spiderling))
+ else if(istype(W,/obj/structure/spider/spiderling))
stored_comms["wood"]++
stored_comms["wood"]++
stored_comms["plastic"]++
@@ -369,7 +374,7 @@
stack = stack_wood
if("plastic")
if(!stack_plastic)
- stack_plastic = new /obj/item/stack/sheet/mineral/plastic/cyborg(src.module)
+ stack_plastic = new /obj/item/stack/sheet/plastic(src.module)
stack_plastic.amount = 1
stack = stack_plastic
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
index aeed17ef9fd..187a32633b6 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
@@ -85,7 +85,7 @@
set desc = "If there is a powered, enabled fabricator in the game world with a prepared chassis, join as a maintenance drone."
if(!(config.allow_drone_spawn))
- to_chat(src, "\red That verb is not currently permitted.")
+ to_chat(src, "That verb is not currently permitted.")
return
if(!src.stat)
@@ -95,7 +95,7 @@
return 0 //something is terribly wrong
if(jobban_isbanned(src,"nonhumandept") || jobban_isbanned(src,"Drone"))
- to_chat(usr, "\red You are banned from playing drones and cannot spawn as a drone.")
+ to_chat(usr, "You are banned from playing drones and cannot spawn as a drone.")
return
if(!ticker || ticker.current_state < 3)
@@ -141,11 +141,11 @@
continue
if(DF.count_drones() >= config.max_maint_drones)
- to_chat(src, "\red There are too many active drones in the world for you to spawn.")
+ to_chat(src, "There are too many active drones in the world for you to spawn.")
return
if(DF.drone_progress >= 100)
DF.create_drone(src.client)
return
- to_chat(src, "\red There are no available drone spawn points, sorry.")
+ to_chat(src, "There are no available drone spawn points, sorry.")
diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm
index afa2d0667c4..f42f19b67fa 100644
--- a/code/modules/mob/living/silicon/robot/life.dm
+++ b/code/modules/mob/living/silicon/robot/life.dm
@@ -229,7 +229,7 @@
weaponlock_time --
if(weaponlock_time <= 0)
if(src.client)
- to_chat(src, "\red Weapon Lock Timed Out!")
+ to_chat(src, "Weapon Lock Timed Out!")
weapon_lock = 0
weaponlock_time = 120
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 2840e7b381c..2b0ded32896 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -180,16 +180,15 @@ var/list/robot_verbs_default = list(
for(var/line in lines)
// split & clean up
- var/list/Entry = splittext(line, ";")
+ var/list/Entry = splittext(line, ":")
for(var/i = 1 to Entry.len)
Entry[i] = trim(Entry[i])
- if(Entry.len < 2)
- continue;
+ if(Entry.len < 2 || Entry[1] != "cyborg") //ignore incorrectly formatted entries or entries that aren't marked for cyborg
+ continue
- if(Entry[1] == src.ckey && Entry[2] == src.real_name) //They're in the list? Custom sprite time, var and icon change required
+ if(Entry[2] == ckey) //They're in the list? Custom sprite time, var and icon change required
custom_sprite = 1
- icon = 'icons/mob/custom-synthetic.dmi'
return 1
@@ -252,12 +251,10 @@ var/list/robot_verbs_default = list(
mmi = null
if(connected_ai)
connected_ai.connected_robots -= src
- qdel(wires)
- wires = null
- qdel(module)
- module = null
- camera = null
- cell = null
+ QDEL_NULL(wires)
+ QDEL_NULL(module)
+ QDEL_NULL(camera)
+ QDEL_NULL(cell)
return ..()
/mob/living/silicon/robot/proc/pick_module()
@@ -265,7 +262,7 @@ var/list/robot_verbs_default = list(
return
var/list/modules = list("Standard", "Engineering", "Medical", "Miner", "Janitor", "Service", "Security")
if(security_level == (SEC_LEVEL_GAMMA || SEC_LEVEL_EPSILON) || crisis)
- to_chat(src, "\red Crisis mode active. Combat module available.")
+ to_chat(src, "Crisis mode active. Combat module available.")
modules+="Combat"
if(ticker && ticker.mode && ticker.mode.name == "nations")
var/datum/game_mode/nations/N = ticker.mode
@@ -289,6 +286,7 @@ var/list/robot_verbs_default = list(
module_sprites["Basic"] = "robot_old"
module_sprites["Android"] = "droid"
module_sprites["Default"] = "robot"
+ module_sprites["Noble-STD"] = "Noble-STD"
if("Service")
module = new /obj/item/weapon/robot_module/butler(src)
@@ -299,6 +297,7 @@ var/list/robot_verbs_default = list(
module_sprites["Rich"] = "maximillion"
module_sprites["Default"] = "Service2"
module_sprites["Standard"] = "robotServ"
+ module_sprites["Noble-SRV"] = "Noble-SRV"
if("Miner")
module = new /obj/item/weapon/robot_module/miner(src)
@@ -309,6 +308,7 @@ var/list/robot_verbs_default = list(
module_sprites["Advanced Droid"] = "droid-miner"
module_sprites["Treadhead"] = "Miner"
module_sprites["Standard"] = "robotMine"
+ module_sprites["Noble-DIG"] = "Noble-DIG"
if("Medical")
module = new /obj/item/weapon/robot_module/medical(src)
@@ -320,6 +320,7 @@ var/list/robot_verbs_default = list(
module_sprites["Advanced Droid"] = "droid-medical"
module_sprites["Needles"] = "medicalrobot"
module_sprites["Standard"] = "robotMedi"
+ module_sprites["Noble-MED"] = "Noble-MED"
status_flags &= ~CANPUSH
if("Security")
@@ -330,6 +331,7 @@ var/list/robot_verbs_default = list(
module_sprites["Black Knight"] = "securityrobot"
module_sprites["Bloodhound"] = "bloodhound"
module_sprites["Standard"] = "robotSecy"
+ module_sprites["Noble-SEC"] = "Noble-SEC"
status_flags &= ~CANPUSH
if("Engineering")
@@ -341,6 +343,7 @@ var/list/robot_verbs_default = list(
module_sprites["Antique"] = "engineerrobot"
module_sprites["Landmate"] = "landmate"
module_sprites["Standard"] = "robotEngi"
+ module_sprites["Noble-ENG"] = "Noble-ENG"
magpulse = 1
if("Janitor")
@@ -350,6 +353,7 @@ var/list/robot_verbs_default = list(
module_sprites["Mopbot"] = "janitorrobot"
module_sprites["Mop Gear Rex"] = "mopgearrex"
module_sprites["Standard"] = "robotJani"
+ module_sprites["Noble-CLN"] = "Noble-CLN"
if("Combat")
module = new /obj/item/weapon/robot_module/combat(src)
@@ -422,7 +426,7 @@ var/list/robot_verbs_default = list(
set name = "Self Diagnosis"
if(!is_component_functioning("diagnosis unit"))
- to_chat(src, "\red Your self-diagnosis component isn't functioning.")
+ to_chat(src, "Your self-diagnosis component isn't functioning.")
var/dat = self_diagnosis()
src << browse(dat, "window=robotdiagnosis")
@@ -447,10 +451,10 @@ var/list/robot_verbs_default = list(
var/datum/robot_component/C = components[toggle]
if(C.toggled)
C.toggled = 0
- to_chat(src, "\red You disable [C.name].")
+ to_chat(src, "You disable [C.name].")
else
C.toggled = 1
- to_chat(src, "\red You enable [C.name].")
+ to_chat(src, "You enable [C.name].")
/mob/living/silicon/robot/proc/sensor_mode()
set name = "Set Sensor Augmentation"
@@ -597,7 +601,7 @@ var/list/robot_verbs_default = list(
C.brute_damage = WC.brute
C.electronics_damage = WC.burn
- to_chat(usr, "\blue You install the [W.name].")
+ to_chat(usr, "You install the [W.name].")
return
@@ -610,7 +614,7 @@ var/list/robot_verbs_default = list(
var/obj/item/weapon/weldingtool/WT = W
user.changeNext_move(CLICK_CD_MELEE)
if(WT.remove_fuel(0))
- playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(src.loc, W.usesound, 50, 1)
adjustBruteLoss(-30)
updatehealth()
add_fingerprint(user)
@@ -644,7 +648,7 @@ var/list/robot_verbs_default = list(
return
to_chat(user, "You jam the crowbar into the robot and begin levering [mmi].")
- if(do_after(user,3 SECONDS, target = src))
+ if(do_after(user, 30 * W.toolspeed, target = src))
to_chat(user, "You damage some parts of the chassis, but eventually manage to rip out [mmi]!")
var/obj/item/robot_parts/robot_suit/C = new/obj/item/robot_parts/robot_suit(loc)
C.l_leg = new/obj/item/robot_parts/l_leg(C)
@@ -798,22 +802,22 @@ var/list/robot_verbs_default = list(
var/time = time2text(world.realtime,"hh:mm:ss")
lawchanges.Add("[time] : [M.name]([M.key]) emagged [name]([key])")
set_zeroth_law("Only [M.real_name] and people he designates as being such are Syndicate Agents.")
- to_chat(src, "\red ALERT: Foreign software detected.")
+ to_chat(src, "ALERT: Foreign software detected.")
sleep(5)
- to_chat(src, "\red Initiating diagnostics...")
+ to_chat(src, "Initiating diagnostics...")
sleep(20)
- to_chat(src, "\red SynBorg v1.7 loaded.")
+ to_chat(src, "SynBorg v1.7 loaded.")
sleep(5)
- to_chat(src, "\red LAW SYNCHRONISATION ERROR")
+ to_chat(src, "LAW SYNCHRONISATION ERROR")
sleep(5)
- to_chat(src, "\red Would you like to send a report to NanoTraSoft? Y/N")
+ to_chat(src, "Would you like to send a report to NanoTraSoft? Y/N")
sleep(10)
- to_chat(src, "\red > N")
+ to_chat(src, "> N")
sleep(20)
- to_chat(src, "\red ERRORERRORERROR")
+ to_chat(src, "ERRORERRORERROR")
to_chat(src, "Obey these laws:")
laws.show_laws(src)
- to_chat(src, "\red \b ALERT: [M.real_name] is your new master. Obey your new laws and his commands.")
+ to_chat(src, "ALERT: [M.real_name] is your new master. Obey your new laws and his commands.")
SetLockdown(0)
if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner))
for(var/obj/item/weapon/pickaxe/drill/cyborg/D in src.module.modules)
@@ -938,9 +942,11 @@ var/list/robot_verbs_default = list(
adjustStaminaLoss(damage)
updatehealth()
+/mob/living/silicon/robot/attack_ghost(mob/user)
+ if(wiresexposed)
+ wires.Interact(user)
/mob/living/silicon/robot/attack_hand(mob/user)
-
add_fingerprint(user)
if(opened && !wiresexposed && (!istype(user, /mob/living/silicon)))
@@ -1004,7 +1010,7 @@ var/list/robot_verbs_default = list(
/mob/living/silicon/robot/proc/installed_modules()
if(weapon_lock)
- to_chat(src, "\red Weapon lock active, unable to use modules! Count:[weaponlock_time]")
+ to_chat(src, "Weapon lock active, unable to use modules! Count:[weaponlock_time]")
return
if(!module)
@@ -1243,15 +1249,14 @@ var/list/robot_verbs_default = list(
triesleft--
var/icontype
-
- if(custom_sprite == 1)
- icontype = "Custom"
- triesleft = 0
- else
- lockcharge = 1 //Locks borg until it select an icon to avoid secborgs running around with a standard sprite
- icontype = input("Select an icon! [triesleft ? "You have [triesleft] more chances." : "This is your last try."]", "Robot", null, null) in module_sprites
+ lockcharge = 1 //Locks borg until it select an icon to avoid secborgs running around with a standard sprite
+ icontype = input("Select an icon! [triesleft ? "You have [triesleft] more chances." : "This is your last try."]", "Robot", null, null) in module_sprites
if(icontype)
+ if(icontype == "Custom")
+ icon = 'icons/mob/custom_synthetic/custom-synthetic.dmi'
+ else
+ icon = 'icons/mob/robots.dmi'
icon_state = module_sprites[icontype]
if(icontype == "Bro")
module.module_type = "Brobot"
diff --git a/code/modules/mob/living/silicon/robot/robot_damage.dm b/code/modules/mob/living/silicon/robot/robot_damage.dm
index 2ef7f30e45b..780a622906a 100644
--- a/code/modules/mob/living/silicon/robot/robot_damage.dm
+++ b/code/modules/mob/living/silicon/robot/robot_damage.dm
@@ -90,11 +90,11 @@
cell.charge -= cost
if(cell.charge <= 0)
cell.charge = 0
- to_chat(src, "\red Your shield has overloaded!")
+ to_chat(src, "Your shield has overloaded!")
else
brute -= absorb_brute
burn -= absorb_burn
- to_chat(src, "\red Your shield absorbs some of the impact!")
+ to_chat(src, "Your shield absorbs some of the impact!")
var/datum/robot_component/armour/A = get_armour()
if(A)
@@ -141,11 +141,11 @@
cell.charge -= cost
if(cell.charge <= 0)
cell.charge = 0
- to_chat(src, "\red Your shield has overloaded!")
+ to_chat(src, "Your shield has overloaded!")
else
brute -= absorb_brute
burn -= absorb_burn
- to_chat(src, "\red Your shield absorbs some of the impact!")
+ to_chat(src, "Your shield absorbs some of the impact!")
var/datum/robot_component/armour/A = get_armour()
if(A)
diff --git a/code/modules/mob/living/silicon/robot/robot_items.dm b/code/modules/mob/living/silicon/robot/robot_items.dm
index 84c07ee7c20..eba7e05d632 100644
--- a/code/modules/mob/living/silicon/robot/robot_items.dm
+++ b/code/modules/mob/living/silicon/robot/robot_items.dm
@@ -65,7 +65,7 @@
deploy_paper(get_turf(src))
/obj/item/weapon/form_printer/proc/deploy_paper(var/turf/T)
- T.visible_message("\blue \The [src.loc] dispenses a sheet of crisp white paper.")
+ T.visible_message("\The [src.loc] dispenses a sheet of crisp white paper.")
new /obj/item/weapon/paper(T)
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index 152ed03fec8..9365da25f8d 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -35,8 +35,7 @@
for(var/module in modules)
qdel(module)
modules.Cut()
- qdel(emag)
- emag = null
+ QDEL_NULL(emag)
return ..()
/obj/item/weapon/robot_module/proc/fix_modules()
@@ -115,8 +114,8 @@
..()
modules += new /obj/item/weapon/melee/baton/loaded(src)
modules += new /obj/item/weapon/extinguisher(src)
- modules += new /obj/item/weapon/wrench(src)
- modules += new /obj/item/weapon/crowbar(src)
+ modules += new /obj/item/weapon/wrench/cyborg(src)
+ modules += new /obj/item/weapon/crowbar/cyborg(src)
modules += new /obj/item/device/healthanalyzer(src)
emag = new /obj/item/weapon/melee/energy/sword/cyborg(src)
@@ -193,11 +192,11 @@
modules += new /obj/item/weapon/rcd/borg(src)
modules += new /obj/item/weapon/extinguisher(src)
modules += new /obj/item/weapon/weldingtool/largetank/cyborg(src)
- modules += new /obj/item/weapon/screwdriver(src)
- modules += new /obj/item/weapon/wrench(src)
- modules += new /obj/item/weapon/crowbar(src)
- modules += new /obj/item/weapon/wirecutters(src)
- modules += new /obj/item/device/multitool(src)
+ modules += new /obj/item/weapon/screwdriver/cyborg(src)
+ modules += new /obj/item/weapon/wrench/cyborg(src)
+ modules += new /obj/item/weapon/crowbar/cyborg(src)
+ modules += new /obj/item/weapon/wirecutters/cyborg(src)
+ modules += new /obj/item/device/multitool/cyborg(src)
modules += new /obj/item/device/t_scanner(src)
modules += new /obj/item/device/analyzer(src)
modules += new /obj/item/taperoll/engineering(src)
@@ -222,7 +221,7 @@
/obj/item/weapon/robot_module/security/New()
..()
modules += new /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg(src)
- modules += new /obj/item/weapon/melee/baton/loaded/robot(src)
+ modules += new /obj/item/weapon/melee/baton/loaded(src)
modules += new /obj/item/weapon/gun/energy/disabler/cyborg(src)
modules += new /obj/item/taperoll/police(src)
modules += new /obj/item/clothing/mask/gas/sechailer/cyborg(src)
@@ -353,7 +352,7 @@
modules += new /obj/item/weapon/gun/energy/printer(src)
modules += new /obj/item/weapon/gun/projectile/revolver/grenadelauncher/multi/cyborg(src)
modules += new /obj/item/weapon/card/emag(src)
- modules += new /obj/item/weapon/crowbar(src)
+ modules += new /obj/item/weapon/crowbar/cyborg(src)
modules += new /obj/item/weapon/pinpointer/operative(src)
emag = null
@@ -391,7 +390,7 @@
modules += new /obj/item/weapon/surgicaldrill(src)
modules += new /obj/item/weapon/melee/energy/sword/cyborg/saw(src) //Energy saw -- primary weapon
modules += new /obj/item/weapon/card/emag(src)
- modules += new /obj/item/weapon/crowbar(src)
+ modules += new /obj/item/weapon/crowbar/cyborg(src)
modules += new /obj/item/weapon/pinpointer/operative(src)
emag = null
@@ -411,7 +410,7 @@
modules += new /obj/item/weapon/pickaxe/drill/jackhammer(src)
modules += new /obj/item/borg/combat/shield(src)
modules += new /obj/item/borg/combat/mobility(src)
- modules += new /obj/item/weapon/wrench(src)
+ modules += new /obj/item/weapon/wrench/cyborg(src)
emag = new /obj/item/weapon/gun/energy/lasercannon/cyborg(src)
fix_modules()
@@ -427,7 +426,7 @@
modules += new /obj/item/weapon/pickaxe/drill/jackhammer(src)
modules += new /obj/item/borg/combat/shield(src)
modules += new /obj/item/borg/combat/mobility(src)
- modules += new /obj/item/weapon/wrench(src)
+ modules += new /obj/item/weapon/wrench/cyborg(src)
emag = new /obj/item/weapon/gun/energy/lasercannon/cyborg(src)
fix_modules()
@@ -474,11 +473,11 @@
/obj/item/weapon/robot_module/drone/New()
modules += new /obj/item/weapon/weldingtool/largetank/cyborg(src)
- modules += new /obj/item/weapon/screwdriver(src)
- modules += new /obj/item/weapon/wrench(src)
- modules += new /obj/item/weapon/crowbar(src)
- modules += new /obj/item/weapon/wirecutters(src)
- modules += new /obj/item/device/multitool(src)
+ modules += new /obj/item/weapon/screwdriver/cyborg(src)
+ modules += new /obj/item/weapon/wrench/cyborg(src)
+ modules += new /obj/item/weapon/crowbar/cyborg(src)
+ modules += new /obj/item/weapon/wirecutters/cyborg(src)
+ modules += new /obj/item/device/multitool/cyborg(src)
modules += new /obj/item/device/lightreplacer(src)
modules += new /obj/item/weapon/gripper(src)
modules += new /obj/item/weapon/matter_decompiler(src)
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 469b6e86574..f9849e9b6cc 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -75,7 +75,7 @@
Stun(3)
flash_eyes(affect_silicon = 1)
to_chat(src, "*BZZZT*")
- to_chat(src, "\red Warning: Electromagnetic pulse detected.")
+ to_chat(src, "Warning: Electromagnetic pulse detected.")
..()
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index 50a7afc64b5..063fc07badf 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -169,14 +169,11 @@
/mob/living/simple_animal/bot/Destroy()
if(paicard)
ejectpai()
- qdel(Radio)
- Radio = null
- qdel(access_card)
- access_card = null
+ QDEL_NULL(Radio)
+ QDEL_NULL(access_card)
if(radio_controller && bot_filter)
radio_controller.remove_object(bot_core, control_freq)
- qdel(bot_core)
- bot_core = null
+ QDEL_NULL(bot_core)
return ..()
/mob/living/simple_animal/bot/death(gibbed)
@@ -263,7 +260,7 @@
interact(H)
else
return ..()
-
+
/mob/living/simple_animal/bot/attack_ghost(mob/M)
interact(M)
@@ -326,7 +323,7 @@
to_chat(user, "Close the access panel before manipulating the personality slot!")
else
to_chat(user, "You attempt to pull [paicard] free...")
- if(do_after(user, 30, target = src))
+ if(do_after(user, 30 * W.toolspeed, target = src))
if(paicard)
user.visible_message("[user] uses [W] to pull [paicard] out of [bot_name]!","You pull [paicard] out of [bot_name] with [W].")
ejectpai(user)
diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
index 2aebeb5d04a..f9f1bbf1c08 100644
--- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
@@ -98,7 +98,7 @@
if(prob(5)) //Spawns foam!
visible_message("[src] whirs and bubbles violently, before releasing a plume of froth!")
- new /obj/effect/effect/foam(loc)
+ new /obj/structure/foam(loc)
else if(prob(5))
audible_message("[src] makes an excited beeping booping sound!")
diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm
index 27bfe821502..d524ffd8e06 100644
--- a/code/modules/mob/living/simple_animal/bot/construction.dm
+++ b/code/modules/mob/living/simple_animal/bot/construction.dm
@@ -139,10 +139,11 @@
to_chat(user, "You need one length of cable to wire the ED-209!")
return
to_chat(user, "You start to wire [src]...")
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * W.toolspeed, target = src))
if(coil.get_amount() >= 1 && build_step == 6)
coil.use(1)
build_step = 7
+ playsound(loc, W.usesound, 50, 1)
to_chat(user, "You wire the ED-209 assembly.")
name = "wired ED-209 assembly"
@@ -174,9 +175,9 @@
if(8)
if(istype(W, /obj/item/weapon/screwdriver))
- playsound(loc, 'sound/items/Screwdriver.ogg', 100, 1)
+ playsound(loc, W.usesound, 100, 1)
to_chat(user, "You start attaching the gun to the frame...")
- if(do_after(user, 40, target = src))
+ if(do_after(user, 40 * W.toolspeed, target = src))
build_step++
name = "armed [name]"
to_chat(user, "Taser gun attached.")
diff --git a/code/modules/mob/living/simple_animal/bot/emote.dm b/code/modules/mob/living/simple_animal/bot/emote.dm
index 1bf29d14178..70e27937745 100644
--- a/code/modules/mob/living/simple_animal/bot/emote.dm
+++ b/code/modules/mob/living/simple_animal/bot/emote.dm
@@ -28,92 +28,44 @@
switch(act)
if("ping")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] pings at [param]."
- else
- message = "[src] pings."
+ message = "[src] pings[M ? " at [M]" : ""]."
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
m_type = 2
if("buzz")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] buzzes at [param]."
- else
- message = "[src] buzzes."
+ message = "[src] buzzes[M ? " at [M]" : ""]."
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
m_type = 2
if("beep")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] beeps at [param]."
- else
- message = "[src] beeps."
+ message = "[src] beeps[M ? " at [M]" : ""]."
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
m_type = 2
if("yes")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] emits an affirmative blip at [param]."
- else
- message = "[src] emits an affirmative blip."
+ message = "[src] emits an affirmative blip[M ? " at [M]" : ""]."
playsound(src.loc, 'sound/machines/synth_yes.ogg', 50, 0)
m_type = 2
if("no")
- var/M = null
- if(param)
- for(var/mob/A in view(null, null))
- if(param == A.name)
- M = A
- break
- if(!M)
- param = null
+ var/M = handle_emote_param(param)
- if(param)
- message = "[src] emits a negative blip at [param]."
- else
- message = "[src] emits a negative blip."
+ message = "[src] emits an negative blip[M ? " at [M]" : ""]."
playsound(src.loc, 'sound/machines/synth_no.ogg', 50, 0)
m_type = 2
if("scream", "screams")
- message = "[src] screams!"
+ var/M = handle_emote_param(param)
+
+ message = "[src] screams[M ? " at [M]" : ""]!"
playsound(src.loc, 'sound/goonstation/voice/robot_scream.ogg', 80, 0)
m_type = 2
diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm
index 14f7030243e..e95d2409921 100644
--- a/code/modules/mob/living/simple_animal/bot/mulebot.dm
+++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm
@@ -65,12 +65,8 @@
/mob/living/simple_animal/bot/mulebot/Destroy()
unload(0)
- if(wires)
- qdel(wires)
- wires = null
- if(cell)
- qdel(cell)
- cell = null
+ QDEL_NULL(wires)
+ QDEL_NULL(cell)
return ..()
/mob/living/simple_animal/bot/mulebot/proc/set_suffix(suffix)
@@ -311,7 +307,7 @@
else
dat += "Removed "
- dat += wires.GetInteractWindow()
+ wires.Interact(user)
else
dat += "
The bot is in maintenance mode and cannot be controlled.
"
diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm
index a439d793eb3..de09cc11084 100644
--- a/code/modules/mob/living/simple_animal/bot/secbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/secbot.dm
@@ -72,6 +72,13 @@
harmbaton = 1
emagged = 2
+/mob/living/simple_animal/bot/secbot/armsky
+ name = "Sergeant-at-Armsky"
+ health = 45
+ idcheck = 1
+ arrest_type = 1
+ weaponscheck = 1
+
/mob/living/simple_animal/bot/secbot/New()
..()
icon_state = "[base_icon][on]"
diff --git a/code/modules/mob/living/simple_animal/corpse.dm b/code/modules/mob/living/simple_animal/corpse.dm
index ef5a8ec3719..e8196b4d3ac 100644
--- a/code/modules/mob/living/simple_animal/corpse.dm
+++ b/code/modules/mob/living/simple_animal/corpse.dm
@@ -103,12 +103,12 @@
/obj/effect/landmark/mobcorpse/syndicatecommando
name = "Syndicate Commando"
corpseuniform = /obj/item/clothing/under/syndicate
- corpsesuit = /obj/item/clothing/suit/space/rig/syndi
+ corpsesuit = /obj/item/clothing/suit/space/hardsuit/syndi
corpseshoes = /obj/item/clothing/shoes/combat
corpsegloves = /obj/item/clothing/gloves/combat
corpseradio = /obj/item/device/radio/headset
corpsemask = /obj/item/clothing/mask/gas/syndicate
- corpsehelmet = /obj/item/clothing/head/helmet/space/rig/syndi
+ corpsehelmet = /obj/item/clothing/head/helmet/space/hardsuit/syndi
corpseback = /obj/item/weapon/tank/jetpack/oxygen
corpsepocket1 = /obj/item/weapon/tank/emergency_oxygen
corpseid = 1
diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm
index dfc0bce32a3..86beb8f6bda 100644
--- a/code/modules/mob/living/simple_animal/friendly/corgi.dm
+++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm
@@ -87,9 +87,9 @@
to_chat(user, "You can't shave this corgi, it's already been shaved!")
return
user.visible_message("[user] starts to shave [src] using \the [O].", "You start to shave [src] using \the [O]...")
- if(do_after(user, 50, target = src))
+ if(do_after(user, 50 * O.toolspeed, target = src))
user.visible_message("[user] shaves [src]'s hair using \the [O].")
- playsound(loc, 'sound/items/Welder2.ogg', 20, 1)
+ playsound(loc, O.usesound, 20, 1)
shaved = 1
icon_living = "[initial(icon_living)]_shaved"
icon_dead = "[initial(icon_living)]_shaved_dead"
@@ -174,7 +174,7 @@
var/list/allowed_types = list(
/obj/item/clothing/suit/armor/vest,
/obj/item/clothing/suit/space/deathsquad,
- /obj/item/clothing/suit/space/rig/engineering,
+ /obj/item/clothing/suit/space/hardsuit/engineering,
/obj/item/device/radio,
/obj/item/device/radio/off,
/obj/item/clothing/suit/cardborg,
@@ -356,7 +356,7 @@
desc = "That's not red paint. That's real corgi blood."
valid = 1
- if(/obj/item/clothing/head/helmet/space/rig/engineering)
+ if(/obj/item/clothing/head/helmet/space/hardsuit/engineering)
name = "Space Explorer [real_name]"
desc = "That's one small step for a corgi. One giant yap for corgikind."
valid = 1
@@ -572,7 +572,7 @@
//Lisa already has a cute bow!
/mob/living/simple_animal/pet/corgi/Lisa/Topic(href, href_list)
if(href_list["remove_inv"] || href_list["add_inv"])
- to_chat(usr, "\red [src] already has a cute bow!")
+ to_chat(usr, "[src] already has a cute bow!")
return
..()
@@ -628,7 +628,7 @@
/mob/living/simple_animal/pet/corgi/Ian/borgi/proc/explode()
for(var/mob/M in viewers(src, null))
if(M.client)
- M.show_message("\red [src] makes an odd whining noise.")
+ M.show_message("[src] makes an odd whining noise.")
sleep(10)
explosion(get_turf(src), 0, 1, 4, 7)
death()
diff --git a/code/modules/mob/living/simple_animal/friendly/crab.dm b/code/modules/mob/living/simple_animal/friendly/crab.dm
index 7a81f52e2b7..02c1445ad27 100644
--- a/code/modules/mob/living/simple_animal/friendly/crab.dm
+++ b/code/modules/mob/living/simple_animal/friendly/crab.dm
@@ -52,7 +52,7 @@
/*/mob/living/simple_animal/crab/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
if(istype(O, /obj/item/weapon/wirecutters))
if(prob(50))
- to_chat(user, "\red \b This kills the crab.")
+ to_chat(user, "This kills the crab.")
health -= 20
death()
else
@@ -69,20 +69,20 @@
qdel(MED)
for(var/mob/M in viewers(src, null))
if((M.client && !( M.blinded )))
- M.show_message("\blue [user] applies the [MED] on [src]")
+ M.show_message("[user] applies the [MED] on [src]")
else
- to_chat(user, "\blue this [src] is dead, medical items won't bring it back to life.")
+ to_chat(user, "this [src] is dead, medical items won't bring it back to life.")
else
if(O.force)
health -= O.force
for(var/mob/M in viewers(src, null))
if((M.client && !( M.blinded )))
- M.show_message("\red \b [src] has been attacked with the [O] by [user]. ")
+ M.show_message("[src] has been attacked with the [O] by [user]. ")
else
- to_chat(usr, "\red This weapon is ineffective, it does no damage.")
+ to_chat(usr, "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 the [O]. ")
+ M.show_message("[user] gently taps [src] with the [O]. ")
/mob/living/simple_animal/crab/Topic(href, href_list)
if(usr.stat) return
@@ -105,14 +105,14 @@
inventory_head.loc = src.loc
inventory_head = null
else
- to_chat(usr, "\red There is nothing to remove from its [remove_from].")
+ to_chat(usr, "There is nothing to remove from its [remove_from].")
return
if("mask")
if(inventory_mask)
inventory_mask.loc = src.loc
inventory_mask = null
else
- to_chat(usr, "\red There is nothing to remove from its [remove_from].")
+ to_chat(usr, "There is nothing to remove from its [remove_from].")
return
//show_inv(usr) //Commented out because changing Ian's name and then calling up his inventory opens a new inventory...which is annoying.
@@ -123,12 +123,12 @@
return
var/add_to = href_list["add_inv"]
if(!usr.get_active_hand())
- to_chat(usr, "\red You have nothing in your hand to put on its [add_to].")
+ to_chat(usr, "You have nothing in your hand to put on its [add_to].")
return
switch(add_to)
if("head")
if(inventory_head)
- to_chat(usr, "\red It's is already wearing something.")
+ to_chat(usr, "It's is already wearing something.")
return
else
var/obj/item/item_to_add = usr.get_active_hand()
@@ -170,7 +170,7 @@
)
if( ! ( item_to_add.type in allowed_types ) )
- to_chat(usr, "\red It doesn't seem too keen on wearing that item.")
+ to_chat(usr, "It doesn't seem too keen on wearing that item.")
return
usr.drop_item()
@@ -233,7 +233,7 @@
if("mask")
if(inventory_mask)
- to_chat(usr, "\red It's already wearing something.")
+ to_chat(usr, "It's already wearing something.")
return
else
var/obj/item/item_to_add = usr.get_active_hand()
@@ -249,7 +249,7 @@
)
if( ! ( item_to_add.type in allowed_types ) )
- to_chat(usr, "\red This object won't fit.")
+ to_chat(usr, "This object won't fit.")
return
usr.drop_item()
diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
index b1b31461b77..840c988dc98 100644
--- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
+++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
@@ -34,7 +34,7 @@
for(var/direction in shuffle(list(1,2,4,8,5,6,9,10)))
var/step = get_step(src, direction)
if(step)
- if(locate(/obj/effect/spacevine) in step)
+ if(locate(/obj/structure/spacevine) in step)
Move(step, get_dir(src, step))
/mob/living/simple_animal/hostile/retaliate/goat/handle_automated_action()
@@ -45,9 +45,9 @@
if(enemies.len && prob(10))
enemies = list()
LoseTarget()
- src.visible_message("\blue [src] calms down.")
+ src.visible_message("[src] calms down.")
- var/obj/effect/spacevine/SV = locate(/obj/effect/spacevine) in loc
+ var/obj/structure/spacevine/SV = locate(/obj/structure/spacevine) in loc
if(SV)
SV.eat(src)
@@ -59,12 +59,12 @@
/mob/living/simple_animal/hostile/retaliate/goat/Retaliate()
..()
- src.visible_message("\red [src] gets an evil-looking gleam in their eye.")
+ src.visible_message("[src] gets an evil-looking gleam in their eye.")
/mob/living/simple_animal/hostile/retaliate/goat/Move()
..()
if(!stat)
- var/obj/effect/spacevine/SV = locate(/obj/effect/spacevine) in loc
+ var/obj/structure/spacevine/SV = locate(/obj/structure/spacevine) in loc
if(SV)
SV.eat(src)
@@ -78,9 +78,9 @@
G.reagents.add_reagent("milk", transfered)
milk_content -= transfered
else if(G.reagents.total_volume >= G.volume)
- to_chat(user, "\red \The [O] is full.")
+ to_chat(user, "\The [O] is full.")
else
- to_chat(user, "\red The udder is dry. Wait a bit longer...")
+ to_chat(user, "The udder is dry. Wait a bit longer...")
else
..()
@@ -124,9 +124,9 @@
G.reagents.add_reagent("milk", transfered)
milk_content -= transfered
else if(G.reagents.total_volume >= G.volume)
- to_chat(user, "\red \The [O] is full.")
+ to_chat(user, "\The [O] is full.")
else
- to_chat(user, "\red The udder is dry. Wait a bit longer...")
+ to_chat(user, "The udder is dry. Wait a bit longer...")
else
..()
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index 0b0a182ed44..fdcf39dd51b 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -112,7 +112,7 @@
if( ishuman(AM) )
if(!stat)
var/mob/M = AM
- to_chat(M, "\blue [bicon(src)] Squeek!")
+ to_chat(M, "[bicon(src)] Squeek!")
M << 'sound/effects/mousesqueek.ogg'
..()
diff --git a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
index 38eea833e04..5b2419bf7e8 100644
--- a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
+++ b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
@@ -48,10 +48,10 @@
if(istype(O, /obj/item/device/mmi) || istype(O, /obj/item/device/mmi/posibrain))
var/obj/item/device/mmi/B = O
if(src.mmi) //There's already a brain in it.
- to_chat(user, "\red There's already a brain in [src]!")
+ to_chat(user, "There's already a brain in [src]!")
return
if(!B.brainmob)
- to_chat(user, "\red Sticking an empty MMI into the frame would sort of defeat the purpose.")
+ to_chat(user, "Sticking an empty MMI into the frame would sort of defeat the purpose.")
return
if(!B.brainmob.key)
var/ghost_can_reenter = 0
@@ -69,14 +69,14 @@
return
if(B.brainmob.stat == DEAD)
- to_chat(user, "\red [O] is dead. Sticking it into the frame would sort of defeat the purpose.")
+ to_chat(user, "[O] is dead. Sticking it into the frame would sort of defeat the purpose.")
return
if(jobban_isbanned(B.brainmob, "Cyborg") || jobban_isbanned(B.brainmob,"nonhumandept"))
- to_chat(user, "\red [O] does not seem to fit.")
+ to_chat(user, "[O] does not seem to fit.")
return
- to_chat(user, "\blue You install [O] in [src]!")
+ to_chat(user, "You install [O] in [src]!")
user.drop_item()
src.mmi = O
@@ -95,15 +95,15 @@
health = maxHealth
add_fingerprint(user)
for(var/mob/W in viewers(user, null))
- W.show_message(text("\red [user] has spot-welded some of the damage to [src]!"), 1)
+ W.show_message(text("[user] has spot-welded some of the damage to [src]!"), 1)
else
- to_chat(user, "\blue [src] is undamaged!")
+ to_chat(user, "[src] is undamaged!")
else
to_chat(user, "Need more welding fuel!")
return
else if(istype(O, /obj/item/weapon/card/id)||istype(O, /obj/item/device/pda))
if(!mmi)
- to_chat(user, "\red There's no reason to swipe your ID - the spiderbot has no brain to remove.")
+ to_chat(user, "There's no reason to swipe your ID - the spiderbot has no brain to remove.")
return 0
var/obj/item/weapon/card/id/id_card
@@ -115,7 +115,7 @@
id_card = pda.id
if(access_robotics in id_card.access)
- to_chat(user, "\blue You swipe your access card and pop the brain out of [src].")
+ to_chat(user, "You swipe your access card and pop the brain out of [src].")
eject_brain()
if(held_item)
@@ -124,7 +124,7 @@
return 1
else
- to_chat(user, "\red You swipe your card, with no effect.")
+ to_chat(user, "You swipe your card, with no effect.")
return 0
else
@@ -135,24 +135,24 @@
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 the [O] by [user]. ")
+ M.show_message("[src] has been attacked with the [O] by [user]. ")
else
- to_chat(usr, "\red This weapon is ineffective, it does no damage.")
+ to_chat(usr, "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 the [O]. ")
+ M.show_message("[user] gently taps [src] with the [O]. ")
/mob/living/simple_animal/spiderbot/emag_act(user as mob)
if(emagged)
- to_chat(user, "\red [src] is already overloaded - better run.")
+ to_chat(user, "[src] is already overloaded - better run.")
return 0
else
emagged = 1
- to_chat(user, "\blue You short out the security protocols and overload [src]'s cell, priming it to explode in a short time.")
+ to_chat(user, "You short out the security protocols and overload [src]'s cell, priming it to explode in a short time.")
spawn(100)
- to_chat(src, "\red Your cell seems to be outputting a lot of power...")
+ to_chat(src, "Your cell seems to be outputting a lot of power...")
spawn(200)
- to_chat(src, "\red Internal heat sensors are spiking! Something is badly wrong with your cell!")
+ to_chat(src, "Internal heat sensors are spiking! Something is badly wrong with your cell!")
spawn(300)
src.explode()
@@ -166,7 +166,7 @@
/mob/living/simple_animal/spiderbot/proc/explode() //When emagged.
for(var/mob/M in viewers(src, null))
if((M.client && !( M.blinded )))
- M.show_message("\red [src] makes an odd warbling noise, fizzles, and explodes.")
+ M.show_message("[src] makes an odd warbling noise, fizzles, and explodes.")
explosion(get_turf(loc), -1, -1, 3, 5)
eject_brain()
death()
@@ -227,18 +227,18 @@
return
if(!held_item)
- to_chat(usr, "\red You have nothing to drop!")
+ to_chat(usr, "You have nothing to drop!")
return 0
if(istype(held_item, /obj/item/weapon/grenade))
- visible_message("\red [src] launches \the [held_item]!", "\red You launch \the [held_item]!", "You hear a skittering noise and a thump!")
+ visible_message("[src] launches \the [held_item]!", "You launch \the [held_item]!", "You hear a skittering noise and a thump!")
var/obj/item/weapon/grenade/G = held_item
G.loc = src.loc
G.prime()
held_item = null
return 1
- visible_message("\blue [src] drops \the [held_item]!", "\blue You drop \the [held_item]!", "You hear a skittering noise and a soft thump.")
+ visible_message("[src] drops \the [held_item]!", "You drop \the [held_item]!", "You hear a skittering noise and a soft thump.")
held_item.loc = src.loc
held_item = null
@@ -255,7 +255,7 @@
return -1
if(held_item)
- to_chat(src, "\red You are already holding \the [held_item]")
+ to_chat(src, "You are already holding \the [held_item]")
return 1
var/list/items = list()
@@ -270,12 +270,12 @@
if(selection == I)
held_item = selection
selection.loc = src
- visible_message("\blue [src] scoops up \the [held_item]!", "\blue You grab \the [held_item]!", "You hear a skittering noise and a clink.")
+ visible_message("[src] scoops up \the [held_item]!", "You grab \the [held_item]!", "You hear a skittering noise and a clink.")
return held_item
- to_chat(src, "\red \The [selection] is too far away.")
+ to_chat(src, "\The [selection] is too far away.")
return 0
- to_chat(src, "\red There is nothing of interest to take.")
+ to_chat(src, "There is nothing of interest to take.")
return 0
/mob/living/simple_animal/spiderbot/examine(mob/user)
diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm
index 538ce8450c7..904762d6c27 100644
--- a/code/modules/mob/living/simple_animal/hostile/bees.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bees.dm
@@ -161,8 +161,8 @@
/mob/living/simple_animal/hostile/poison/bees/worker/Found(atom/A)
if(istype(A, /obj/machinery/hydroponics))
var/obj/machinery/hydroponics/Hydro = A
- if(Hydro.myseed && !Hydro.dead && !Hydro.recent_bee_visit)
- wanted_objects |= /obj/machinery/hydroponics //so we only hunt them while they're alive/seeded/not visisted
+ if(Hydro.myseed && !Hydro.dead && !Hydro.recent_bee_visit && !Hydro.lid_state)
+ wanted_objects |= /obj/machinery/hydroponics //so we only hunt them while they're alive/seeded/not visisted and uncovered
return 1
..()
@@ -188,12 +188,12 @@
..()
/mob/living/simple_animal/hostile/poison/bees/worker/proc/pollinate(obj/machinery/hydroponics/Hydro)
- if(!istype(Hydro) || !Hydro.myseed || Hydro.dead || Hydro.recent_bee_visit)
+ if(!istype(Hydro) || !Hydro.myseed || Hydro.dead || Hydro.recent_bee_visit || Hydro.lid_state)
target = null
return
target = null //so we pick a new hydro tray next FindTarget(), instead of loving the same plant for eternity
- wanted_objects -= /obj/machinery/hydroponics //so we only hunt them while they're alive/seeded/not visisted
+ wanted_objects -= /obj/machinery/hydroponics //so we only hunt them while they're alive/seeded/not visisted and uncovered
Hydro.recent_bee_visit = TRUE
spawn(BEE_TRAY_RECENT_VISIT)
if(Hydro)
@@ -295,8 +295,7 @@
queen = new(src)
/obj/item/queen_bee/Destroy()
- qdel(queen)
- queen = null
+ QDEL_NULL(queen)
return ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
index 368626f49fe..e45d5a1a391 100644
--- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
+++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
@@ -116,7 +116,7 @@
GiveUp(C)
return
//second, spin a sticky spiderweb on this tile
- var/obj/effect/spider/stickyweb/W = locate() in get_turf(src)
+ var/obj/structure/spider/stickyweb/W = locate() in get_turf(src)
if(!W)
Web()
else
@@ -157,7 +157,7 @@
stop_automated_movement = 1
spawn(40)
if(busy == SPINNING_WEB && src.loc == T)
- new /obj/effect/spider/stickyweb(T)
+ new /obj/structure/spider/stickyweb(T)
busy = 0
stop_automated_movement = 0
@@ -187,7 +187,7 @@
spawn(50)
if(busy == SPINNING_COCOON)
if(cocoon_target && istype(cocoon_target.loc, /turf) && get_dist(src,cocoon_target) <= 1)
- var/obj/effect/spider/cocoon/C = new(cocoon_target.loc)
+ var/obj/structure/spider/cocoon/C = new(cocoon_target.loc)
var/large_cocoon = 0
C.pixel_x = cocoon_target.pixel_x
C.pixel_y = cocoon_target.pixel_y
@@ -223,7 +223,7 @@
set category = "Spider"
set desc = "Lay a clutch of eggs, but you must wrap a creature for feeding first."
- var/obj/effect/spider/eggcluster/E = locate() in get_turf(src)
+ var/obj/structure/spider/eggcluster/E = locate() in get_turf(src)
if(E)
to_chat(src, "There is already a cluster of eggs here!")
else if(!fed)
@@ -236,7 +236,7 @@
if(busy == LAYING_EGGS)
E = locate() in get_turf(src)
if(!E)
- var/obj/effect/spider/eggcluster/C = new /obj/effect/spider/eggcluster(src.loc)
+ var/obj/structure/spider/eggcluster/C = new /obj/structure/spider/eggcluster(src.loc)
C.faction = faction
C.master_commander = master_commander
if(ckey)
diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
index 5b76f3a633c..3c521d56d04 100644
--- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
@@ -83,7 +83,7 @@
/mob/living/simple_animal/hostile/hivebot/tele/warpbots()
icon_state = "def_radar"
- visible_message("\red The [src] turns on!")
+ visible_message("The [src] turns on!")
while(bot_amt > 0)
bot_amt--
switch(bot_type)
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
index dfb9948a1e3..228f4df9ad6 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
@@ -108,7 +108,7 @@ Difficulty: Hard
..()
/mob/living/simple_animal/hostile/megafauna/hierophant/Destroy()
- qdel(spawned_rune)
+ QDEL_NULL(spawned_rune)
. = ..()
/mob/living/simple_animal/hostile/megafauna/hierophant/devour(mob/living/L)
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
index bd916532519..a8102b94b94 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
@@ -43,7 +43,7 @@
mouse_opacity = 2 // Easier to click on in melee, they're giant targets anyway
/mob/living/simple_animal/hostile/megafauna/Destroy()
- qdel(internal_gps)
+ QDEL_NULL(internal_gps)
. = ..()
/mob/living/simple_animal/hostile/megafauna/death(gibbed)
@@ -77,7 +77,7 @@
OpenFire()
else
devour(L)
-
+
/mob/living/simple_animal/hostile/megafauna/onShuttleMove()
var/turf/oldloc = loc
. = ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm
index f3ed8a34f51..80227526cbc 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm
@@ -227,7 +227,7 @@
/obj/item/asteroid/goliath_hide/afterattack(atom/target, mob/user, proximity_flag)
if(proximity_flag)
- if(istype(target, /obj/item/clothing/suit/space/rig/mining) || istype(target, /obj/item/clothing/head/helmet/space/rig/mining) || istype(target, /obj/item/clothing/suit/space/eva/plasmaman/miner) || istype(target, /obj/item/clothing/head/helmet/space/eva/plasmaman/miner))
+ if(istype(target, /obj/item/clothing/suit/space/hardsuit/mining) || istype(target, /obj/item/clothing/head/helmet/space/hardsuit/mining) || istype(target, /obj/item/clothing/suit/space/eva/plasmaman/miner) || istype(target, /obj/item/clothing/head/helmet/space/eva/plasmaman/miner))
var/obj/item/clothing/C = target
var/current_armor = C.armor
if(current_armor.["melee"] < 60)
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm
index 9f98b205fc9..3cfc1b2c291 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm
@@ -79,7 +79,7 @@
//repair a bit of damage
if(prob(1))
- src.visible_message("\red [bicon(src)] [src] shudders and shakes as some of it's damaged systems come back online.")
+ src.visible_message("[bicon(src)] [src] shudders and shakes as some of it's damaged systems come back online.")
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
@@ -94,10 +94,10 @@
//sometimes our targetting sensors malfunction, and we attack anyone nearby
if(prob(disabled ? 0 : 1))
if(hostile_drone)
- src.visible_message("\blue [bicon(src)] [src] retracts several targetting vanes, and dulls it's running lights.")
+ src.visible_message("[bicon(src)] [src] retracts several targetting vanes, and dulls it's running lights.")
hostile_drone = 0
else
- src.visible_message("\red [bicon(src)] [src] suddenly lights up, and additional targetting vanes slide into place.")
+ src.visible_message("[bicon(src)] [src] suddenly lights up, and additional targetting vanes slide into place.")
hostile_drone = 1
if(health / maxHealth > 0.9)
@@ -118,17 +118,17 @@
exploding = 0
if(!disabled)
if(prob(50))
- src.visible_message("\blue [bicon(src)] [src] suddenly shuts down!")
+ src.visible_message("[bicon(src)] [src] suddenly shuts down!")
else
- src.visible_message("\blue [bicon(src)] [src] suddenly lies still and quiet.")
+ src.visible_message("[bicon(src)] [src] suddenly lies still and quiet.")
disabled = rand(150, 600)
walk(src,0)
if(exploding && prob(20))
if(prob(50))
- src.visible_message("\red [bicon(src)] [src] begins to spark and shake violenty!")
+ src.visible_message("[bicon(src)] [src] begins to spark and shake violenty!")
else
- src.visible_message("\red [bicon(src)] [src] sparks and shakes like it's about to explode!")
+ src.visible_message("[bicon(src)] [src] sparks and shakes like it's about to explode!")
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm
index 41ca671bc56..168ed2d441c 100644
--- a/code/modules/mob/living/simple_animal/hostile/statue.dm
+++ b/code/modules/mob/living/simple_animal/hostile/statue.dm
@@ -39,6 +39,7 @@
search_objects = 1 // So that it can see through walls
+ see_invisible = SEE_INVISIBLE_OBSERVER_NOLIGHTING
sight = SEE_SELF|SEE_MOBS|SEE_OBJS|SEE_TURFS
anchored = 1
status_flags = GODMODE // Cannot push also
@@ -56,9 +57,6 @@
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/blindness(null))
AddSpell(new /obj/effect/proc_holder/spell/targeted/night_vision(null))
- // Give nightvision
- see_invisible = SEE_INVISIBLE_OBSERVER_NOLIGHTING
-
// Set creator
if(creator)
src.creator = creator
@@ -190,7 +188,7 @@
//Toggle Night Vision
/obj/effect/proc_holder/spell/targeted/night_vision
- name = "Toggle Nightvision \[ON\]"
+ name = "Toggle Nightvision"
desc = "Toggle your nightvision mode."
charge_max = 10
@@ -199,17 +197,15 @@
message = "You toggle your night vision!"
range = -1
include_user = 1
+ var/non_night_vision = SEE_INVISIBLE_LIVING
+ var/night_vision = SEE_INVISIBLE_OBSERVER_NOLIGHTING
/obj/effect/proc_holder/spell/targeted/night_vision/cast(list/targets, mob/user = usr)
-
for(var/mob/living/target in targets)
- if(target.see_invisible == SEE_INVISIBLE_LIVING)
- target.see_invisible = SEE_INVISIBLE_OBSERVER_NOLIGHTING
- name = "Toggle Nightvision \[ON\]"
+ if(target.see_invisible == non_night_vision)
+ target.see_invisible = night_vision
else
- target.see_invisible = SEE_INVISIBLE_LIVING
- name = "Toggle Nightvision \[OFF\]"
- return
+ target.see_invisible = non_night_vision
/mob/living/simple_animal/hostile/statue/sentience_act()
faction -= "neutral"
diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
index be2cfff6f0c..805059f25f7 100644
--- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm
+++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
@@ -46,13 +46,13 @@
if(O.damtype == STAMINA)
damage = 0
health -= damage
- visible_message("\red \b [src] has been attacked with the [O] by [user]. ")
+ visible_message("[src] has been attacked with the [O] by [user]. ")
else
- visible_message("\red \b [src] blocks the [O] with its shield! ")
+ visible_message("[src] blocks the [O] with its shield! ")
playsound(loc, O.hitsound, 25, 1, -1)
else
- to_chat(usr, "\red This weapon is ineffective, it does no damage.")
- visible_message("\red [user] gently taps [src] with the [O]. ")
+ to_chat(usr, "This weapon is ineffective, it does no damage.")
+ visible_message("[user] gently taps [src] with the [O]. ")
/mob/living/simple_animal/hostile/syndicate/melee/bullet_act(var/obj/item/projectile/Proj)
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/__defines.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/__defines.dm
index 8453a71cff4..eefc506ff99 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/__defines.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/__defines.dm
@@ -4,6 +4,13 @@
#define MOVING_TO_TARGET 3
#define SPINNING_COCOON 4
+#define TS_AI_AGGRESSIVE 0
+#define TS_AI_DEFENSIVE 1
+
+#define TS_DAMAGE_SIMPLE 0
+#define TS_DAMAGE_POISON 1
+#define TS_DAMAGE_BRUTE 2
+
#define TS_DESC_RED "Red - Assault"
#define TS_DESC_GRAY "Gray - Ambush"
#define TS_DESC_GREEN "Green - Nurse"
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm
index ca216da052d..90cef39a98f 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm
@@ -7,7 +7,7 @@
/datum/action/innate/terrorspider/web/Activate()
var/mob/living/simple_animal/hostile/poison/terror_spider/user = owner
- user.Web()
+ user.Web(0)
/datum/action/innate/terrorspider/wrap
name = "Wrap"
@@ -32,14 +32,25 @@
// ---------- PRINCE ACTIONS
-/datum/action/innate/terrorspider/princesmash
+/datum/action/innate/terrorspider/thickweb
+ name = "Thick Web"
+ icon_icon = 'icons/effects/effects.dmi'
+ button_icon_state = "stickyweb2"
+
+/datum/action/innate/terrorspider/thickweb/Activate()
+ var/mob/living/simple_animal/hostile/poison/terror_spider/user = owner
+ user.Web(1)
+
+// ---------- BOSS ACTIONS
+
+/datum/action/innate/terrorspider/ventsmash
name = "Smash Welded Vent"
icon_icon = 'icons/atmos/vent_pump.dmi'
button_icon_state = "map_vent"
-/datum/action/innate/terrorspider/princesmash/Activate()
- var/mob/living/simple_animal/hostile/poison/terror_spider/prince/user = owner
- user.DoPrinceSmash()
+/datum/action/innate/terrorspider/ventsmash/Activate()
+ var/mob/living/simple_animal/hostile/poison/terror_spider/user = owner
+ user.DoVentSmash()
// ---------- QUEEN ACTIONS
@@ -50,7 +61,7 @@
/datum/action/innate/terrorspider/queen/queennest/Activate()
var/mob/living/simple_animal/hostile/poison/terror_spider/queen/user = owner
- user.NestMode()
+ user.NestPrompt()
/datum/action/innate/terrorspider/queen/queensense
name = "Hive Sense"
@@ -79,25 +90,42 @@
var/mob/living/simple_animal/hostile/poison/terror_spider/queen/user = owner
user.QueenFakeLings()
+// ---------- EMPRESS
+
+/datum/action/innate/terrorspider/queen/empress/empresserase
+ name = "Erase Brood"
+ icon_icon = 'icons/effects/blood.dmi'
+ button_icon_state = "mgibbl1"
+
+/datum/action/innate/terrorspider/queen/empress/empresserase/Activate()
+ var/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/user = owner
+ user.EraseBrood()
+
// ---------- WEB
-/mob/living/simple_animal/hostile/poison/terror_spider/proc/Web()
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/Web(var/thick = 0)
var/turf/mylocation = loc
visible_message("[src] begins to secrete a sticky substance.")
- if(do_after(src, 40, target = loc))
+ if(do_after(src, delay_web, target = loc))
if(loc != mylocation)
return
else if(istype(loc, /turf/space))
to_chat(src, "Webs cannot be spun in space.")
else
- var/obj/effect/spider/terrorweb/T = locate() in get_turf(src)
+ var/obj/structure/spider/terrorweb/T = locate() in get_turf(src)
if(T)
to_chat(src, "There is already a web here.")
else
- var/obj/effect/spider/terrorweb/W = new /obj/effect/spider/terrorweb(loc)
+ var/obj/structure/spider/terrorweb/W = new /obj/structure/spider/terrorweb(loc)
W.creator_ckey = ckey
+ if(thick)
+ W.opacity = 1
+ W.name = "thick terror web"
+ if(web_infects)
+ W.infectious = 1
+ W.name = "sharp terror web"
-/obj/effect/spider/terrorweb
+/obj/structure/spider/terrorweb
name = "terror web"
desc = "it's stringy and sticky"
icon = 'icons/effects/effects.dmi'
@@ -106,26 +134,43 @@
health = 20 // two welders, or one laser shot (15 for the normal spider webs)
icon_state = "stickyweb1"
var/creator_ckey = null
+ var/infectious = 0
-/obj/effect/spider/terrorweb/New()
+/obj/structure/spider/terrorweb/New()
..()
if(prob(50))
icon_state = "stickyweb2"
-/obj/effect/spider/terrorweb/CanPass(atom/movable/mover, turf/target)
+/obj/structure/spider/terrorweb/proc/DeCloakNearby()
+ for(var/mob/living/simple_animal/hostile/poison/terror_spider/gray/G in view(6,src))
+ if(!G.ckey && G.stat != DEAD)
+ G.GrayDeCloak()
+ G.Aggro()
+
+/obj/structure/spider/terrorweb/CanPass(atom/movable/mover, turf/target)
if(istype(mover, /mob/living/simple_animal/hostile/poison/terror_spider))
return 1
if(istype(mover, /obj/item/projectile/terrorqueenspit))
return 1
if(isliving(mover))
+ var/mob/living/M = mover
+ if(M.lying)
+ return 1
if(prob(80))
to_chat(mover, "You get stuck in [src] for a moment.")
- var/mob/living/M = mover
M.Stun(4) // 8 seconds.
M.Weaken(4) // 8 seconds.
+ DeCloakNearby()
if(iscarbon(mover))
+ var/mob/living/carbon/C = mover
+ if(!IsTSInfected(C) && infectious)
+ var/inject_target = pick("chest","head")
+ if(C.can_inject(null, 0, inject_target, 0))
+ to_chat(C, "[src] slices into you!")
+ new /obj/item/organ/internal/body_egg/terror_eggs(C)
spawn(70)
- qdel(src)
+ if(C.loc == loc)
+ qdel(src)
return 1
else
return 0
@@ -133,7 +178,7 @@
return prob(20)
return ..()
-/obj/effect/spider/terrorweb/bullet_act(obj/item/projectile/Proj)
+/obj/structure/spider/terrorweb/bullet_act(obj/item/projectile/Proj)
if(Proj.damage_type != BRUTE && Proj.damage_type != BURN)
visible_message("[src] is undamaged by [Proj]!")
// Webs don't care about disablers, tasers, etc. Or toxin damage. They're organic, but not alive.
@@ -151,7 +196,7 @@
choices += L
for(var/obj/O in oview(1,src))
if(Adjacent(O) && !O.anchored)
- if(!istype(O, /obj/effect/spider/terrorweb) && !istype(O, /obj/effect/spider/cocoon) && !istype(O, /obj/effect/spider/spiderling/terror_spiderling))
+ if(!istype(O, /obj/structure/spider/terrorweb) && !istype(O, /obj/structure/spider/cocoon) && !istype(O, /obj/structure/spider/spiderling/terror_spiderling))
choices += O
if(choices.len)
cocoon_target = input(src,"What do you wish to cocoon?") in null|choices
@@ -170,16 +215,17 @@
if(do_after(src, 40, target = cocoon_target.loc))
if(busy == SPINNING_COCOON)
if(cocoon_target && isturf(cocoon_target.loc) && get_dist(src,cocoon_target) <= 1)
- var/obj/effect/spider/cocoon/C = new(cocoon_target.loc)
+ var/obj/structure/spider/cocoon/C = new(cocoon_target.loc)
var/large_cocoon = 0
C.pixel_x = cocoon_target.pixel_x
C.pixel_y = cocoon_target.pixel_y
for(var/obj/O in C.loc)
- if(istype(O, /obj/item))
- O.loc = C
- else if(istype(O, /obj/machinery) || istype(O, /obj/structure))
- O.loc = C
- large_cocoon = 1
+ if(!O.anchored)
+ if(istype(O, /obj/item))
+ O.loc = C
+ else if(istype(O, /obj/machinery) || istype(O, /obj/structure))
+ O.loc = C
+ large_cocoon = 1
for(var/mob/living/L in C.loc)
if(istype(L, /mob/living/simple_animal/hostile/poison/terror_spider))
continue
@@ -188,12 +234,15 @@
if(iscarbon(L))
regen_points += regen_points_per_kill
fed++
+ visible_message("[src] sticks a proboscis into [L] and sucks a viscous substance out.")
+ to_chat(src, "You feel invigorated!")
+ else
+ visible_message("[src] wraps [L] in a web.")
large_cocoon = 1
last_cocoon_object = 0
L.loc = C
C.pixel_x = L.pixel_x
C.pixel_y = L.pixel_y
- visible_message("[src] sticks a proboscis into [L] and sucks a viscous substance out.")
break
if(large_cocoon)
C.icon_state = pick("cocoon_large1","cocoon_large2","cocoon_large3")
@@ -201,17 +250,18 @@
busy = 0
stop_automated_movement = 0
-/mob/living/simple_animal/hostile/poison/terror_spider/prince/proc/DoPrinceSmash()
- for(var/obj/machinery/atmospherics/unary/vent_pump/P in view(1,src))
- if(P.welded)
- P.welded = 0
- P.update_icon()
- visible_message("[src] smashes the welded cover off [P]!")
- return
- for(var/obj/machinery/atmospherics/unary/vent_scrubber/C in view(1,src))
- if(C.welded)
- C.welded = 0
- C.update_icon()
- visible_message("[src] smashes the welded cover off [C]!")
- return
- to_chat(src, "There is no unwelded vent close enough to do this.")
\ No newline at end of file
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/DoVentSmash()
+ if(do_after(src, 40, target = loc))
+ for(var/obj/machinery/atmospherics/unary/vent_pump/P in view(1, src))
+ if(P.welded)
+ P.welded = 0
+ P.update_icon()
+ P.visible_message("[src] smashes the welded cover off [P]!")
+ return
+ for(var/obj/machinery/atmospherics/unary/vent_scrubber/C in view(1, src))
+ if(C.welded)
+ C.welded = 0
+ C.update_icon()
+ C.visible_message("[src] smashes the welded cover off [C]!")
+ return
+ to_chat(src, "There is no welded vent or scrubber close enough to do this.")
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/black.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/black.dm
index 04ac9d30bf2..c1a7bf45da7 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/black.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/black.dm
@@ -12,6 +12,7 @@
name = "Black Terror spider"
desc = "An ominous-looking spider, black as the darkest night. It has merciless eyes, and a blood-red hourglass pattern on its back."
spider_role_summary = "Hit-and-run attacker with extremely venomous bite."
+ ai_target_method = TS_DAMAGE_POISON
icon_state = "terror_widow"
icon_living = "terror_widow"
@@ -37,3 +38,10 @@
else
visible_message("[src] bites [target], but cannot inject venom into their [inject_target]!")
L.attack_animal(src)
+ if(!ckey && (!(target in enemies) || L.reagents.has_reagent("terror_black_toxin", 60)))
+ step_away(src,L)
+ step_away(src,L)
+ LoseTarget()
+ for(var/i in 0 to 3)
+ step_away(src, L)
+ visible_message("[src] warily eyes [L] from a distance.")
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/chem.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/chem.dm
index 8049a742994..0ed63563011 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/chem.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/chem.dm
@@ -31,16 +31,3 @@
M.EyeBlurry(6)
M.Paralyse(5)
..()
-
-// Terror Spider, Queen Toxin
-
-/datum/reagent/terror_queen_toxin
- name = "Terror Queen venom"
- id = "terror_queen_toxin"
- description = "A royally potent venom."
- color = "#CF3600"
- metabolization_rate = 2
-
-/datum/reagent/terror_queen_toxin/on_mob_life(mob/living/M)
- // make them hallucinate a lot, like a changeling sting
- M.AdjustHallucinate(50, bound_upper = 400)
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm
new file mode 100644
index 00000000000..2d2c9af9bda
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm
@@ -0,0 +1,104 @@
+// --------------------------------------------------------------------------------
+// ----------------- TERROR SPIDERS: T5 EMPRESS OF TERROR -------------------------
+// --------------------------------------------------------------------------------
+// -------------: ROLE: ruling over planets of uncountable spiders, like Xenomorph Empresses.
+// -------------: AI: none - this is strictly adminspawn-only and intended for RP events, coder testing, and teaching people 'how to queen'
+// -------------: SPECIAL: Lay Eggs ability that allows laying queen-level eggs.
+// -------------: TO FIGHT IT: run away screaming?
+// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386
+
+/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress
+ name = "Empress of Terror"
+ desc = "The unholy offspring of spiders, nightmares, and lovecraft fiction."
+ spider_role_summary = "Adminbus spider"
+ ai_target_method = TS_DAMAGE_SIMPLE
+ maxHealth = 1000
+ health = 1000
+ melee_damage_lower = 30
+ melee_damage_upper = 60
+ move_to_delay = 5
+ ventcrawler = 1
+ idle_ventcrawl_chance = 0
+ ai_playercontrol_allowtype = 0
+ ai_type = TS_AI_AGGRESSIVE
+ rapid = 1
+ canlay = 1000
+ spider_tier = TS_TIER_5
+ projectiletype = /obj/item/projectile/terrorqueenspit/empress
+ var/datum/action/innate/terrorspider/queen/empress/empresslings/empresslings_action
+ var/datum/action/innate/terrorspider/queen/empress/empresserase/empresserase_action
+ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/New()
+ ..()
+ empresserase_action = new()
+ empresserase_action.Grant(src)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/handle_automated_action()
+ return
+
+/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/NestMode()
+ ..()
+ queeneggs_action.button.name = "Empress Eggs"
+ queenfakelings_action.button.name = "Empress Lings"
+
+/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/LayQueenEggs()
+ var/eggtype = input("What kind of eggs?") as null|anything in list(TS_DESC_QUEEN, TS_DESC_MOTHER, TS_DESC_PRINCE, TS_DESC_RED, TS_DESC_GRAY, TS_DESC_GREEN, TS_DESC_BLACK, TS_DESC_PURPLE, TS_DESC_WHITE)
+ var/numlings = input("How many in the batch?") as null|anything in list(1, 2, 3, 4, 5, 10, 15, 20, 30, 40, 50)
+ if(eggtype == null || numlings == null)
+ to_chat(src, "Cancelled.")
+ return
+ switch(eggtype)
+ if(TS_DESC_RED)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red,numlings,1)
+ if(TS_DESC_GRAY)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/gray,numlings,1)
+ if(TS_DESC_GREEN)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green,numlings,1)
+ if(TS_DESC_BLACK)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/black,numlings,1)
+ if(TS_DESC_PURPLE)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple,numlings,0)
+ if(TS_DESC_WHITE)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/white,numlings,0)
+ if(TS_DESC_PRINCE)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/prince,numlings,1)
+ if(TS_DESC_MOTHER)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/mother,numlings,1)
+ if(TS_DESC_QUEEN)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/queen,numlings,1)
+ else
+ to_chat(src, "Unrecognized egg type.")
+
+/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/QueenFakeLings()
+ var/numlings = input("How many?") as null|anything in list(10, 20, 30, 40, 50)
+ var/sbpc = input("%chance to be stillborn?") as null|anything in list(0, 25, 50, 75, 100)
+ for(var/i=0, iThrough the hivemind, the raw power of [src] floods into your body, burning it from the inside out!")
+ for(var/obj/structure/spider/eggcluster/terror_eggcluster/T in ts_egg_list)
+ qdel(T)
+ for(var/obj/structure/spider/spiderling/terror_spiderling/T in ts_spiderling_list)
+ T.stillborn = 1
+ to_chat(src, "All Terror Spiders, except yourself, will die off shortly.")
+
+
+/obj/item/projectile/terrorqueenspit/empress
+ damage_type = BURN
+ damage = 30
+ bonus_tox = 0
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/gray.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/gray.dm
index ddfe48bae09..fdaa36257d2 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/gray.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/gray.dm
@@ -2,24 +2,30 @@
// --------------------------------------------------------------------------------
// ----------------- TERROR SPIDERS: T1 GRAY TERROR -------------------------------
// --------------------------------------------------------------------------------
-// -------------: ROLE: fast, weak terror spider
-// -------------: SPECIAL: silences targets
-// -------------: TO FIGHT IT: shoot it!
+// -------------: ROLE: ambusher
+// -------------: AI: hides in vents, emerges when prey is near to kill it, then hides again. Intended to scare normal crew.
+// -------------: SPECIAL: invisible when on top of a vent, emerges when prey approaches or gets trapped in webs. Bite silences targets.
+// -------------: TO FIGHT IT: shoot it through a window, or make it regret ambushing you
// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386
/mob/living/simple_animal/hostile/poison/terror_spider/gray
name = "Gray Terror spider"
- desc = "An ominous-looking gray spider, it seems jittery."
- spider_role_summary = "Fast-moving but weak spider."
+ desc = "An ominous-looking gray spider. It twitches occasionally, always seeming ready to pounce."
+ spider_role_summary = "Stealth spider that ambushes weak humans from vents."
+ ai_target_method = TS_DAMAGE_BRUTE
icon_state = "terror_gray"
icon_living = "terror_gray"
icon_dead = "terror_gray_dead"
- maxHealth = 120 // same health as hunter spider, aka, pretty weak.. but silences its targets
+ maxHealth = 120 // same health as hunter spider, aka, pretty weak.. but its almost invisible.
health = 120
melee_damage_lower = 10
melee_damage_upper = 20
- move_to_delay = 5 // normal speed
+ regen_points_per_hp = 2 // 50% higher regen speed
+ move_to_delay = 5 // slightly faster than normal
stat_attack = 1 // ensures they will target people in crit, too!
+ wander = 0 // wandering defeats the purpose of stealth
+ idle_vision_range = 3 // very low idle vision range
+ delay_web = 20 // double speed
/mob/living/simple_animal/hostile/poison/terror_spider/gray/spider_specialattack(mob/living/carbon/human/L, poisonable)
@@ -35,4 +41,102 @@
visible_message("[src] buries grey fangs deep into the [inject_target] of [target]!")
else
visible_message("[src] bites [target], but cannot inject venom into their [inject_target]!")
- L.attack_animal(src)
\ No newline at end of file
+ L.attack_animal(src)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/gray/adjustBruteLoss(damage)
+ ..(damage)
+ if(invisibility > 0)
+ GrayDeCloak()
+
+/mob/living/simple_animal/hostile/poison/terror_spider/gray/adjustFireLoss(damage)
+ ..(damage)
+ if(invisibility > 0)
+ GrayDeCloak()
+
+/mob/living/simple_animal/hostile/poison/terror_spider/gray/Aggro()
+ GrayDeCloak()
+ ..()
+
+/mob/living/simple_animal/hostile/poison/terror_spider/gray/AttackingTarget()
+ if(invisibility > 0)
+ GrayDeCloak()
+ else
+ ..()
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/GrayCloak()
+ visible_message("[src] hides in the vent.")
+ invisibility = SEE_INVISIBLE_LEVEL_ONE
+ icon_state = "terror_gray_cloaked"
+ icon_living = "terror_gray_cloaked"
+ if(!ckey)
+ vision_range = 3
+ idle_vision_range = 3
+ // Bugged, does not work yet. Also spams webs. Also doesn't look great. But... planned.
+ move_to_delay = 15 // while invisible, slow.
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/GrayDeCloak()
+ invisibility = 0
+ icon_state = "terror_gray"
+ icon_living = "terror_gray"
+ vision_range = 9
+ idle_vision_range = 9
+ move_to_delay = 5
+ prob_ai_hides_in_vents = 10
+
+
+/mob/living/simple_animal/hostile/poison/terror_spider/gray/spider_special_action()
+ if(prob(prob_ai_hides_in_vents))
+ var/obj/machinery/atmospherics/unary/vent_pump/e = locate() in get_turf(src)
+ if(e)
+ if(!e.welded || spider_awaymission)
+ if(invisibility != SEE_INVISIBLE_LEVEL_ONE) // aka: 35. ghosts have 15 with no darkness, 60 with darkness. Weird...
+ var/list/g_turfs_webbed = ListWebbedTurfs()
+ var/webcount = g_turfs_webbed.len
+ if(webcount >= 4)
+ // if there are already at least 4 webs around us, then we have a good web setup already. Cloak.
+ GrayCloak()
+ // I wonder if we should settle down here forever?
+ var/foundqueen = 0
+ for(var/mob/living/H in view(src, 10))
+ if(istype(H, /mob/living/simple_animal/hostile/poison/terror_spider/queen))
+ foundqueen = 1
+ break
+ if(!foundqueen)
+ var/list/g_turfs_visible = ListVisibleTurfs()
+ if(g_turfs_visible.len >= 12)
+ // So long as the room isn't tiny, and it has no queen in it, sure, settle there
+ // since we are settled now, disable most AI behaviors so we don't waste CPU.
+ ai_ventcrawls = 0
+ ai_spins_webs = 0
+ ai_break_lights = 0
+ prob_ai_hides_in_vents = 3
+ visible_message("[src] finishes setting up its trap in [get_area(src)].")
+ else
+ var/list/g_turfs_valid = ListValidTurfs()
+ var/turfcount = g_turfs_valid.len
+ if(turfcount == 0)
+ // if there is literally nowhere else we could put a web, cloak.
+ GrayCloak()
+ else
+ // otherwise, pick one of the valid turfs with no web to create a web there.
+ new /obj/structure/spider/terrorweb(pick(g_turfs_valid))
+ visible_message("[src] spins a web.")
+ else
+ if(invisibility == SEE_INVISIBLE_LEVEL_ONE)
+ // if our vent is welded, decloak
+ GrayDeCloak()
+ else
+ if(invisibility == SEE_INVISIBLE_LEVEL_ONE)
+ // if there is no vent under us, and we are cloaked, decloak
+ GrayDeCloak()
+ var/vdistance = 99
+ var/temp_vent = null
+ for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(7,src))
+ if(!v.welded)
+ if(get_dist(src,v) < vdistance)
+ temp_vent = v
+ vdistance = get_dist(src,v)
+ if(temp_vent)
+ if(get_dist(src,temp_vent) > 0 && get_dist(src,temp_vent) < 5)
+ step_to(src,temp_vent)
+ // if you're bumped off your vent, try to get back to it
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm
index 56265386686..89378e6a2ae 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm
@@ -3,6 +3,7 @@
// ----------------- TERROR SPIDERS: T1 GREEN TERROR ------------------------------
// --------------------------------------------------------------------------------
// -------------: ROLE: reproduction
+// -------------: AI: after it kills you, it webs you and lays new terror eggs on your body
// -------------: SPECIAL: can also create webs, web normal objects, etc
// -------------: TO FIGHT IT: kill it however you like - just don't die to it!
// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386
@@ -11,7 +12,7 @@
name = "Green Terror spider"
desc = "An ominous-looking green spider. It has a small egg-sac attached to it, and dried blood stains on its carapace."
spider_role_summary = "Average melee spider that webs its victims and lays more spider eggs"
-
+ ai_target_method = TS_DAMAGE_BRUTE
icon_state = "terror_green"
icon_living = "terror_green"
icon_dead = "terror_green_dead"
@@ -20,7 +21,6 @@
melee_damage_lower = 10
melee_damage_upper = 20
var/feedings_to_lay = 2
-
var/datum/action/innate/terrorspider/greeneggs/greeneggs_action
@@ -30,11 +30,11 @@
greeneggs_action.Grant(src)
/mob/living/simple_animal/hostile/poison/terror_spider/green/proc/DoLayGreenEggs()
- var/obj/effect/spider/eggcluster/E = locate() in get_turf(src)
+ var/obj/structure/spider/eggcluster/E = locate() in get_turf(src)
if(E)
to_chat(src, "There is already a cluster of eggs here!")
else if(fed < feedings_to_lay)
- to_chat(src, "You must wrap more prey before you can do this!")
+ to_chat(src, "You must wrap more humanoid prey before you can do this!")
else
visible_message("[src] begins to lay a cluster of eggs.")
if(prob(33))
@@ -45,6 +45,43 @@
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green, 1, 1)
fed -= feedings_to_lay
+/mob/living/simple_animal/hostile/poison/terror_spider/green/spider_special_action()
+ if(cocoon_target)
+ if(get_dist(src, cocoon_target) <= 1)
+ spider_steps_taken = 0
+ DoWrap()
+ else
+ if(spider_steps_taken > spider_max_steps)
+ spider_steps_taken = 0
+ cocoon_target = null
+ busy = 0
+ stop_automated_movement = 0
+ else
+ spider_steps_taken++
+ CreatePath(cocoon_target)
+ step_to(src,cocoon_target)
+ if(spider_debug)
+ visible_message("[src] moves towards [cocoon_target] to cocoon it.")
+ else if(fed >= feedings_to_lay)
+ DoLayGreenEggs()
+ else if(world.time > (last_cocoon_object + freq_cocoon_object))
+ last_cocoon_object = world.time
+ var/list/can_see = view(src, 10)
+ for(var/mob/living/C in can_see)
+ if(C.stat == DEAD && !isterrorspider(C) && !C.anchored)
+ spider_steps_taken = 0
+ cocoon_target = C
+ return
+ for(var/obj/O in can_see)
+ if(O.anchored)
+ continue
+ if(istype(O, /obj/item) || istype(O, /obj/structure) || istype(O, /obj/machinery))
+ if(!istype(O, /obj/item/weapon/paper))
+ cocoon_target = O
+ stop_automated_movement = 1
+ spider_steps_taken = 0
+ return
+
/mob/living/simple_animal/hostile/poison/terror_spider/green/spider_specialattack(mob/living/carbon/human/L, poisonable)
if(!poisonable)
..()
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/hive.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/hive.dm
index 2c58a133792..c3ee3dd6a35 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/hive.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/hive.dm
@@ -18,6 +18,21 @@
hsline += " AI "
to_chat(src,hsline)
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/SetHiveCommand(set_ai, set_ventcrawl)
+ var/numspiders = 0
+ for(var/mob/living/simple_animal/hostile/poison/terror_spider/T in ts_spiderlist)
+ if(spider_awaymission && !T.spider_awaymission)
+ continue
+ else if(!spider_awaymission && T.spider_awaymission)
+ continue
+ numspiders += 1
+ if(spider_tier >= T.spider_tier)
+ if(T.ai_type != set_ai)
+ T.ai_type = set_ai
+ if(T.idle_ventcrawl_chance != set_ventcrawl)
+ T.idle_ventcrawl_chance = set_ventcrawl
+ return numspiders
+
/mob/living/simple_animal/hostile/poison/terror_spider/proc/CountSpiders()
var/numspiders = 0
for(var/mob/living/simple_animal/hostile/poison/terror_spider/T in ts_spiderlist)
@@ -31,10 +46,10 @@
if(T.stat != DEAD && !T.spider_placed && spider_awaymission == T.spider_awaymission)
if(T.type == specific_type)
numspiders += 1
- for(var/obj/effect/spider/eggcluster/terror_eggcluster/E in ts_egg_list)
+ for(var/obj/structure/spider/eggcluster/terror_eggcluster/E in ts_egg_list)
if(E.spiderling_type == specific_type && E.z == z)
numspiders += E.spiderling_number
- for(var/obj/effect/spider/spiderling/terror_spiderling/L in ts_spiderling_list)
+ for(var/obj/structure/spider/spiderling/terror_spiderling/L in ts_spiderling_list)
if(!L.stillborn && L.grow_as == specific_type && L.z == z)
numspiders += 1
return numspiders
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm
index f41ebb54b43..b6e8a0680ae 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm
@@ -3,6 +3,7 @@
// ----------------- TERROR SPIDERS: T3 MOTHER OF TERROR --------------------------
// --------------------------------------------------------------------------------
// -------------: ROLE: living schmuck bait
+// -------------: AI: no special ai
// -------------: SPECIAL: spawns an ungodly number of spiderlings when killed
// -------------: TO FIGHT IT: don't! Just leave it alone! It is harmless by itself... but god help you if you aggro it.
// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386
@@ -11,7 +12,7 @@
name = "Mother of Terror spider"
desc = "An enormous spider. Hundreds of tiny spiderlings are crawling all over it. Their beady little eyes all stare at you. The horror!"
spider_role_summary = "Schmuck bait. Extremely weak in combat, but spawns many spiderlings when it dies."
-
+ ai_target_method = TS_DAMAGE_SIMPLE
icon_state = "terror_gray2"
icon_living = "terror_gray2"
icon_dead = "terror_gray2_dead"
@@ -20,23 +21,29 @@
melee_damage_lower = 10
melee_damage_upper = 20
move_to_delay = 5
-
+ idle_ventcrawl_chance = 5
spider_tier = TS_TIER_3
spider_opens_doors = 2
-
var/canspawn = 1
+ var/datum/action/innate/terrorspider/ventsmash/ventsmash_action
+/mob/living/simple_animal/hostile/poison/terror_spider/mother/New()
+ ..()
+ ventsmash_action = new()
+ ventsmash_action.Grant(src)
/mob/living/simple_animal/hostile/poison/terror_spider/mother/death(gibbed)
if(canspawn)
canspawn = 0
for(var/i in 0 to 30)
- var/obj/effect/spider/spiderling/terror_spiderling/S = new /obj/effect/spider/spiderling/terror_spiderling(get_turf(src))
+ var/obj/structure/spider/spiderling/terror_spiderling/S = new /obj/structure/spider/spiderling/terror_spiderling(get_turf(src))
S.grow_as = pick(/mob/living/simple_animal/hostile/poison/terror_spider/red, /mob/living/simple_animal/hostile/poison/terror_spider/gray)
if(prob(66))
S.stillborn = 1
else if(prob(10))
S.grow_as = pick(/mob/living/simple_animal/hostile/poison/terror_spider/black, /mob/living/simple_animal/hostile/poison/terror_spider/green)
+ S.amount_grown = 50 // double speed growth
+ S.immediate_ventcrawl = 1
visible_message("[src] breaks apart, the many spiders on its back scurrying everywhere!")
degenerate = 1
..()
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm
index 5a3a746e1a9..40e6515668f 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm
@@ -12,33 +12,35 @@
name = "Prince of Terror spider"
desc = "An enormous, terrifying spider. It looks like it is judging everything it sees. Its hide seems armored, and it bears the scars of many battles."
spider_role_summary = "Miniboss terror spider. Lightning bruiser."
-
+ ai_target_method = TS_DAMAGE_BRUTE
icon_state = "terror_allblack"
icon_living = "terror_allblack"
icon_dead = "terror_allblack_dead"
-
maxHealth = 600 // 30 laser shots
health = 600
regen_points_per_hp = 6 // double the normal - IE halved regen speed
-
- melee_damage_lower = 20
- melee_damage_upper = 30
+ melee_damage_lower = 30
+ melee_damage_upper = 40
move_to_delay = 4 // faster than normal
-
ventcrawler = 0
+ ai_ventcrawls = 0
environment_smash = 3
-
loot = list(/obj/item/clothing/accessory/medal)
+ idle_ventcrawl_chance = 0
spider_tier = TS_TIER_3
spider_opens_doors = 2
-
- var/datum/action/innate/terrorspider/princesmash/princesmash_action
-
+ var/datum/action/innate/terrorspider/thickweb/thickweb_action
/mob/living/simple_animal/hostile/poison/terror_spider/prince/New()
..()
- princesmash_action = new()
- princesmash_action.Grant(src)
+ thickweb_action = new()
+ thickweb_action.Grant(src)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/prince/death(gibbed)
+ if(!hasdied)
+ if(spider_uo71)
+ UnlockBlastDoors("UO71_SciStorage")
+ ..()
/mob/living/simple_animal/hostile/poison/terror_spider/prince/spider_specialattack(mob/living/carbon/human/L)
if(prob(15))
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm
index 7b801d76651..6b524872552 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm
@@ -3,6 +3,7 @@
// ----------------- TERROR SPIDERS: T2 PURPLE TERROR -----------------------------
// --------------------------------------------------------------------------------
// -------------: ROLE: guarding queen nests
+// -------------: AI: dies if too far from queen
// -------------: SPECIAL: chance to stun on hit
// -------------: TO FIGHT IT: shoot it from range, bring friends!
// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386
@@ -11,7 +12,7 @@
name = "Purple Terror spider"
desc = "An ominous-looking purple spider. It looks about warily, as if waiting for something."
spider_role_summary = "Guards the nest of the Queen of Terror."
-
+ ai_target_method = TS_DAMAGE_BRUTE
icon_state = "terror_purple"
icon_living = "terror_purple"
icon_dead = "terror_purple_dead"
@@ -20,17 +21,28 @@
melee_damage_lower = 15
melee_damage_upper = 25
move_to_delay = 6
-
spider_tier = TS_TIER_2
spider_opens_doors = 2
-
ventcrawler = 0
+ ai_ventcrawls = 0
environment_smash = 3
-
+ idle_ventcrawl_chance = 0 // stick to the queen!
var/dcheck_counter = 0
var/queen_visible = 1
var/cycles_noqueen = 0
+
+/mob/living/simple_animal/hostile/poison/terror_spider/purple/death(gibbed)
+ if(spider_myqueen)
+ var/mob/living/simple_animal/hostile/poison/terror_spider/queen/Q = spider_myqueen
+ if(Q.stat != DEAD && !Q.ckey)
+ if(get_dist(src,Q) > 20)
+ if(!degenerate && !Q.degenerate)
+ degenerate = 1
+ Q.DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple,1,0)
+ visible_message("[src] chitters in the direction of [Q]!")
+ . = ..()
+
/mob/living/simple_animal/hostile/poison/terror_spider/purple/spider_specialattack(mob/living/carbon/human/L, poisonable)
if(cycles_noqueen < 6 && prob(10))
visible_message("[src] rams into [L], knocking them to the floor!")
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm
index 6ee528218ce..3b6266e777b 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm
@@ -3,6 +3,7 @@
// ----------------- TERROR SPIDERS: T4 QUEEN OF TERROR ---------------------------
// --------------------------------------------------------------------------------
// -------------: ROLE: gamma-level threat to the whole station, like a blob
+// -------------: AI: builds a nest, lays many eggs, attempts to take over the station
// -------------: SPECIAL: spins webs, breaks lights, breaks cameras, webs objects, lays eggs, commands other spiders...
// -------------: TO FIGHT IT: bring an army, and take no prisoners. Mechs and/or decloner guns are a very good idea.
// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386
@@ -11,12 +12,13 @@
name = "Queen of Terror spider"
desc = "An enormous, terrifying spider. Its egg sac is almost as big as its body, and teeming with spider eggs!"
spider_role_summary = "Commander of the spider forces. Lays eggs, directs the brood."
-
+ ai_target_method = TS_DAMAGE_SIMPLE
icon_state = "terror_queen"
icon_living = "terror_queen"
icon_dead = "terror_queen_dead"
maxHealth = 200
health = 200
+ regen_points_per_tick = 3
melee_damage_lower = 10
melee_damage_upper = 20
move_to_delay = 15 // yeah, this is very slow, but
@@ -28,33 +30,32 @@
var/lastnestsetup = 0
var/neststep = 0
var/hasnested = 0
- var/spider_max_per_nest = 20 // above this, queen stops spawning more, and declares war.
-
- var/canlay = 0 // main counter for egg-laying ability! # = num uses, incremented at intervals
+ var/spider_max_per_nest = 25 // above this, AI queens become stable
+ var/canlay = 4 // main counter for egg-laying ability! # = num uses, incremented at intervals
+ var/eggslaid = 0
var/spider_can_fakelings = 3 // spawns defective spiderlings that don't grow up, used to freak out crew, atmosphere
-
+ idle_ventcrawl_chance = 0
force_threshold = 18 // outright immune to anything of force under 18, this means welders can't hurt it, only guns can
-
ranged = 1
retreat_distance = 5
minimum_distance = 5
projectilesound = 'sound/weapons/pierce.ogg'
projectiletype = /obj/item/projectile/terrorqueenspit
-
spider_tier = TS_TIER_4
spider_opens_doors = 2
loot = list(/obj/item/clothing/accessory/medal)
-
var/datum/action/innate/terrorspider/queen/queennest/queennest_action
var/datum/action/innate/terrorspider/queen/queensense/queensense_action
var/datum/action/innate/terrorspider/queen/queeneggs/queeneggs_action
var/datum/action/innate/terrorspider/queen/queenfakelings/queenfakelings_action
-
+ var/datum/action/innate/terrorspider/ventsmash/ventsmash_action
/mob/living/simple_animal/hostile/poison/terror_spider/queen/New()
..()
queennest_action = new()
queennest_action.Grant(src)
+ ventsmash_action = new()
+ ventsmash_action.Grant(src)
spider_myqueen = src
if(spider_awaymission)
spider_growinstantly = 1
@@ -65,10 +66,15 @@
if(.) // if mob is NOT dead
if(ckey && canlay < 12 && hasnested) // max 12 eggs worth stored at any one time, realistically that's tons.
if(world.time > (spider_lastspawn + spider_spawnfrequency))
- canlay++
+ if(eggslaid >= 20)
+ canlay += 3
+ else if(eggslaid >= 10)
+ canlay += 2
+ else
+ canlay++
spider_lastspawn = world.time
if(canlay == 1)
- to_chat(src, "You are able to lay eggs again.")
+ to_chat(src, "You have an egg available to lay.")
else if(canlay == 12)
to_chat(src, "You have [canlay] eggs available to lay. You won't grow any more eggs until you lay some of your existing ones.")
else
@@ -76,6 +82,9 @@
/mob/living/simple_animal/hostile/poison/terror_spider/queen/death(gibbed)
if(!hasdied)
+ SetHiveCommand(0, 15) // Hive becomes very aggressive.
+ if(spider_uo71)
+ UnlockBlastDoors("UO71_Caves")
// When a queen dies, so do her player-controlled purple-type guardians. Intended as a motivator for purples to ensure they guard her.
for(var/mob/living/simple_animal/hostile/poison/terror_spider/purple/P in ts_spiderlist)
if(ckey)
@@ -84,6 +93,134 @@
P.degenerate = 1
..()
+/mob/living/simple_animal/hostile/poison/terror_spider/queen/Retaliate()
+ ..()
+ for(var/mob/living/simple_animal/hostile/poison/terror_spider/T in ts_spiderlist)
+ T.enemies |= enemies
+
+/mob/living/simple_animal/hostile/poison/terror_spider/queen/handle_automated_action()
+ ..()
+ if(!stat && !ckey && AIStatus != AI_OFF && !target && !path_to_vent)
+ switch(neststep)
+ if(0)
+ // we have no nest :(
+ var/ok_to_nest = 1
+ var/area/new_area = get_area(loc)
+ if(new_area)
+ if(findtext(new_area.name, "hall"))
+ ok_to_nest = 0
+ // nesting in a hallway would be very stupid - crew would find and kill you almost instantly
+ var/numhostiles = 0
+ for(var/mob/living/H in oview(10, src))
+ if(!istype(H, /mob/living/simple_animal/hostile/poison/terror_spider))
+ if(H.stat != DEAD)
+ numhostiles += 1
+ // nesting RIGHT NEXT TO SOMEONE is even worse
+ if(numhostiles > 0)
+ ok_to_nest = 0
+ var/vdistance = 99
+ for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(10, src))
+ if(!v.welded)
+ if(get_dist(src, v) < vdistance)
+ entry_vent = v
+ vdistance = get_dist(src, v)
+ if(!entry_vent)
+ ok_to_nest = 0
+ // don't nest somewhere with no vent - your brood won't be able to get out!
+ if(ok_to_nest && entry_vent)
+ nest_vent = entry_vent
+ neststep = 1
+ visible_message("\The [src] settles down, starting to build a nest.")
+ else if(entry_vent)
+ if(!path_to_vent)
+ visible_message("\The [src] looks around warily - then seeks a better nesting ground.")
+ path_to_vent = 1
+ else
+ visible_message("\The [src] looks around, searching for the vent that should be there, but isn't. A bluespace portal forms on her, and she is gone.")
+ qdel(src)
+ new /obj/effect/portal(get_turf(loc))
+ if(1)
+ if(world.time > (lastnestsetup + nestfrequency))
+ lastnestsetup = world.time
+ neststep = 2
+ NestMode()
+ if(2)
+ if(world.time > (lastnestsetup + nestfrequency))
+ lastnestsetup = world.time
+ spider_lastspawn = world.time
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, 2, 0)
+ neststep = 3
+ if(3)
+ if(world.time > (spider_lastspawn + spider_spawnfrequency))
+ if(prob(20))
+ var/obj/structure/spider/eggcluster/terror_eggcluster/N = locate() in get_turf(src)
+ if(!N)
+ spider_lastspawn = world.time
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green, 2, 0)
+ neststep = 4
+ if(4)
+ if(world.time > (spider_lastspawn + spider_spawnfrequency))
+ if(prob(20))
+ var/obj/structure/spider/eggcluster/terror_eggcluster/N = locate() in get_turf(src)
+ if(!N)
+ spider_lastspawn = world.time
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red, 2, 1)
+ neststep = 5
+ if(5)
+ if(world.time > (spider_lastspawn + spider_spawnfrequency))
+ if(prob(20))
+ var/obj/structure/spider/eggcluster/terror_eggcluster/N = locate() in get_turf(src)
+ if(!N)
+ if(!spider_awaymission)
+ QueenFakeLings()
+ spider_lastspawn = world.time
+ if(prob(33))
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/gray, 2, 1)
+ else if(prob(50))
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red, 2, 1)
+ else
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green, 2, 1)
+ var/spidercount = CountSpiders()
+ if(spidercount >= spider_max_per_nest) // station overwhelmed!
+ neststep = 6
+ if(6)
+ if(world.time > (spider_lastspawn + spider_spawnfrequency))
+ spider_lastspawn = world.time
+ // go hostile, EXTERMINATE MODE.
+ SetHiveCommand(0, 15) // AI=0 (attack everyone), ventcrawl=15%/tick
+ var/numspiders = CountSpiders()
+ if(numspiders < spider_max_per_nest)
+ if(prob(33))
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/black, 2, 1)
+ else if(prob(50))
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red, 2, 0)
+ else
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green, 2, 1)
+ else if(spider_awaymission)
+ neststep = 7
+ spider_spawnfrequency = spider_spawnfrequency_stable
+ // if we're an away mission queen... don't keep spawning spiders at high rates. Away team should have a chance.
+ if(7)
+ if(world.time > (spider_lastspawn + spider_spawnfrequency))
+ spider_lastspawn = world.time
+ var/numspiders = CountSpiders()
+ if(numspiders < spider_max_per_nest)
+ // someone is killing my children...
+ if(prob(25))
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/black, 2, 1)
+ else if(prob(33))
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red, 2, 0)
+ else if(prob(50))
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green, 2, 1)
+ else
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, 2, 0)
+ neststep = 6
+
+/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/NestPrompt()
+ var/confirm = alert(src, "Are you sure you want to nest? You will be able to lay eggs, and smash walls, but not ventcrawl.","Nest?","Yes","No")
+ if(confirm == "Yes")
+ NestMode()
+
/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/NestMode()
queeneggs_action = new()
queeneggs_action.Grant(src)
@@ -94,6 +231,7 @@
queennest_action.Remove(src)
hasnested = 1
ventcrawler = 0
+ ai_ventcrawls = 0
environment_smash = 3
DoQueenScreech(8, 100, 8, 100)
MassFlicker()
@@ -113,6 +251,8 @@
I.flicker()
/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/LayQueenEggs()
+ if(stat == DEAD)
+ return
if(!hasnested)
to_chat(src, "You must nest before doing this.")
return
@@ -159,8 +299,8 @@
if(eggtype == null || numlings == null)
to_chat(src, "Cancelled.")
return
- //spider_lastspawn = world.time // don't think we actually need this, if queen is laying manually canlay controls her rate.
canlay -= numlings
+ eggslaid += numlings
if(eggtype == TS_DESC_RED)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red, numlings, 1)
else if(eggtype == TS_DESC_GRAY)
@@ -184,11 +324,14 @@
C.toggle_cam(src, 0)
/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/QueenFakeLings()
+ if(eggslaid < 10)
+ to_chat(src, "You must lay at least 10 eggs before doing this.")
+ return
if(spider_can_fakelings)
spider_can_fakelings--
var/numlings = 15
for(var/i in 1 to numlings)
- var/obj/effect/spider/spiderling/terror_spiderling/S = new /obj/effect/spider/spiderling/terror_spiderling(get_turf(src))
+ var/obj/structure/spider/spiderling/terror_spiderling/S = new /obj/structure/spider/spiderling/terror_spiderling(get_turf(src))
S.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/red
S.stillborn = 1
S.name = "Evil-Looking Spiderling"
@@ -203,12 +346,13 @@
damage = 0
icon_state = "toxin"
damage_type = TOX
+ var/bonus_tox = 30
/obj/item/projectile/terrorqueenspit/on_hit(mob/living/carbon/target)
if(ismob(target))
var/mob/living/L = target
if(L.reagents)
if(L.can_inject(null, 0, "chest", 0))
- L.reagents.add_reagent("terror_queen_toxin", 15)
- if(!istype(L, /mob/living/simple_animal/hostile/poison/terror_spider))
- L.adjustToxLoss(30)
\ No newline at end of file
+ L.Hallucinate(400)
+ if(!isterrorspider(L))
+ L.adjustToxLoss(bonus_tox)
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm
index cd48027775d..3a77209cbfd 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm
@@ -12,9 +12,8 @@
/mob/living/simple_animal/hostile/poison/terror_spider/red
name = "Red Terror spider"
desc = "An ominous-looking red spider, it has eight beady red eyes, and nasty, big, pointy fangs! It looks like it has a vicious streak a mile wide."
-
spider_role_summary = "High health, high damage, very slow, melee juggernaut"
-
+ ai_target_method = TS_DAMAGE_BRUTE
icon_state = "terror_red"
icon_living = "terror_red"
icon_dead = "terror_red_dead"
@@ -55,6 +54,6 @@
if(health > (maxHealth/2))
enrage = 1
visible_message("[src] retracts its fangs a little.")
- melee_damage_lower = melee_damage_lower_rage0
- melee_damage_upper = melee_damage_upper_rage0
+ melee_damage_lower = melee_damage_lower_rage1
+ melee_damage_upper = melee_damage_upper_rage1
..()
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm
index ccb7a5c1148..d1ffa073582 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm
@@ -3,7 +3,7 @@
// ----------------- TERROR SPIDERS: SPIDERLINGS (USED BY GREEN, WHITE, QUEEN AND MOTHER TYPES)
// --------------------------------------------------------------------------------
-/obj/effect/spider/spiderling/terror_spiderling
+/obj/structure/spider/spiderling/terror_spiderling
name = "spiderling"
desc = "A fast-moving tiny spider, prone to making aggressive hissing sounds. Hope it doesn't grow up."
icon_state = "spiderling"
@@ -14,16 +14,18 @@
faction = list("terrorspiders")
var/spider_myqueen = null
var/use_vents = 1
+ var/list/enemies = list()
+ var/immediate_ventcrawl = 0
-/obj/effect/spider/spiderling/terror_spiderling/New()
+/obj/structure/spider/spiderling/terror_spiderling/New()
..()
ts_spiderling_list += src
-/obj/effect/spider/spiderling/terror_spiderling/Destroy()
+/obj/structure/spider/spiderling/terror_spiderling/Destroy()
ts_spiderling_list -= src
return ..()
-/obj/effect/spider/spiderling/terror_spiderling/Bump(atom/A)
+/obj/structure/spider/spiderling/terror_spiderling/Bump(atom/A)
if(istype(A, /obj/structure/table))
forceMove(A.loc)
else if(istype(A, /obj/machinery/recharge_station))
@@ -31,7 +33,7 @@
else
..()
-/obj/effect/spider/spiderling/terror_spiderling/process()
+/obj/structure/spider/spiderling/terror_spiderling/process()
if(travelling_in_vent)
if(isturf(loc))
travelling_in_vent = 0
@@ -72,8 +74,10 @@
var/list/nearby = oview(10, src)
if(nearby.len)
var/target_atom = pick(nearby)
- walk_to(src, target_atom)
- else if(prob(10) && use_vents)
+ if(!istype(get_turf(target_atom),/turf/space))
+ walk_to(src, target_atom)
+ else if(immediate_ventcrawl || (prob(10) && use_vents))
+ immediate_ventcrawl = 0
for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(7,src))
if(!v.welded)
entry_vent = v
@@ -91,6 +95,7 @@
S.faction = faction
S.spider_myqueen = spider_myqueen
S.master_commander = master_commander
+ S.enemies = enemies
qdel(src)
// --------------------------------------------------------------------------------
@@ -99,20 +104,21 @@
/mob/living/simple_animal/hostile/poison/terror_spider/proc/DoLayTerrorEggs(lay_type, lay_number, lay_crawl)
stop_automated_movement = 1
- var/obj/effect/spider/eggcluster/terror_eggcluster/C = new /obj/effect/spider/eggcluster/terror_eggcluster(get_turf(src))
+ var/obj/structure/spider/eggcluster/terror_eggcluster/C = new /obj/structure/spider/eggcluster/terror_eggcluster(get_turf(src))
C.spiderling_type = lay_type
C.spiderling_number = lay_number
C.spiderling_ventcrawl = lay_crawl
C.faction = faction
C.spider_myqueen = spider_myqueen
C.master_commander = master_commander
+ C.enemies = enemies
if(spider_growinstantly)
C.amount_grown = 250
C.spider_growinstantly = 1
spawn(10)
stop_automated_movement = 0
-/obj/effect/spider/eggcluster/terror_eggcluster
+/obj/structure/spider/eggcluster/terror_eggcluster
name = "terror egg cluster"
desc = "A cluster of tiny spider eggs. They pulse with a strong inner life, and appear to have sharp thorns on the sides."
icon_state = "eggs"
@@ -122,8 +128,9 @@
var/spiderling_type = null
var/spiderling_number = 1
var/spiderling_ventcrawl = 1
+ var/list/enemies = list()
-/obj/effect/spider/eggcluster/terror_eggcluster/New()
+/obj/structure/spider/eggcluster/terror_eggcluster/New()
..()
ts_egg_list += src
spawn(50)
@@ -146,27 +153,28 @@
else if(spiderling_type == /mob/living/simple_animal/hostile/poison/terror_spider/queen)
name = "queen of terror eggs"
-/obj/effect/spider/eggcluster/terror_eggcluster/Destroy()
+/obj/structure/spider/eggcluster/terror_eggcluster/Destroy()
ts_egg_list -= src
return ..()
-/obj/effect/spider/eggcluster/terror_eggcluster/process()
+/obj/structure/spider/eggcluster/terror_eggcluster/process()
amount_grown += rand(0,2)
if(amount_grown >= 100)
var/num = spiderling_number
for(var/i=0, i melee_damage_upper)
+ continue
+ if(H in enemies)
+ targets2 += H
+ else
+ targets3 += H
+ for(var/obj/mecha/M in view(src, vision_range))
+ if(get_dist(M, src) <= 2)
+ targets2 += M
+ else
+ targets3 += M
+ for(var/obj/spacepod/S in view(src, vision_range))
+ targets3 += S
+ if(targets1.len)
+ return targets1
+ if(targets2.len)
+ return targets2
+ return targets3
+
+/mob/living/simple_animal/hostile/poison/terror_spider/LoseTarget()
+ if(target && isliving(target))
+ var/mob/living/T = target
+ if(T.stat > 0)
+ killcount++
+ regen_points += regen_points_per_kill
+ attackstep = 0
+ attackcycles = 0
+ ..()
+
+// --------------------------------------------------------------------------------
+// --------------------- TERROR SPIDERS: AI BEHAVIOR CODE -------------------------
+// --------------------------------------------------------------------------------
+
+/mob/living/simple_animal/hostile/poison/terror_spider/handle_automated_action()
+ if (stat || ckey)
+ return ..()
+ if(AIStatus != AI_OFF && !target)
+ var/my_ventcrawl_freq = freq_ventcrawl_idle
+ if(ts_count_dead > 0)
+ if(world.time < (ts_death_last + ts_death_window))
+ my_ventcrawl_freq = freq_ventcrawl_combat
+ // First, check for general actions that any spider could take.
+ if(path_to_vent)
+ if(entry_vent)
+ if(spider_steps_taken > spider_max_steps)
+ path_to_vent = 0
+ stop_automated_movement = 0
+ spider_steps_taken = 0
+ path_to_vent = 0
+ entry_vent = null
+ else if(get_dist(src, entry_vent) <= 1)
+ path_to_vent = 0
+ stop_automated_movement = 1
+ spider_steps_taken = 0
+ spawn(50)
+ stop_automated_movement = 0
+ TSVentCrawlRandom(entry_vent)
+ else
+ spider_steps_taken++
+ CreatePath(entry_vent)
+ step_to(src,entry_vent)
+ if(spider_debug > 0)
+ visible_message("[src] moves towards the vent [entry_vent].")
+ else
+ path_to_vent = 0
+ else if(ai_break_lights && world.time > (last_break_light + freq_break_light))
+ last_break_light = world.time
+ for(var/obj/machinery/light/L in range(1, src))
+ if(!L.status)
+ step_to(src,L)
+ L.on = 1
+ L.broken()
+ L.do_attack_animation(src)
+ visible_message("[src] smashes the [L.name].")
+ break
+ else if(ai_spins_webs && world.time > (last_spins_webs + freq_spins_webs))
+ last_spins_webs = world.time
+ var/obj/structure/spider/terrorweb/T = locate() in get_turf(src)
+ if(!T)
+ var/obj/structure/spider/terrorweb/W = new /obj/structure/spider/terrorweb(loc)
+ if(web_infects)
+ W.infectious = 1
+ W.name = "sharp terror web"
+ visible_message("[src] puts up some spider webs.")
+ else if(ai_ventcrawls && world.time > (last_ventcrawl_time + my_ventcrawl_freq))
+ if(prob(idle_ventcrawl_chance))
+ last_ventcrawl_time = world.time
+ var/vdistance = 99
+ for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(10, src))
+ if(!v.welded)
+ if(get_dist(src,v) < vdistance)
+ entry_vent = v
+ vdistance = get_dist(src,v)
+ if(entry_vent)
+ path_to_vent = 1
+ else
+ // If none of the general actions apply, check for class-specific actions.
+ spider_special_action()
+ else if(AIStatus != AI_OFF && target)
+ CreatePath(target)
+ ..()
+
+/mob/living/simple_animal/hostile/poison/terror_spider/adjustBruteLoss(damage)
+ ..(damage)
+ Retaliate()
+
+/mob/living/simple_animal/hostile/poison/terror_spider/adjustFireLoss(damage)
+ ..(damage)
+ Retaliate()
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/Retaliate()
+ var/list/around = oview(src, 7)
+ var/list/ts_nearby = list()
+ for(var/atom/movable/A in around)
+ if(A in enemies)
+ continue
+ if(isterrorspider(A))
+ ts_nearby += A
+ continue
+ if(isliving(A))
+ var/mob/living/M = A
+ if(!("terrorspiders" in M.faction))
+ enemies |= M
+ else if(istype(A, /obj/mecha))
+ var/obj/mecha/M = A
+ if(M.occupant)
+ enemies |= M
+ enemies |= M.occupant
+ else if(istype(A, /obj/spacepod))
+ var/obj/spacepod/M = A
+ if(M.pilot)
+ enemies |= M
+ enemies |= M.pilot
+ for(var/mob/living/simple_animal/hostile/poison/terror_spider/H in ts_nearby)
+ var/retaliate_faction_check = 0
+ for(var/F in faction)
+ if(F in H.faction)
+ retaliate_faction_check = 1
+ break
+ if(retaliate_faction_check && !attack_same && !H.attack_same)
+ H.enemies |= enemies
+ return 0
+
+// --------------------------------------------------------------------------------
+// --------------------- TERROR SPIDERS: PATHING CODE -----------------------------
+// --------------------------------------------------------------------------------
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/CreatePath(mygoal)
+ var/m2 = get_turf(src)
+ if(m2 == mylocation)
+ chasecycles++
+ ClearObstacle(get_turf(mygoal))
+ if(chasecycles >= 1)
+ chasecycles = 0
+ if(spider_opens_doors)
+ var/tgt_dir = get_dir(src,mygoal)
+ for(var/obj/machinery/door/airlock/A in view(1, src))
+ if(A.density)
+ try_open_airlock(A)
+ for(var/obj/machinery/door/firedoor/F in view(1, src))
+ if(tgt_dir == get_dir(src,F) && F.density && !F.welded)
+ visible_message("[src] pries open the firedoor!")
+ F.open()
+
+ else
+ mylocation = m2
+ chasecycles = 0
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/ClearObstacle(turf/target_turf)
+ var/list/valid_obstacles = list(/obj/structure/window, /obj/structure/closet, /obj/structure/table, /obj/structure/grille, /obj/structure/rack, /obj/machinery/door/window)
+ for(var/dir in cardinal) // North, South, East, West
+ var/obj/structure/obstacle = locate(/obj/structure, get_step(src, dir))
+ if(is_type_in_list(obstacle, valid_obstacles))
+ obstacle.attack_animal(src)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/TSVentCrawlRandom(/var/entry_vent)
+ if(entry_vent)
+ if(get_dist(src, entry_vent) <= 2)
+ var/list/vents = list()
+ for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in entry_vent.parent.other_atmosmch)
+ vents.Add(temp_vent)
+ if(!vents.len)
+ entry_vent = null
+ return
+ var/obj/machinery/atmospherics/unary/vent_pump/exit_vent = pick(vents)
+ visible_message("[src] scrambles into the ventillation ducts!", "You hear something squeezing through the ventilation ducts.")
+ spawn(rand(20,60))
+ var/original_location = loc
+ forceMove(exit_vent)
+ var/travel_time = round(get_dist(loc, exit_vent.loc) / 2)
+ spawn(travel_time)
+ if(!exit_vent || exit_vent.welded)
+ forceMove(original_location)
+ entry_vent = null
+ return
+ if(prob(50))
+ audible_message("You hear something squeezing through the ventilation ducts.")
+ spawn(travel_time)
+ if(!exit_vent || exit_vent.welded)
+ forceMove(original_location)
+ entry_vent = null
+ return
+ forceMove(exit_vent.loc)
+ entry_vent = null
+ var/area/new_area = get_area(loc)
+ if(new_area)
+ new_area.Entered(src)
+
+// --------------------------------------------------------------------------------
+// --------------------- TERROR SPIDERS: ENVIRONMENT CODE -------------------------
+// --------------------------------------------------------------------------------
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/ListValidTurfs()
+ var/list/potentials = list()
+ for(var/turf/simulated/T in oview(3,get_turf(src)))
+ if(T.density == 0 && get_dist(get_turf(src),T) == 3)
+ var/obj/structure/spider/terrorweb/W = locate() in T
+ if(!W)
+ var/obj/structure/grille/G = locate() in T
+ if(!G)
+ var/obj/structure/window/O = locate() in T
+ if(!O)
+ potentials += T
+ return potentials
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/ListWebbedTurfs()
+ var/list/webbed = list()
+ for(var/turf/simulated/T in oview(3,get_turf(src)))
+ if(T.density == 0 && get_dist(get_turf(src),T) == 3)
+ var/obj/structure/spider/terrorweb/W = locate() in T
+ if(W)
+ webbed += T
+ return webbed
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/ListVisibleTurfs()
+ var/list/vturfs = list()
+ for(var/turf/simulated/T in oview(7,get_turf(src)))
+ if(T.density == 0)
+ vturfs += T
+ return vturfs
+
+// --------------------------------------------------------------------------------
+// --------------------- TERROR SPIDERS: MISC AI CODE -----------------------------
+// --------------------------------------------------------------------------------
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/UnlockBlastDoors(target_id_tag)
+ for(var/obj/machinery/door/poddoor/P in airlocks)
+ if(P.density && P.id_tag == target_id_tag && P.z == z && !P.operating)
+ P.open()
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
index 7fa291eb2a6..caff5e2017f 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
@@ -1,4 +1,3 @@
-
var/global/list/ts_ckey_blacklist = list()
var/global/ts_count_dead = 0
var/global/ts_count_alive_awaymission = 0
@@ -43,6 +42,15 @@ var/global/list/ts_spiderling_list = list()
// Ventcrawling
ventcrawler = 1 // allows player ventcrawling
+ var/ai_ventcrawls = 1
+ var/idle_ventcrawl_chance = 3 // default 3% chance to ventcrawl when not in combat to a random exit vent
+ var/freq_ventcrawl_combat = 1800 // 3 minutes
+ var/freq_ventcrawl_idle = 9000 // 15 minutes
+ var/last_ventcrawl_time = -9000 // Last time the spider crawled. Used to prevent excessive crawling. Setting to freq*-1 ensures they can crawl once on spawn.
+
+ // AI movement tracking
+ var/spider_steps_taken = 0 // leave at 0, its a counter for ai steps taken.
+ var/spider_max_steps = 15 // after we take X turns trying to do something, give up!
// Speech
speak_chance = 0 // quiet but deadly
@@ -71,15 +79,35 @@ var/global/list/ts_spiderling_list = list()
aggro_vision_range = 10
see_in_dark = 10
nightvision = 1
- vision_type = new /datum/vision_override/nightvision/thermals/ling_augmented_eyesight
see_invisible = 5
+ sight = SEE_MOBS
+
+ // AI aggression settings
+ var/ai_type = TS_AI_AGGRESSIVE // 0 = aggressive to everyone, 1 = defends self only
+ var/ai_target_method = TS_DAMAGE_SIMPLE
// AI player control by ghosts
var/ai_playercontrol_allowtype = 1 // if 0, this specific class of spider is not player-controllable. Default set in code for each class, cannot be changed.
+ var/ai_break_lights = 1 // AI lightbreaking behavior
+ var/freq_break_light = 600
+ var/last_break_light = 0 // leave this, changed by procs.
+
+ var/ai_spins_webs = 1 // AI web-spinning behavior
+ var/freq_spins_webs = 600
+ var/last_spins_webs = 0 // leave this, changed by procs.
+ var/delay_web = 40 // delay between starting to spin web, and finishing
+
+ var/freq_cocoon_object = 1200 // two minutes between each attempt
+ var/last_cocoon_object = 0 // leave this, changed by procs.
+
+ var/prob_ai_hides_in_vents = 15 // probabily of a gray spider hiding in a vent
+
var/spider_opens_doors = 1 // all spiders can open firedoors (they have no security). 1 = can open depowered doors. 2 = can open powered doors
faction = list("terrorspiders")
var/spider_awaymission = 0 // if 1, limits certain behavior in away missions
+ var/spider_uo71 = 0 // if 1, spider is in the UO71 away mission
+ var/spider_unlock_id_tag = "" // if defined, unlock awaymission blast doors with this tag on death
var/spider_role_summary = "UNDEFINED"
var/spider_placed = 0
@@ -90,16 +118,19 @@ var/global/list/ts_spiderling_list = list()
var/obj/machinery/atmospherics/unary/vent_pump/nest_vent // home vent, usually used by queens
var/fed = 0
var/travelling_in_vent = 0
+ var/list/enemies = list()
+ var/path_to_vent = 0
var/killcount = 0
var/busy = 0 // leave this alone!
var/spider_tier = TS_TIER_1 // 1 for red,gray,green. 2 for purple,black,white, 3 for prince, mother. 4 for queen
var/hasdied = 0
+ var/list/spider_special_drops = list()
var/attackstep = 0
var/attackcycles = 0
var/spider_myqueen = null
var/mylocation = null
var/chasecycles = 0
- var/last_cocoon_object = 0 // leave this, changed by procs.
+ var/web_infects = 0
var/datum/action/innate/terrorspider/web/web_action
var/datum/action/innate/terrorspider/wrap/wrap_action
@@ -124,18 +155,20 @@ var/global/list/ts_spiderling_list = list()
/mob/living/simple_animal/hostile/poison/terror_spider/AttackingTarget()
if(isterrorspider(target))
+ if(target in enemies)
+ enemies -= target
var/mob/living/simple_animal/hostile/poison/terror_spider/T = target
if(T.spider_tier > spider_tier)
- visible_message("[src] bows in respect for the terrifying presence of [target].")
+ visible_message("[src] cowers before [target].")
else if(T.spider_tier == spider_tier)
visible_message("[src] nuzzles [target].")
else if(T.spider_tier < spider_tier && spider_tier >= 4)
- visible_message("[src] gives [target] a stern look.")
+ target.attack_animal(src)
else
visible_message("[src] harmlessly nuzzles [target].")
T.CheckFaction()
CheckFaction()
- else if(istype(target, /obj/effect/spider/cocoon))
+ else if(istype(target, /obj/structure/spider/cocoon))
to_chat(src, "Destroying our own cocoons would not help us.")
else if(istype(target, /obj/machinery/door/firedoor))
var/obj/machinery/door/firedoor/F = target
@@ -223,6 +256,14 @@ var/global/list/ts_spiderling_list = list()
if(is_away_level(z))
spider_awaymission = 1
ts_count_alive_awaymission++
+ if(spider_tier >= 3)
+ ai_ventcrawls = 0 // means that pre-spawned bosses on away maps won't ventcrawl. Necessary to keep prince/mother in one place.
+ if(istype(get_area(src), /area/awaymission/UO71)) // if we are playing the away mission with our special spiders...
+ spider_uo71 = 1
+ if(world.time < 600)
+ // these are static spiders, specifically for the UO71 away mission, make them stay in place
+ ai_ventcrawls = 0
+ spider_placed = 1
else
ts_count_alive_station++
// after 30 seconds, assuming nobody took control of it yet, offer it to ghosts.
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/white.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/white.dm
index 191eed19c47..0eced254544 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/white.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/white.dm
@@ -1,4 +1,3 @@
-
// --------------------------------------------------------------------------------
// ----------------- TERROR SPIDERS: T2 WHITE TERROR ------------------------------
// --------------------------------------------------------------------------------
@@ -12,31 +11,51 @@
name = "White Terror spider"
desc = "An ominous-looking white spider, its ghostly eyes and vicious-looking fangs are the stuff of nightmares."
spider_role_summary = "Rare, bite-and-run spider that infects hosts with spiderlings"
-
+ ai_target_method = TS_DAMAGE_POISON
icon_state = "terror_white"
icon_living = "terror_white"
icon_dead = "terror_white_dead"
- maxHealth = 100
- health = 100
+ maxHealth = 200
+ health = 200
melee_damage_lower = 5
melee_damage_upper = 15
move_to_delay = 4
spider_tier = TS_TIER_2
loot = list(/obj/item/clothing/accessory/medal)
+ web_infects = 1
+/mob/living/simple_animal/hostile/poison/terror_spider/white/LoseTarget()
+ stop_automated_movement = 0
+ attackstep = 0
+ attackcycles = 0
+ ..()
+
+/mob/living/simple_animal/hostile/poison/terror_spider/white/death(gibbed)
+ if(!hasdied)
+ if(spider_uo71)
+ UnlockBlastDoors("UO71_Bridge")
+ ..()
+
/mob/living/simple_animal/hostile/poison/terror_spider/white/spider_specialattack(mob/living/carbon/human/L, poisonable)
if(!poisonable)
..()
return
var/inject_target = pick("chest","head")
L.attack_animal(src)
- if(L.stunned || L.paralysis || L.can_inject(null,0,inject_target,0))
- if(!IsInfected(L))
+ if(L.stunned || L.paralysis || L.can_inject(null, 0, inject_target, 0))
+ if(!IsTSInfected(L))
visible_message("[src] buries its long fangs deep into the [inject_target] of [L]!")
new /obj/item/organ/internal/body_egg/terror_eggs(L)
+ if(!ckey)
+ LoseTarget()
+ walk_away(src,L,2,1)
+ else if(prob(25))
+ visible_message("[src] pounces on [L]!")
+ L.Weaken(5)
+ L.Stun(5)
-/mob/living/simple_animal/hostile/poison/terror_spider/proc/IsInfected(mob/living/carbon/C) // Terror AI requires this
+/proc/IsTSInfected(mob/living/carbon/C) // Terror AI requires this
if(C.get_int_organ(/obj/item/organ/internal/body_egg))
return 1
return 0
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index 8e655760d11..2c1fb61be2f 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -406,7 +406,7 @@
if(!parrot_perch || parrot_interest.loc != parrot_perch.loc)
held_item = parrot_interest
parrot_interest.loc = src
- visible_message("[src] grabs the [held_item]!", "\blue You grab the [held_item]!", "You hear the sounds of wings flapping furiously.")
+ visible_message("[src] grabs the [held_item]!", "You grab the [held_item]!", "You hear the sounds of wings flapping furiously.")
parrot_interest = null
parrot_state = PARROT_SWOOP | PARROT_RETURN
diff --git a/code/modules/mob/living/simple_animal/posessed_object.dm b/code/modules/mob/living/simple_animal/posessed_object.dm
index 1473bd5990a..0abbdcdbcfd 100644
--- a/code/modules/mob/living/simple_animal/posessed_object.dm
+++ b/code/modules/mob/living/simple_animal/posessed_object.dm
@@ -13,12 +13,11 @@
universal_speak = 1 // Tell the humans spooky things about the afterlife
speak_emote = list("mumbles", "moans", "whispers", "laments", "screeches")
- allow_spin = 0 // No spinning. Spinning breaks our floating animation and broken floating animations make ghosts SUPER ANGRY.
+ allow_spin = 0 // No spinning. Spinning breaks our floating animation.
no_spin_thrown = 1
var/obj/item/possessed_item
-
/mob/living/simple_animal/possessed_object/examine(mob/user)
possessed_item.examine(user)
if(health > (maxHealth / 30))
@@ -47,15 +46,17 @@
/mob/living/simple_animal/possessed_object/death(gibbed)
+ var/mob/dead/observer/ghost = ghostize(1)
..()
if(gibbed) // Leave no trace.
- var/mob/dead/observer/ghost = ghostize(1)
ghost.timeofdeath = world.time
qdel(src)
return
- possessed_item.forceMove(loc) // Put the normal item back once the EVIL SPIRIT has been vanquished from it.
+ if(possessed_item.loc == src)
+ possessed_item.forceMove(loc) // Put the normal item back once the EVIL SPIRIT has been vanquished from it. If it's not already in place
+
qdel(src)
@@ -65,15 +66,23 @@
if(!possessed_item) // If we're a donut and someone's eaten us, for instance.
death(1)
- if(possessed_item.loc != src)
- forceMove(possessed_item.loc)
- possessed_item.forceMove(src)
+ if( possessed_item.loc != src )
+ if ( isturf(possessed_item.loc) ) // If we've, say, placed the possessed item on the table move onto the table ourselves instead and put it back inside of us.
+ forceMove(possessed_item.loc)
+ possessed_item.forceMove(src)
+ else // If we're inside a toolbox or something, we are inside the item rather than the item inside us. This is so people can see the item in the toolbox.
+ forceMove( possessed_item )
if(l_hand) // Incase object interactions put things directly into our hands. (Like cameras, or gun magizines)
drop_l_hand()
if(r_hand)
drop_r_hand()
+/mob/living/simple_animal/possessed_object/Login()
+ ..()
+ to_chat(src, "Your spirit has entered [src] and possessed it. You are able to do most things a humanoid would be able to do with a [src] in their hands. If you want to end your ghostly possession, use the 'ghost' verb, it won't penalize your ability to respawn.")
+
+
/mob/living/simple_animal/possessed_object/New(var/atom/loc as obj)
..()
@@ -89,23 +98,14 @@
qdel(src)
possessed_item = loc
- forceMove(possessed_loc)
+ forceMove( possessed_loc )
possessed_item.forceMove(src) // We'll keep the actual item inside of us until we die.
- zone_sel = new /obj/screen/zone_sel(src) // Create a new zone selection item so the human attacks have something to reference.
+ zone_sel = new /obj/screen/zone_sel(src) // Create a new zone selection item so the human attacks have something to reference. Horrifying and ugly hack, do not look directly at this.
- name = possessed_item.name // Take on all the attributes of the item we've possessed.
- real_name = name
- desc = possessed_item.desc
- icon = possessed_item.icon
- icon_living = possessed_item.icon_state
- icon_state = possessed_item.icon_state
- dir = possessed_item.dir
- color = possessed_item.color
- overlays = possessed_item.overlays
- set_opacity(possessed_item.opacity)
+ update_icon(1)
- visible_message("[src] rises into the air and begins to float!") // Inform those around us that shit's gettin' spooky.
+ visible_message("[src] rises into the air and begins to float!") // Inform those around us that shit's gettin' spooky.
animate_ghostly_presence(src, -1, 20, 1)
@@ -138,17 +138,26 @@
else
..()
- if(possessed_item.loc != src) // If we've, say, placed the possessed item on the table move onto the table ourselves instead and put it back inside of us.
- forceMove(possessed_item.loc)
- possessed_item.forceMove(src)
+ if( possessed_item.loc != src )
+ if ( isturf(possessed_item.loc) ) // If we've, say, placed the possessed item on the table move onto the table ourselves instead and put it back inside of us.
+ forceMove(possessed_item.loc)
+ possessed_item.forceMove(src)
+ else // If we're inside a toolbox or something, we are inside the item rather than the item inside us. This is so people can see the item in the toolbox.
+ forceMove( possessed_item )
- name = possessed_item.name // Update our status
+ update_icon()
+
+/mob/living/simple_animal/possessed_object/proc/update_icon(update_pixel_xy = 0)
+ name = possessed_item.name // Take on all the attributes of the item we've possessed.
real_name = name
desc = possessed_item.desc
icon = possessed_item.icon
icon_living = possessed_item.icon_state
icon_state = possessed_item.icon_state
dir = possessed_item.dir
+ if(update_pixel_xy)
+ pixel_x = possessed_item.pixel_x
+ pixel_y = possessed_item.pixel_y
color = possessed_item.color
overlays = possessed_item.overlays
- opacity = possessed_item.opacity
+ set_opacity(possessed_item.opacity)
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/powers.dm b/code/modules/mob/living/simple_animal/powers.dm
index 9177b61ea2d..9d1d6217415 100644
--- a/code/modules/mob/living/simple_animal/powers.dm
+++ b/code/modules/mob/living/simple_animal/powers.dm
@@ -8,13 +8,13 @@
if(layer != TURF_LAYER+0.2)
layer = TURF_LAYER+0.2
- to_chat(src, text("\green You are now hiding."))
+ to_chat(src, text("You are now hiding."))
for(var/mob/O in oviewers(src, null))
if((O.client && !( O.blinded )))
to_chat(O, text("[] scurries to the ground!", src))
else
layer = MOB_LAYER
- to_chat(src, text("\green You have stopped hiding."))
+ to_chat(src, text("You have stopped hiding."))
for(var/mob/O in oviewers(src, null))
if((O.client && !( O.blinded )))
to_chat(O, text("[] slowly peaks up from the ground...", src))
diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm
index d4d52f63ce5..01ce4964ece 100644
--- a/code/modules/mob/living/simple_animal/shade.dm
+++ b/code/modules/mob/living/simple_animal/shade.dm
@@ -40,12 +40,12 @@
health -= damage
for(var/mob/M in viewers(src, null))
if((M.client && !( M.blinded )))
- M.show_message("\red \b [src] has been attacked with the [O] by [user]. ")
+ M.show_message("[src] has been attacked with the [O] by [user]. ")
else
- to_chat(usr, "\red This weapon is ineffective, it does no damage.")
+ to_chat(usr, "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 the [O]. ")
+ M.show_message("[user] gently taps [src] with the [O]. ")
return
/mob/living/simple_animal/shade/sword
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 9669c90b3ec..7c951cebbc9 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -96,6 +96,7 @@
if(collar)
collar.forceMove(loc)
collar = null
+ master_commander = null
simple_animal_list -= src
return ..()
@@ -303,7 +304,7 @@
/mob/living/simple_animal/proc/attacked_by(obj/item/I, mob/living/user) // Handled in _onclick/click.dm
return
-
+
/mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
if(!Proj)
return
@@ -662,15 +663,15 @@
. = ..()
/mob/living/simple_animal/can_equip(obj/item/I, slot, disable_warning = 0)
- // . = ..() // Do not call parent. We do not want animals using their hand slots.
- switch(slot)
- if(slot_collar)
- if(collar)
- return 0
- if(!can_collar)
- return 0
- if(!istype(I, /obj/item/clothing/accessory/petcollar))
- return 0
+ // . = ..() // Do not call parent. We do not want animals using their hand slots.
+ switch(slot)
+ if(slot_collar)
+ if(collar)
+ return 0
+ if(!can_collar)
+ return 0
+ if(!istype(I, /obj/item/clothing/accessory/petcollar))
+ return 0
return 1
/mob/living/simple_animal/equip_to_slot(obj/item/W, slot)
@@ -692,13 +693,13 @@
name = collar.tagname
real_name = collar.tagname
regenerate_icons()
-
-/mob/living/simple_animal/unEquip(obj/item/I, force)
- . = ..()
- if(!. || !I)
- return
-
- if(I == collar)
+
+/mob/living/simple_animal/unEquip(obj/item/I, force)
+ . = ..()
+ if(!. || !I)
+ return
+
+ if(I == collar)
collar = null
regenerate_icons()
@@ -712,16 +713,17 @@
/mob/living/simple_animal/proc/sentience_act() //Called when a simple animal gains sentience via gold slime potion
return
-/mob/living/simple_animal/update_sight()
+/mob/living/simple_animal/update_sight(reset_sight = FALSE)
if(!client)
return
if(stat == DEAD)
grant_death_vision()
return
- see_invisible = initial(see_invisible)
- see_in_dark = initial(see_in_dark)
- sight = initial(sight)
+ if(reset_sight)
+ see_invisible = initial(see_invisible)
+ see_in_dark = initial(see_in_dark)
+ sight = initial(sight)
if(client.eye != src)
var/atom/A = client.eye
diff --git a/code/modules/mob/living/simple_animal/tribbles.dm b/code/modules/mob/living/simple_animal/tribbles.dm
index 6a18da90aaa..78b28abf9f8 100644
--- a/code/modules/mob/living/simple_animal/tribbles.dm
+++ b/code/modules/mob/living/simple_animal/tribbles.dm
@@ -195,10 +195,10 @@ var/global/totaltribbles = 0 //global variable so it updates for all tribbles,
if(src.destroyed)
return
else
- to_chat(usr, text("\blue You kick the lab cage."))
+ to_chat(usr, text("You kick the lab cage."))
for(var/mob/O in oviewers())
if((O.client && !( O.blinded )))
- to_chat(O, text("\red [] kicks the lab cage.", usr))
+ to_chat(O, text("[] kicks the lab cage.", usr))
src.health -= 2
healthcheck()
return
diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm
index 402f94e837e..30fe030bdcb 100644
--- a/code/modules/mob/living/status_procs.dm
+++ b/code/modules/mob/living/status_procs.dm
@@ -140,12 +140,14 @@
/mob/living/proc/StartResting(updating = 1)
var/val_change = !resting
resting = TRUE
+
if(updating && val_change)
update_canmove()
/mob/living/proc/StopResting(updating = 1)
var/val_change = !!resting
resting = FALSE
+
if(updating && val_change)
update_canmove()
@@ -352,19 +354,19 @@
// SLEEPING
-/mob/living/Sleeping(amount, updating = 1)
- SetSleeping(max(sleeping, amount), updating)
+/mob/living/Sleeping(amount, updating = 1, no_alert = FALSE)
+ SetSleeping(max(sleeping, amount), updating, no_alert)
-/mob/living/SetSleeping(amount, updating = 1)
+/mob/living/SetSleeping(amount, updating = 1, no_alert = FALSE)
sleeping = max(amount, 0)
- update_sleeping_effects()
+ update_sleeping_effects(no_alert)
if(updating)
update_stat()
update_canmove()
-/mob/living/AdjustSleeping(amount, bound_lower = 0, bound_upper = INFINITY, updating = 1)
+/mob/living/AdjustSleeping(amount, bound_lower = 0, bound_upper = INFINITY, updating = 1, no_alert = FALSE)
var/new_value = directional_bounded_sum(sleeping, amount, bound_lower, bound_upper)
- SetSleeping(new_value, updating)
+ SetSleeping(new_value, updating, no_alert)
// SLOWED
diff --git a/code/modules/mob/living/update_status.dm b/code/modules/mob/living/update_status.dm
index 59b7077e79e..257a4bc87c1 100644
--- a/code/modules/mob/living/update_status.dm
+++ b/code/modules/mob/living/update_status.dm
@@ -30,9 +30,10 @@
else
clear_fullscreen("nearsighted")
-/mob/living/update_sleeping_effects()
+/mob/living/update_sleeping_effects(no_alert = FALSE)
if(sleeping)
- throw_alert("asleep", /obj/screen/alert/asleep)
+ if(!no_alert)
+ throw_alert("asleep", /obj/screen/alert/asleep)
else
clear_alert("asleep")
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 3f3792fd1b7..40835475e2c 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -47,14 +47,14 @@
var/datum/gas_mixture/environment = loc.return_air()
- var/t = "\blue Coordinates: [x],[y] \n"
- t+= "\red Temperature: [environment.temperature] \n"
- t+= "\blue Nitrogen: [environment.nitrogen] \n"
- t+= "\blue Oxygen: [environment.oxygen] \n"
- t+= "\blue Plasma : [environment.toxins] \n"
- t+= "\blue Carbon Dioxide: [environment.carbon_dioxide] \n"
+ var/t = "Coordinates: [x],[y] \n"
+ t+= "Temperature: [environment.temperature] \n"
+ t+= "Nitrogen: [environment.nitrogen] \n"
+ t+= "Oxygen: [environment.oxygen] \n"
+ t+= "Plasma : [environment.toxins] \n"
+ t+= "Carbon Dioxide: [environment.carbon_dioxide] \n"
for(var/datum/gas/trace_gas in environment.trace_gases)
- to_chat(usr, "\blue [trace_gas.type]: [trace_gas.moles] \n")
+ to_chat(usr, "[trace_gas.type]: [trace_gas.moles] \n")
usr.show_message(t, 1)
@@ -171,9 +171,8 @@
if(istype(W))
if(istype(W, /obj/item/clothing))
var/obj/item/clothing/C = W
- if(C.rig_restrict_helmet)
- to_chat(src, "\red You must fasten the helmet to a hardsuit first. (Target the head and use on a hardsuit)")// Stop eva helms equipping.
-
+ if(C.hardsuit_restrict_helmet)
+ to_chat(src, "You must fasten the helmet to a hardsuit first. (Target the head and use on a hardsuit)")// Stop eva helms equipping.
else
equip_to_slot_if_possible(C, slot)
else
@@ -208,7 +207,7 @@
qdel(W)
else
if(!disable_warning)
- to_chat(src, "\red You are unable to equip that.")//Only print if del_on_fail is false
+ to_chat(src, "You are unable to equip that.")//Only print if del_on_fail is false
return 0
@@ -231,22 +230,18 @@
//Mob can equip. Equip it.
equip_to_slot_or_del(W, slot)
else
- //Mob can't equip it. Put it in a bag B.
- // Do I have a backpack?
- var/obj/item/weapon/storage/B
- if(istype(back,/obj/item/weapon/storage))
- //Mob is wearing backpack
- B = back
- else
- //not wearing backpack. Check if player holding plastic bag
- B=is_in_hands(/obj/item/weapon/storage/bag/plasticbag)
- if(!B) //If not holding plastic bag, give plastic bag
- B=new /obj/item/weapon/storage/bag/plasticbag(null) // Null in case of failed equip.
- if(!put_in_hands(B))
- return // Bag could not be placed in players hands. I don't know what to do here...
- //Now, B represents a container we can insert W into.
- B.handle_item_insertion(W,1)
- return B
+ //Mob can't equip it. Put it their backpack or toss it on the floor
+ if(istype(back, /obj/item/weapon/storage))
+ var/obj/item/weapon/storage/S = back
+ //Now, B represents a container we can insert W into.
+ S.handle_item_insertion(W,1)
+ return S
+
+ var/turf/T = get_turf(src)
+ if(istype(T))
+ W.forceMove(T)
+ return T
+
//The list of slots by priority. equip_to_appropriate_slot() uses this list. Doesn't matter if a mob type doesn't have a slot.
var/list/slot_equipment_priority = list( \
@@ -352,7 +347,7 @@ var/list/slot_equipment_priority = list( \
if(slot_belt)
if(!H.w_uniform)
if(!disable_warning)
- to_chat(H, "\red You need a jumpsuit before you can attach this [name].")
+ to_chat(H, "You need a jumpsuit before you can attach this [name].")
return 0
if( !(slot_flags & SLOT_BELT) )
return 0
@@ -412,7 +407,7 @@ var/list/slot_equipment_priority = list( \
if(slot_wear_id)
if(!H.w_uniform)
if(!disable_warning)
- to_chat(H, "\red You need a jumpsuit before you can attach this [name].")
+ to_chat(H, "You need a jumpsuit before you can attach this [name].")
return 0
if( !(slot_flags & SLOT_ID) )
return 0
@@ -427,7 +422,7 @@ var/list/slot_equipment_priority = list( \
return 0
if(!H.w_uniform)
if(!disable_warning)
- to_chat(H, "\red You need a jumpsuit before you can attach this [name].")
+ to_chat(H, "You need a jumpsuit before you can attach this [name].")
return 0
if(slot_flags & SLOT_DENYPOCKET)
return
@@ -438,7 +433,7 @@ var/list/slot_equipment_priority = list( \
return 0
if(!H.w_uniform)
if(!disable_warning)
- to_chat(H, "\red You need a jumpsuit before you can attach this [name].")
+ to_chat(H, "You need a jumpsuit before you can attach this [name].")
return 0
if(slot_flags & SLOT_DENYPOCKET)
return 0
@@ -448,7 +443,7 @@ var/list/slot_equipment_priority = list( \
if(slot_s_store)
if(!H.wear_suit)
if(!disable_warning)
- to_chat(H, "\red You need a suit before you can attach this [name].")
+ to_chat(H, "You need a suit before you can attach this [name].")
return 0
if(!H.wear_suit.allowed)
if(!disable_warning)
@@ -752,7 +747,7 @@ var/list/slot_equipment_priority = list( \
if(client.holder && (client.holder.rights & R_ADMIN))
is_admin = 1
else if(stat != DEAD || istype(src, /mob/new_player))
- to_chat(usr, "\blue You must be observing to use this!")
+ to_chat(usr, "You must be observing to use this!")
return
if(is_admin && stat == DEAD)
@@ -1061,7 +1056,7 @@ var/list/slot_equipment_priority = list( \
visible_implants += O
return visible_implants
-mob/proc/yank_out_object()
+/mob/proc/yank_out_object()
set category = "Object"
set name = "Yank out object"
set desc = "Remove an embedded item at the cost of bleeding and pain."
@@ -1098,8 +1093,10 @@ mob/proc/yank_out_object()
var/obj/item/weapon/selection = input("What do you want to yank out?", "Embedded objects") in valid_objects
if(self)
+ visible_message("[usr] appears to be trying to extract an object from their body.")
to_chat(src, "You attempt to get a good grip on [selection] in your body.")
else
+ visible_message("[usr] attempts to get a good grip on [selection] in [S]'s body.")
to_chat(U, "You attempt to get a good grip on [selection] in [S]'s body.")
if(!do_after(U, 80, target = S))
diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm
index 446ec797a76..e52854621bd 100644
--- a/code/modules/mob/mob_grab.dm
+++ b/code/modules/mob/mob_grab.dm
@@ -347,9 +347,9 @@
if(state < GRAB_NECK)
to_chat(assailant, "You require a better grab to do this.")
return
- if((affected.head && affected.head.flags & HEADCOVERSEYES) || \
- (affected.wear_mask && affected.wear_mask.flags & MASKCOVERSEYES) || \
- (affected.glasses && affected.glasses.flags & GLASSESCOVERSEYES))
+ if((affected.head && affected.head.flags_cover & HEADCOVERSEYES) || \
+ (affected.wear_mask && affected.wear_mask.flags_cover & MASKCOVERSEYES) || \
+ (affected.glasses && affected.glasses.flags_cover & GLASSESCOVERSEYES))
to_chat(assailant, "You're going to need to remove the eye covering first.")
return
if(!affected.internal_organs_by_name["eyes"])
@@ -364,7 +364,7 @@
eyes.damage += rand(3,4)
if(eyes.damage >= eyes.min_broken_damage)
if(M.stat != 2)
- to_chat(M, "\red You go blind!")*///This is a demonstration of adding a new damaging type based on intent as well as hitzone.
+ to_chat(M, "You go blind!")*///This is a demonstration of adding a new damaging type based on intent as well as hitzone.
//This specific example would allow you to squish people's eyes with a GRAB_NECK.
@@ -444,8 +444,7 @@
if(assailant.client)
assailant.client.screen -= hud
assailant = null
- qdel(hud)
- hud = null
+ QDEL_NULL(hud)
return ..()
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 2e83e9b9a95..69bba669de0 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -41,8 +41,8 @@
else if(eyes) //If they're not, check to see if their eyes got one of them there colour matrices. Will be null if eyes are robotic/the mob isn't colourblind and they have no default colour matrix.
return eyes.get_colourmatrix()
-/proc/isloyal(A) //Checks to see if the person contains a mindshield implant, then checks that the implant is actually inside of them
- for(var/obj/item/weapon/implant/loyalty/L in A)
+/proc/ismindshielded(A) //Checks to see if the person contains a mindshield implant, then checks that the implant is actually inside of them
+ for(var/obj/item/weapon/implant/mindshield/L in A)
if(L && L.implanted)
return 1
return 0
@@ -380,9 +380,16 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HARM)
set name = "Rest"
set category = "IC"
- resting = !resting
- update_canmove()
- to_chat(src, "You are now [resting ? "resting" : "getting up"].")
+ if(world.time < client.move_delay)
+ return
+
+ if(!resting)
+ client.move_delay = world.time + 20
+ to_chat(src, "You are now resting.")
+ StartResting()
+ else if(resting)
+ to_chat(src, "You are now getting up.")
+ StopResting()
/proc/is_blind(A)
if(iscarbon(A))
@@ -453,7 +460,7 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HARM)
lname = "[lname] "
to_chat(M, "[lname][follow][message]")
-/proc/notify_ghosts(message, ghost_sound = null, enter_link = null, atom/source = null, image/alert_overlay = null, flashwindow = TRUE, var/action = NOTIFY_JUMP) //Easy notification of ghosts.
+/proc/notify_ghosts(message, ghost_sound = null, enter_link = null, title = null, atom/source = null, image/alert_overlay = null, flashwindow = TRUE, var/action = NOTIFY_JUMP) //Easy notification of ghosts.
for(var/mob/dead/observer/O in player_list)
if(O.client)
to_chat(O, "[message][(enter_link) ? " [enter_link]" : ""]")
@@ -466,6 +473,8 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HARM)
if(A)
if(O.client.prefs && O.client.prefs.UI_style)
A.icon = ui_style2icon(O.client.prefs.UI_style)
+ if(title)
+ A.name = title
A.desc = message
A.action = action
A.target = source
@@ -619,4 +628,4 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HARM)
return !!(client.prefs.toggles & toggleflag)
-#define isterrorspider(A) (istype((A), /mob/living/simple_animal/hostile/poison/terror_spider))
\ No newline at end of file
+#define isterrorspider(A) (istype((A), /mob/living/simple_animal/hostile/poison/terror_spider))
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 8b8fafd32b7..cef870811db 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -50,12 +50,12 @@
var/mob/living/silicon/robot/R = usr
var/module = R.get_selected_module()
if(!module)
- to_chat(usr, "\red You have no module selected.")
+ to_chat(usr, "You have no module selected.")
return
R.cycle_modules()
R.uneq_numbered(module)
else
- to_chat(usr, "\red This mob type cannot throw items.")
+ to_chat(usr, "This mob type cannot throw items.")
return
@@ -63,17 +63,17 @@
if(iscarbon(usr))
var/mob/living/carbon/C = usr
if(!C.get_active_hand())
- to_chat(usr, "\red You have nothing to drop in your hand.")
+ to_chat(usr, "You have nothing to drop in your hand.")
return
drop_item()
else if(isrobot(usr))
var/mob/living/silicon/robot/R = usr
if(!R.get_selected_module())
- to_chat(usr, "\red You have no module selected.")
+ to_chat(usr, "You have no module selected.")
return
R.deselect_module(R.get_selected_module())
else
- to_chat(usr, "\red This mob type cannot drop items.")
+ to_chat(usr, "This mob type cannot drop items.")
return
//This gets called when you press the delete button.
@@ -81,7 +81,7 @@
set hidden = 1
if(!usr.pulling)
- to_chat(usr, "\blue You are not pulling anything.")
+ to_chat(usr, "You are not pulling anything.")
return
usr.stop_pulling()
@@ -199,6 +199,10 @@
var/atom/O = mob.loc
return O.relaymove(mob, direct)
+ if(istype(mob.get_active_hand(), /obj/item))
+ var/obj/item/I = mob.get_active_hand()
+ I.moved(mob, n, direct)
+
if(!mob.Process_Spacemove(direct))
return 0
@@ -208,13 +212,13 @@
for(var/mob/M in range(mob, 1))
if(M.pulling == mob)
if(!M.restrained() && M.stat == 0 && M.canmove && mob.Adjacent(M))
- to_chat(src, "\blue You're restrained! You can't move!")
+ to_chat(src, "You're restrained! You can't move!")
return 0
else
M.stop_pulling()
if(mob.pinned.len)
- to_chat(src, "\blue You're pinned to a wall by [mob.pinned[1]]!")
+ to_chat(src, "You're pinned to a wall by [mob.pinned[1]]!")
return 0
var/turf/T = mob.loc
diff --git a/code/modules/mob/mob_transformation_simple.dm b/code/modules/mob/mob_transformation_simple.dm
index 856879acf38..a94be6a54c1 100644
--- a/code/modules/mob/mob_transformation_simple.dm
+++ b/code/modules/mob/mob_transformation_simple.dm
@@ -5,7 +5,7 @@
/mob/proc/change_mob_type(var/new_type = null, var/turf/location = null, var/new_name = null as text, var/delete_old_mob = 0 as num, var/forcekey = 0)
if(istype(src,/mob/new_player))
- to_chat(usr, "\red cannot convert players who have not entered yet.")
+ to_chat(usr, "cannot convert players who have not entered yet.")
return
if(!new_type)
@@ -19,7 +19,7 @@
return
if( new_type == /mob/new_player )
- to_chat(usr, "\red cannot convert into a new_player mob type.")
+ to_chat(usr, "cannot convert into a new_player mob type.")
return
var/mob/M
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 006bf2c344f..58c5ee4104d 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -131,7 +131,7 @@
observer.started_as_observer = 1
close_spawn_windows()
var/obj/O = locate("landmark*Observer-Start")
- to_chat(src, "\blue Now teleporting.")
+ to_chat(src, "Now teleporting.")
observer.loc = O.loc
observer.timeofdeath = world.time // Set the time of death so that the respawn timer works correctly.
client.prefs.update_preview_icon(1)
@@ -151,7 +151,7 @@
if(href_list["late_join"])
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
- to_chat(usr, "\red The round is either not ready, or has already finished...")
+ to_chat(usr, "The round is either not ready, or has already finished...")
return
if(client.prefs.species in whitelisted_species)
@@ -168,7 +168,7 @@
if(href_list["SelectedJob"])
if(!enter_allowed)
- to_chat(usr, "\blue There is an administrative lock on entering the game!")
+ to_chat(usr, "There is an administrative lock on entering the game!")
return
if(client.prefs.randomslot)
@@ -230,10 +230,10 @@
if(src != usr)
return 0
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
- to_chat(usr, "\red The round is either not ready, or has already finished...")
+ to_chat(usr, "The round is either not ready, or has already finished...")
return 0
if(!enter_allowed)
- to_chat(usr, "\blue There is an administrative lock on entering the game!")
+ to_chat(usr, "There is an administrative lock on entering the game!")
return 0
if(!IsJobAvailable(rank))
to_chat(src, alert("[rank] is not available. Please try another."))
diff --git a/code/modules/mob/new_player/poll.dm b/code/modules/mob/new_player/poll.dm
index a603369c5b5..ecd690c871d 100644
--- a/code/modules/mob/new_player/poll.dm
+++ b/code/modules/mob/new_player/poll.dm
@@ -495,7 +495,7 @@
break
if(!validpoll)
- to_chat(usr, "\red Poll is not valid.")
+ to_chat(usr, "Poll is not valid.")
return
var/DBQuery/select_query2 = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_option")] WHERE id = [optionid] AND pollid = [pollid]")
@@ -508,7 +508,7 @@
break
if(!validoption)
- to_chat(usr, "\red Poll option is not valid.")
+ to_chat(usr, "Poll option is not valid.")
return
var/alreadyvoted = 0
@@ -522,11 +522,11 @@
break
if(!multichoice && alreadyvoted)
- to_chat(usr, "\red You already voted in this poll.")
+ to_chat(usr, "You already voted in this poll.")
return
if(multichoice && (alreadyvoted >= multiplechoiceoptions))
- to_chat(usr, "\red You already have more than [multiplechoiceoptions] logged votes on this poll. Enough is enough. Contact the database admin if this is an error.")
+ to_chat(usr, "You already have more than [multiplechoiceoptions] logged votes on this poll. Enough is enough. Contact the database admin if this is an error.")
return
var/adminrank = "Player"
@@ -537,7 +537,7 @@
var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (id ,datetime ,pollid ,optionid ,ckey ,ip ,adminrank) VALUES (null, Now(), [pollid], [optionid], '[ckey]', '[usr.client.address]', '[adminrank]')")
insert_query.Execute()
- to_chat(usr, "\blue Vote successful.")
+ to_chat(usr, "Vote successful.")
usr << browse(null,"window=playerpoll")
@@ -562,7 +562,7 @@
break
if(!validpoll)
- to_chat(usr, "\red Poll is not valid.")
+ to_chat(usr, "Poll is not valid.")
return
var/alreadyvoted = 0
@@ -575,7 +575,7 @@
break
if(alreadyvoted)
- to_chat(usr, "\red You already sent your feedback for this poll.")
+ to_chat(usr, "You already sent your feedback for this poll.")
return
var/adminrank = "Player"
@@ -595,7 +595,7 @@
var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO [format_table_name("poll_textreply")] (id ,datetime ,pollid ,ckey ,ip ,replytext ,adminrank) VALUES (null, Now(), [pollid], '[ckey]', '[usr.client.address]', '[replytext]', '[adminrank]')")
insert_query.Execute()
- to_chat(usr, "\blue Feedback logging successful.")
+ to_chat(usr, "Feedback logging successful.")
usr << browse(null,"window=playerpoll")
@@ -620,7 +620,7 @@
break
if(!validpoll)
- to_chat(usr, "\red Poll is not valid.")
+ to_chat(usr, "Poll is not valid.")
return
var/DBQuery/select_query2 = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_option")] WHERE id = [optionid] AND pollid = [pollid]")
@@ -633,7 +633,7 @@
break
if(!validoption)
- to_chat(usr, "\red Poll option is not valid.")
+ to_chat(usr, "Poll option is not valid.")
return
var/alreadyvoted = 0
@@ -646,7 +646,7 @@
break
if(alreadyvoted)
- to_chat(usr, "\red You already voted in this poll.")
+ to_chat(usr, "You already voted in this poll.")
return
var/adminrank = "Player"
@@ -657,5 +657,5 @@
var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (id ,datetime ,pollid ,optionid ,ckey ,ip ,adminrank, rating) VALUES (null, Now(), [pollid], [optionid], '[ckey]', '[usr.client.address]', '[adminrank]', [(isnull(rating)) ? "null" : rating])")
insert_query.Execute()
- to_chat(usr, "\blue Vote successful.")
+ to_chat(usr, "Vote successful.")
usr << browse(null,"window=playerpoll")
\ No newline at end of file
diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm
index 15473caf5f2..e8899ef6123 100644
--- a/code/modules/mob/new_player/preferences_setup.dm
+++ b/code/modules/mob/new_player/preferences_setup.dm
@@ -470,7 +470,7 @@
if(CHEF)
clothes_s = new /icon(uniform_dmi, "chef_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY)
- clothes_s.Blend(new /icon('icons/mob/head.dmi', "chefhat"), ICON_OVERLAY)
+ clothes_s.Blend(new /icon('icons/mob/head.dmi', "chef"), ICON_OVERLAY)
if(prob(1))
clothes_s.Blend(new /icon('icons/mob/suit.dmi', "apronchef"), ICON_OVERLAY)
switch(backbag)
diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm
index a29a2e9480a..ea80c4def16 100644
--- a/code/modules/mob/new_player/sprite_accessories.dm
+++ b/code/modules/mob/new_player/sprite_accessories.dm
@@ -431,106 +431,87 @@
/datum/sprite_accessory/hair/ipc
species_allowed = list("Machine")
glasses_over = 1
+ models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.", "Shellguard Munitions Monitor Series")
/datum/sprite_accessory/hair/ipc/ipc_screen_pink
name = "Pink IPC Screen"
icon_state = "ipc_pink"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/ipc_screen_red
name = "Red IPC Screen"
icon_state = "ipc_red"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/ipc_screen_green
name = "Green IPC Screen"
icon_state = "ipc_green"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/ipc_screen_blue
name = "Blue IPC Screen"
icon_state = "ipc_blue"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/ipc_screen_breakout
name = "Breakout IPC Screen"
icon_state = "ipc_breakout"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/ipc_screen_eight
name = "Eight IPC Screen"
icon_state = "ipc_eight"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/ipc_screen_rainbow
name = "Rainbow IPC Screen"
icon_state = "ipc_rainbow"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/ipc_screen_goggles
name = "Goggles IPC Screen"
icon_state = "ipc_goggles"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/ipc_screen_heart
name = "Heart IPC Screen"
icon_state = "ipc_heart"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/ipc_screen_monoeye
name = "Monoeye IPC Screen"
icon_state = "ipc_monoeye"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/ipc_screen_nature
name = "Nature IPC Screen"
icon_state = "ipc_nature"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/ipc_screen_orange
name = "Orange IPC Screen"
icon_state = "ipc_orange"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/ipc_screen_purple
name = "Purple IPC Screen"
icon_state = "ipc_purple"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/ipc_screen_shower
name = "Shower IPC Screen"
icon_state = "ipc_shower"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/ipc_screen_static
name = "Static IPC Screen"
icon_state = "ipc_static"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/ipc_screen_yellow
name = "Yellow IPC Screen"
icon_state = "ipc_yellow"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/ipc_screen_scrolling
name = "Scanline IPC Screen"
icon_state = "ipc_scroll"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/ipc_screen_console
name = "Console IPC Screen"
icon_state = "ipc_console"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/ipc_screen_rgb
name = "RGB IPC Screen"
icon_state = "ipc_rgb"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/ipc_screen_glider
name = "Glider IPC Screen"
icon_state = "ipc_gol_glider"
- models_allowed = list("Bishop Cybernetics mtr.", "Hesphiastos Industries mtr.", "Morpheus Cyberkinetics", "Ward-Takahashi mtr.", "Xion Manufacturing Group mtr.")
/datum/sprite_accessory/hair/ipc/hesphiastos_alt_off
name = "Dark Hesphiastos Screen"
@@ -578,10 +559,67 @@
/datum/sprite_accessory/hair/unathi
species_allowed = list("Unathi")
glasses_over = 1
+ icon = 'icons/mob/body_accessory.dmi'
-/datum/sprite_accessory/hair/unathi/una_horns
- name = "Unathi Horns"
- icon_state = "soghun_horns"
+/datum/sprite_accessory/hair/unathi/una_side_frills
+ icon = 'icons/mob/human_face.dmi'
+ name = "Unathi Side Frills"
+ icon_state = "unathi_sidefrills"
+ secondary_theme = "webbing"
+
+/datum/sprite_accessory/hair/unathi/una_frills_dorsal
+ icon = 'icons/mob/human_face.dmi'
+ name = "Dorsal Frills"
+ icon_state = "unathi_dorsalfrills"
+ secondary_theme = "webbing"
+
+/datum/sprite_accessory/hair/unathi/simple
+ name = "Simple Horns"
+ icon_state = "horns_simple"
+
+/datum/sprite_accessory/hair/unathi/short
+ name = "Short Horns"
+ icon_state = "horns_short"
+
+/datum/sprite_accessory/hairy/unathi/curled
+ name = "Curled Horns"
+ icon_state = "horns_curled"
+
+/datum/sprite_accessory/hair/unathi/ram
+ name = "Ram Horns"
+ icon_state = "horns_ram"
+
+/datum/sprite_accessory/hair/unathi/double
+ name = "Double Horns"
+ icon_state = "horns_drac"
+
+/datum/sprite_accessory/hair/unathi/lower
+ name = "Lower Horns"
+ icon_state = "horns_lower"
+
+/datum/sprite_accessory/hair/unathi/big
+ name = "Big"
+ icon_state = "horns_big"
+
+/datum/sprite_accessory/hair/unathi/ram2
+ name = "Ram alt."
+ icon_state = "horns_ram2"
+
+/datum/sprite_accessory/hair/unathi/small
+ name = "Small"
+ icon_state = "horns_small"
+
+/datum/sprite_accessory/hair/unathi/chin
+ name = "Chin"
+ icon_state = "horns_chin"
+
+/datum/sprite_accessory/hair/unathi/adorns
+ name = "Adorns"
+ icon_state = "horns_adorns"
+
+/datum/sprite_accessory/hair/unathi/spikes
+ name = "Spikes"
+ icon_state = "horns_spikes"
/datum/sprite_accessory/hair/skrell
species_allowed = list("Skrell")
@@ -766,6 +804,20 @@
icon_state = "braided"
secondary_theme = "beads"
+/datum/sprite_accessory/hair/vulpkanin/vulp_hair_punkbraided
+ name = "Punk Braided"
+ icon_state = "punkbraided"
+ secondary_theme = "flare"
+
+/datum/sprite_accessory/hair/vulpkanin/vulp_hair_short2
+ name = "Short Alt."
+ icon_state = "short2"
+ glasses_over = 1
+
+/datum/sprite_accessory/hair/vulpkanin/vulp_hair_rough
+ name = "Rough-Cropped Mane"
+ icon_state = "rough"
+
/datum/sprite_accessory/hair/vox
species_allowed = list("Vox")
glasses_over = 1
@@ -1003,6 +1055,10 @@
name = "Tajara Goatee"
icon_state = "facial_goatee"
+/datum/sprite_accessory/facial_hair/tajara/taj_goatee_faded
+ name = "Tajara Faded Goatee"
+ icon_state = "facial_goatee_faded"
+
/datum/sprite_accessory/facial_hair/tajara/taj_smallstache
name = "Tajara Smallstache"
icon_state = "facial_smallstache"
@@ -1067,6 +1123,15 @@
name = "Swift"
icon_state = "vulp_facial_swift"
+/datum/sprite_accessory/facial_hair/vulpkanin/vulp_elder
+ name = "Elder"
+ icon_state = "vulp_facial_elder"
+ secondary_theme = "chin"
+
+/datum/sprite_accessory/facial_hair/vulpkanin/vulp_slash
+ name = "Slash"
+ icon_state = "vulp_facial_slash"
+
/datum/sprite_accessory/facial_hair/unathi
species_allowed = list("Unathi")
gender = NEUTER
@@ -1074,39 +1139,74 @@
/datum/sprite_accessory/facial_hair/unathi/una_spines_long
name = "Long Spines"
- icon_state = "soghun_longspines"
+ icon_state = "unathi_longspines"
/datum/sprite_accessory/facial_hair/unathi/una_spines_short
name = "Short Spines"
- icon_state = "soghun_shortspines"
+ icon_state = "unathi_shortspines"
+
+/datum/sprite_accessory/facial_hair/unathi/una_frills_aquaspine
+ name = "Spiny Aquatic Frills"
+ icon_state = "unathi_dracfrills"
/datum/sprite_accessory/facial_hair/unathi/una_frills_aquatic
name = "Aquatic Frills"
- icon_state = "soghun_aquaticfrills"
+ icon_state = "unathi_aquaticfrills"
/datum/sprite_accessory/facial_hair/unathi/una_frills_long
name = "Long Frills"
- icon_state = "soghun_longfrills"
+ icon_state = "unathi_longfrills"
/datum/sprite_accessory/facial_hair/unathi/una_frills_short
name = "Short Frills"
- icon_state = "soghun_shortfrills"
+ icon_state = "unathi_shortfrills"
+
+/datum/sprite_accessory/facial_hair/unathi/una_frills_webbed_aquaspine
+ name = "Spiny Aquatic Webbed Frills"
+ icon_state = "unathi_dracfrills"
+ secondary_theme = "webbing"
/datum/sprite_accessory/facial_hair/unathi/una_frills_webbed_aquatic
name = "Aquatic Webbed Frills"
- icon_state = "soghun_aquaticfrills"
+ icon_state = "unathi_aquaticfrills"
secondary_theme = "webbing"
/datum/sprite_accessory/facial_hair/unathi/una_frills_webbed_long
name = "Long Webbed Frills"
- icon_state = "soghun_longfrills"
+ icon_state = "unathi_longfrills"
secondary_theme = "webbing"
/datum/sprite_accessory/facial_hair/unathi/una_frills_webbed_short
name = "Short Webbed Frills"
- icon_state = "soghun_shortfrills"
+ icon_state = "unathi_shortfrills"
secondary_theme = "webbing"
+/datum/sprite_accessory/facial_hair/unathi/una_side_frills
+ name = "Side Frills"
+ icon_state = "unathi_sidefrills"
+ secondary_theme = "webbing"
+
+/datum/sprite_accessory/facial_hair/unathi/una_frills_dorsal
+ over_hair = null
+ name = "Dorsal Frills"
+ icon_state = "unathi_dorsalfrills"
+ secondary_theme = "webbing"
+
+/datum/sprite_accessory/facial_hair/unathi/una_chin_horns
+ name = "Chin Horns"
+ icon = 'icons/mob/body_accessory.dmi'
+ icon_state = "horns_chin"
+
+/datum/sprite_accessory/facial_hair/unathi/una_horn_adorns
+ name = "Horn Adorns"
+ icon = 'icons/mob/body_accessory.dmi'
+ icon_state = "horns_adorns"
+
+/datum/sprite_accessory/facial_hair/unathi/una_spikes
+ name = "Spikes"
+ icon = 'icons/mob/body_accessory.dmi'
+ icon_state = "horns_spikes"
+
//skin styles - WIP
//going to have to re-integrate this with surgery
//let the icon_state hold an icon preview for now
@@ -1151,13 +1251,13 @@
///////////////////////////
/datum/sprite_accessory/underwear
icon = 'icons/mob/underwear.dmi'
- species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skeleton", "Drask")
+ species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask")
gender = NEUTER
/datum/sprite_accessory/underwear/nude
name = "Nude"
icon_state = null
- species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skeleton", "Drask", "Vox")
+ species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask", "Vox")
/datum/sprite_accessory/underwear/male
gender = MALE
@@ -1277,13 +1377,13 @@
////////////////////////////
/datum/sprite_accessory/undershirt
icon = 'icons/mob/underwear.dmi'
- species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skeleton", "Drask")
+ species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask")
gender = NEUTER
/datum/sprite_accessory/undershirt/nude
name = "Nude"
icon_state = null
- species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skeleton", "Drask", "Vox")
+ species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask", "Vox")
//plain color shirts
/datum/sprite_accessory/undershirt/shirt_white
@@ -1513,13 +1613,13 @@
///////////////////////
/datum/sprite_accessory/socks
icon = 'icons/mob/underwear.dmi'
- species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skeleton", "Drask")
+ species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask")
gender = NEUTER
/datum/sprite_accessory/socks/nude
name = "Nude"
icon_state = null
- species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skeleton", "Drask", "Vox")
+ species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask", "Vox")
/datum/sprite_accessory/socks/white_norm
name = "Normal White"
@@ -1645,7 +1745,7 @@
/datum/sprite_accessory/head_accessory/none
name = "None"
- species_allowed = list("Human", "Unathi", "Diona", "Grey", "Machine", "Tajaran", "Vulpkanin", "Slime People", "Skeleton", "Vox")
+ species_allowed = list("Human", "Unathi", "Diona", "Grey", "Kidan", "Machine", "Tajaran", "Vulpkanin", "Skrell", "Slime People", "Skeleton", "Vox")
icon_state = "accessory_none"
/datum/sprite_accessory/head_accessory/unathi
@@ -1668,6 +1768,38 @@
name = "Ram"
icon_state = "horns_ram"
+/datum/sprite_accessory/head_accessory/unathi/double
+ name = "Double"
+ icon_state = "horns_drac"
+
+/datum/sprite_accessory/head_accessory/unathi/lower
+ name = "Lower"
+ icon_state = "horns_lower"
+
+/datum/sprite_accessory/head_accessory/unathi/big
+ name = "Big"
+ icon_state = "horns_big"
+
+/datum/sprite_accessory/head_accessory/unathi/ram2
+ name = "Ram alt."
+ icon_state = "horns_ram2"
+
+/datum/sprite_accessory/head_accessory/unathi/small
+ name = "Small"
+ icon_state = "horns_small"
+
+/datum/sprite_accessory/head_accessory/unathi/chin
+ name = "Chin"
+ icon_state = "horns_chin"
+
+/datum/sprite_accessory/head_accessory/unathi/adorns
+ name = "Adorns"
+ icon_state = "horns_adorns"
+
+/datum/sprite_accessory/head_accessory/unathi/spikes
+ name = "Spikes"
+ icon_state = "horns_spikes"
+
/datum/sprite_accessory/head_accessory/tajara
species_allowed = list("Tajaran")
@@ -1748,6 +1880,20 @@
name = "Vulpkanin Nose"
icon_state = "markings_face_nose_vulp"
+/datum/sprite_accessory/head_accessory/vulpkanin/vulp_nose2
+ name = "Vulpkanin Nose Alt."
+ icon_state = "markings_face_nose2_vulp"
+
+/datum/sprite_accessory/head_accessory/vulpkanin/vulp_elder
+ icon = 'icons/mob/human_face.dmi'
+ name = "Elder"
+ icon_state = "vulp_facial_elder"
+
+/datum/sprite_accessory/head_accessory/vulpkanin/vulp_slash
+ icon = 'icons/mob/human_face.dmi'
+ name = "Slash"
+ icon_state = "vulp_facial_slash"
+
/datum/sprite_accessory/head_accessory/ipc
species_allowed = list("Machine")
over_hair = 1
@@ -1768,6 +1914,68 @@
name = "Head Light"
icon_state = "light"
+/datum/sprite_accessory/head_accessory/ipc/ipc_side_lights
+ name = "Side Lights"
+ icon_state = "sidelights"
+
+/datum/sprite_accessory/head_accessory/ipc/ipc_side_cyber_head
+ name = "Cyber Pipes"
+ icon_state = "cyberhead"
+
+/datum/sprite_accessory/head_accessory/ipc/ipc_side_antlers
+ name = "Antlers"
+ icon_state = "antlers"
+
+/datum/sprite_accessory/head_accessory/ipc/ipc_side_drone_eyes
+ name = "Drone Eyes"
+ icon_state = "droneeyes"
+
+/datum/sprite_accessory/head_accessory/ipc/ipc_crowned
+ name = "Crowned"
+ icon_state = "crowned"
+
+/datum/sprite_accessory/head_accessory/kidan
+ icon = 'icons/mob/human_face.dmi'
+ species_allowed = list("Kidan")
+ over_hair = 1
+ do_colouration = 1
+
+/datum/sprite_accessory/head_accessory/kidan/perked_antennae
+ name = "Perked-up Antennae"
+ icon_state = "kidan_perky"
+
+/datum/sprite_accessory/head_accessory/kidan/mopey_antennae
+ name = "Mopey Antennae"
+ icon_state = "kidan_mopey"
+
+/datum/sprite_accessory/head_accessory/kidan/curious_antennae
+ name = "Curious Antennae"
+ icon_state = "kidan_curious"
+
+/datum/sprite_accessory/head_accessory/kidan/mopey_antennae
+ name = "Mopey Antennae"
+ icon_state = "kidan_mopey"
+
+/datum/sprite_accessory/head_accessory/kidan/crescent_antennae
+ name = "Crescent Antennae"
+ icon_state = "kidan_crescent"
+
+/datum/sprite_accessory/head_accessory/kidan/alert_antennae
+ name = "Alert Antennae"
+ icon_state = "kidan_alert"
+
+/datum/sprite_accessory/head_accessory/kidan/normal_antennae
+ name = "Normal Antennae"
+ icon_state = "kidan_normal"
+
+/datum/sprite_accessory/head_accessory/kidan/long_antennae
+ name = "Long Antennae"
+ icon_state = "kidan_long"
+
+/datum/sprite_accessory/head_accessory/kidan/moth_antennae
+ name = "Moth Antennae"
+ icon_state = "kidan_moth"
+
/* BODY MARKINGS */
@@ -1779,7 +1987,7 @@
/datum/sprite_accessory/body_markings/none
name = "None"
- species_allowed = list("Human", "Unathi", "Diona", "Grey", "Machine", "Tajaran", "Vulpkanin", "Slime People", "Skeleton", "Vox")
+ species_allowed = list("Human", "Unathi", "Diona", "Grey", "Machine", "Tajaran", "Vulpkanin", "Skrell", "Slime People", "Skeleton", "Vox")
icon_state = "accessory_none"
/datum/sprite_accessory/body_markings/tiger
@@ -1933,6 +2141,10 @@
name = "Vulpkanin Nose"
icon_state = "markings_face_nose_vulp"
+/datum/sprite_accessory/body_markings/head/vulpkanin/nose2_default_vulp
+ name = "Vulpkanin Nose Alt."
+ icon_state = "markings_face_nose2_vulp"
+
/datum/sprite_accessory/body_markings/head/vulpkanin/muzzle_vulp //Companion marking for Vulpkanin Belly Alt..
name = "Vulpkanin Muzzle"
icon_state = "markings_face_full_vulp"
@@ -1968,6 +2180,7 @@
/datum/sprite_accessory/body_markings/head/unathi/snout_lower_una_round
name = "Unathi Lower Round Snout"
icon_state = "markings_face_snout_lower_una"
+ heads_allowed = list("All")
/datum/sprite_accessory/body_markings/head/unathi/banded_una //Companion marking for Unathi Banded.
name = "Unathi Banded Head"
diff --git a/code/modules/modular_computers/NTNet/NTNRC/conversation.dm b/code/modules/modular_computers/NTNet/NTNRC/conversation.dm
new file mode 100644
index 00000000000..55998071e71
--- /dev/null
+++ b/code/modules/modular_computers/NTNet/NTNRC/conversation.dm
@@ -0,0 +1,70 @@
+var/global/static/ntnrc_uid = 0
+
+/datum/ntnet_conversation
+ var/id = null
+ var/title = "Untitled Conversation"
+ var/datum/computer_file/program/chatclient/operator // "Administrator" of this channel. Creator starts as channel's operator,
+ var/list/messages = list()
+ var/list/clients = list()
+ var/password
+
+/datum/ntnet_conversation/New()
+ id = ntnrc_uid
+ ntnrc_uid++
+ if(ntnet_global)
+ ntnet_global.chat_channels.Add(src)
+ ..()
+
+/datum/ntnet_conversation/Destroy()
+ if(ntnet_global)
+ ntnet_global.chat_channels.Remove(src)
+ return ..()
+
+/datum/ntnet_conversation/proc/add_message(message, username)
+ message = "[worldtime2text()] [username]: [message]"
+ messages.Add(message)
+ trim_message_list()
+
+/datum/ntnet_conversation/proc/add_status_message(message)
+ messages.Add("[worldtime2text()] -!- [message]")
+ trim_message_list()
+
+/datum/ntnet_conversation/proc/trim_message_list()
+ if(messages.len <= 50)
+ return
+ messages = messages.Copy(messages.len-50 ,0)
+
+/datum/ntnet_conversation/proc/add_client(datum/computer_file/program/chatclient/C)
+ if(!istype(C))
+ return
+ clients.Add(C)
+ add_status_message("[C.username] has joined the channel.")
+ // No operator, so we assume the channel was empty. Assign this user as operator.
+ if(!operator)
+ changeop(C)
+
+/datum/ntnet_conversation/proc/remove_client(datum/computer_file/program/chatclient/C)
+ if(!istype(C) || !(C in clients))
+ return
+ clients.Remove(C)
+ add_status_message("[C.username] has left the channel.")
+
+ // Channel operator left, pick new operator
+ if(C == operator)
+ operator = null
+ if(clients.len)
+ var/datum/computer_file/program/chatclient/newop = pick(clients)
+ changeop(newop)
+
+
+/datum/ntnet_conversation/proc/changeop(datum/computer_file/program/chatclient/newop)
+ if(istype(newop))
+ operator = newop
+ add_status_message("Channel operator status transferred to [newop.username].")
+
+/datum/ntnet_conversation/proc/change_title(newtitle, datum/computer_file/program/chatclient/client)
+ if(operator != client)
+ return 0 // Not Authorised
+
+ add_status_message("[client.username] has changed channel title from [title] to [newtitle]")
+ title = newtitle
diff --git a/code/modules/modular_computers/NTNet/NTNet.dm b/code/modules/modular_computers/NTNet/NTNet.dm
new file mode 100644
index 00000000000..ed69207f0ee
--- /dev/null
+++ b/code/modules/modular_computers/NTNet/NTNet.dm
@@ -0,0 +1,145 @@
+var/global/datum/ntnet/ntnet_global = new()
+
+
+// This is the NTNet datum. There can be only one NTNet datum in game at once. Modular computers read data from this.
+/datum/ntnet
+ var/list/relays = list()
+ var/list/logs = list()
+ var/list/available_station_software = list()
+ var/list/available_antag_software = list()
+ var/list/chat_channels = list()
+ var/list/fileservers = list()
+ // Amount of logs the system tries to keep in memory. Keep below 999 to prevent byond from acting weirdly.
+ // High values make displaying logs much laggier.
+ var/setting_maxlogcount = 100
+
+ // These only affect wireless. LAN (consoles) are unaffected since it would be possible to create scenario where someone turns off NTNet, and is unable to turn it back on since it refuses connections
+ var/setting_softwaredownload = 1
+ var/setting_peertopeer = 1
+ var/setting_communication = 1
+ var/setting_systemcontrol = 1
+ var/setting_disabled = 0 // Setting to 1 will disable all wireless, independently on relays status.
+
+ var/intrusion_detection_enabled = 1 // Whether the IDS warning system is enabled
+ var/intrusion_detection_alarm = 0 // Set when there is an IDS warning due to malicious (antag) software.
+
+
+// If new NTNet datum is spawned, it replaces the old one.
+/datum/ntnet/New()
+ if(ntnet_global && (ntnet_global != src))
+ ntnet_global = src // There can be only one.
+ for(var/obj/machinery/ntnet_relay/R in machines)
+ relays.Add(R)
+ R.NTNet = src
+ build_software_lists()
+ add_log("NTNet logging system activated.")
+
+// Simplified logging: Adds a log. log_string is mandatory parameter, source is optional.
+/datum/ntnet/proc/add_log(log_string, obj/item/weapon/computer_hardware/network_card/source = null)
+ var/log_text = "[worldtime2text()] - "
+ if(source)
+ log_text += "[source.get_network_tag()] - "
+ else
+ log_text += "*SYSTEM* - "
+ log_text += log_string
+ logs.Add(log_text)
+
+
+ // We have too many logs, remove the oldest entries until we get into the limit
+ if(logs.len > setting_maxlogcount)
+ logs = logs.Copy(logs.len-setting_maxlogcount,0)
+
+
+// Checks whether NTNet operates. If parameter is passed checks whether specific function is enabled.
+/datum/ntnet/proc/check_function(specific_action = 0)
+ if(!relays || !relays.len) // No relays found. NTNet is down
+ return 0
+
+ var/operating = 0
+
+ // Check all relays. If we have at least one working relay, network is up.
+ for(var/M in relays)
+ var/obj/machinery/ntnet_relay/R = M
+ if(R.operable())
+ operating = 1
+ break
+
+ if(setting_disabled)
+ return 0
+
+ switch(specific_action)
+ if(NTNET_SOFTWAREDOWNLOAD)
+ return (operating && setting_softwaredownload)
+ if(NTNET_PEERTOPEER)
+ return (operating && setting_peertopeer)
+ if(NTNET_COMMUNICATION)
+ return (operating && setting_communication)
+ if(NTNET_SYSTEMCONTROL)
+ return (operating && setting_systemcontrol)
+ return operating
+
+// Builds lists that contain downloadable software.
+/datum/ntnet/proc/build_software_lists()
+ available_station_software = list()
+ available_antag_software = list()
+ for(var/F in typesof(/datum/computer_file/program))
+ var/datum/computer_file/program/prog = new F
+ // Invalid type (shouldn't be possible but just in case), invalid filetype (not executable program) or invalid filename (unset program)
+ if(!prog || prog.filename == "UnknownProgram" || prog.filetype != "PRG")
+ continue
+ // Check whether the program should be available for station/antag download, if yes, add it to lists.
+ if(prog.available_on_ntnet)
+ available_station_software.Add(prog)
+ if(prog.available_on_syndinet)
+ available_antag_software.Add(prog)
+
+// Attempts to find a downloadable file according to filename var
+/datum/ntnet/proc/find_ntnet_file_by_name(filename)
+ for(var/N in available_station_software)
+ var/datum/computer_file/program/P = N
+ if(filename == P.filename)
+ return P
+ for(var/N in available_antag_software)
+ var/datum/computer_file/program/P = N
+ if(filename == P.filename)
+ return P
+
+// Resets the IDS alarm
+/datum/ntnet/proc/resetIDS()
+ intrusion_detection_alarm = 0
+
+/datum/ntnet/proc/toggleIDS()
+ resetIDS()
+ intrusion_detection_enabled = !intrusion_detection_enabled
+
+// Removes all logs
+/datum/ntnet/proc/purge_logs()
+ logs = list()
+ add_log("-!- LOGS DELETED BY SYSTEM OPERATOR -!-")
+
+// Updates maximal amount of stored logs. Use this instead of setting the number, it performs required checks.
+/datum/ntnet/proc/update_max_log_count(lognumber)
+ if(!lognumber)
+ return 0
+ // Trim the value if necessary
+ lognumber = max(MIN_NTNET_LOGS, min(lognumber, MAX_NTNET_LOGS))
+ setting_maxlogcount = lognumber
+ add_log("Configuration Updated. Now keeping [setting_maxlogcount] logs in system memory.")
+
+/datum/ntnet/proc/toggle_function(function)
+ if(!function)
+ return
+ function = text2num(function)
+ switch(function)
+ if(NTNET_SOFTWAREDOWNLOAD)
+ setting_softwaredownload = !setting_softwaredownload
+ add_log("Configuration Updated. Wireless network firewall now [setting_softwaredownload ? "allows" : "disallows"] connection to software repositories.")
+ if(NTNET_PEERTOPEER)
+ setting_peertopeer = !setting_peertopeer
+ add_log("Configuration Updated. Wireless network firewall now [setting_peertopeer ? "allows" : "disallows"] peer to peer network traffic.")
+ if(NTNET_COMMUNICATION)
+ setting_communication = !setting_communication
+ add_log("Configuration Updated. Wireless network firewall now [setting_communication ? "allows" : "disallows"] instant messaging and similar communication services.")
+ if(NTNET_SYSTEMCONTROL)
+ setting_systemcontrol = !setting_systemcontrol
+ add_log("Configuration Updated. Wireless network firewall now [setting_systemcontrol ? "allows" : "disallows"] remote control of station's systems.")
diff --git a/code/modules/modular_computers/NTNet/NTNet_relay.dm b/code/modules/modular_computers/NTNet/NTNet_relay.dm
new file mode 100644
index 00000000000..5f5325e0364
--- /dev/null
+++ b/code/modules/modular_computers/NTNet/NTNet_relay.dm
@@ -0,0 +1,128 @@
+// Relays don't handle any actual communication. Global NTNet datum does that, relays only tell the datum if it should or shouldn't work.
+/obj/machinery/ntnet_relay
+ name = "NTNet Quantum Relay"
+ desc = "A very complex router and transmitter capable of connecting electronic devices together. Looks fragile."
+ use_power = 2
+ active_power_usage = 10000 //10kW, apropriate for machine that keeps massive cross-Zlevel wireless network operational. Used to be 20 but that actually drained the smes one round
+ idle_power_usage = 100
+ icon = 'icons/obj/stationobjs.dmi'
+ icon_state = "bus"
+ anchored = 1
+ density = 1
+ var/datum/ntnet/NTNet = null // This is mostly for backwards reference and to allow varedit modifications from ingame.
+ var/enabled = 1 // Set to 0 if the relay was turned off
+ var/dos_failure = 0 // Set to 1 if the relay failed due to (D)DoS attack
+ var/list/dos_sources = list() // Backwards reference for qdel() stuff
+
+ // Denial of Service attack variables
+ var/dos_overload = 0 // Amount of DoS "packets" in this relay's buffer
+ var/dos_capacity = 500 // Amount of DoS "packets" in buffer required to crash the relay
+ var/dos_dissipate = 1 // Amount of DoS "packets" dissipated over time.
+
+
+// TODO: Implement more logic here. For now it's only a placeholder.
+/obj/machinery/ntnet_relay/inoperable(additional_flags = 0)
+ if(stat & (BROKEN | NOPOWER | EMPED | additional_flags))
+ return 1
+ if(dos_failure)
+ return 1
+ if(!enabled)
+ return 1
+ return 0
+
+/obj/machinery/ntnet_relay/update_icon()
+ if(operable())
+ icon_state = "bus"
+ else
+ icon_state = "bus_off"
+
+/obj/machinery/ntnet_relay/process()
+ if(operable())
+ use_power = 2
+ else
+ use_power = 1
+
+ update_icon()
+
+ if(dos_overload)
+ dos_overload = max(0, dos_overload - dos_dissipate)
+
+ // If DoS traffic exceeded capacity, crash.
+ if((dos_overload > dos_capacity) && !dos_failure)
+ dos_failure = 1
+ update_icon()
+ ntnet_global.add_log("Quantum relay switched from normal operation mode to overload recovery mode.")
+ // If the DoS buffer reaches 0 again, restart.
+ if((dos_overload == 0) && dos_failure)
+ dos_failure = 0
+ update_icon()
+ ntnet_global.add_log("Quantum relay switched from overload recovery mode to normal operation mode.")
+ ..()
+
+/obj/machinery/ntnet_relay/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "ntnet_relay.tmpl", "NTNet Quantum Relay", 500, 300)
+ ui.open()
+
+/obj/machinery/ntnet_relay/ui_data(mob/user)
+ var/list/data = list()
+ data["enabled"] = enabled
+ data["dos_capacity"] = dos_capacity
+ data["dos_overload"] = dos_overload
+ data["dos_crashed"] = dos_failure
+ return data
+
+
+/obj/machinery/ntnet_relay/Topic(href, list/href_list)
+ if(..())
+ return
+ switch(href_list["action"])
+ if("restart")
+ dos_overload = 0
+ dos_failure = 0
+ update_icon()
+ ntnet_global.add_log("Quantum relay manually restarted from overload recovery mode to normal operation mode.")
+ if("toggle")
+ enabled = !enabled
+ ntnet_global.add_log("Quantum relay manually [enabled ? "enabled" : "disabled"].")
+ update_icon()
+ return 1
+
+
+/obj/machinery/ntnet_relay/attack_hand(mob/living/user)
+ ui_interact(user)
+
+/obj/machinery/ntnet_relay/New()
+ uid = gl_uid
+ gl_uid++
+ component_parts = list()
+ component_parts += new /obj/item/weapon/circuitboard/machine/ntnet_relay(null)
+ component_parts += new /obj/item/stack/cable_coil(null, 2)
+ component_parts += new /obj/item/weapon/stock_parts/subspace/filter(null)
+
+ if(ntnet_global)
+ ntnet_global.relays.Add(src)
+ NTNet = ntnet_global
+ ntnet_global.add_log("New quantum relay activated. Current amount of linked relays: [NTNet.relays.len]")
+ ..()
+
+/obj/machinery/ntnet_relay/Destroy()
+ if(ntnet_global)
+ ntnet_global.relays.Remove(src)
+ ntnet_global.add_log("Quantum relay connection severed. Current amount of linked relays: [NTNet.relays.len]")
+ NTNet = null
+
+ for(var/datum/computer_file/program/ntnet_dos/D in dos_sources)
+ D.target = null
+ D.error = "Connection to quantum relay severed"
+
+ return ..()
+
+/obj/item/weapon/circuitboard/machine/ntnet_relay
+ name = "NTNet Relay (Machine Board)"
+ build_path = /obj/machinery/ntnet_relay
+ origin_tech = "programming=3;bluespace=3;magnets=2"
+ req_components = list(
+ /obj/item/stack/cable_coil = 2,
+ /obj/item/weapon/stock_parts/subspace/filter = 1)
diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm
new file mode 100644
index 00000000000..9f867692153
--- /dev/null
+++ b/code/modules/modular_computers/computers/item/computer.dm
@@ -0,0 +1,381 @@
+// This is the base type that does all the hardware stuff.
+// Other types expand it - tablets use a direct subtypes, and
+// consoles and laptops use "procssor" item that is held inside machinery piece
+/obj/item/device/modular_computer
+ name = "modular microcomputer"
+ desc = "A small portable microcomputer."
+
+ var/enabled = 0 // Whether the computer is turned on.
+ var/screen_on = 1 // Whether the computer is active/opened/it's screen is on.
+ var/datum/computer_file/program/active_program = null // A currently active program running on the computer.
+ var/hardware_flag = 0 // A flag that describes this device type
+ var/last_power_usage = 0
+ var/last_battery_percent = 0 // Used for deciding if battery percentage has chandged
+ var/last_world_time = "00:00"
+ var/list/last_header_icons
+ var/emagged = 0 // Whether the computer is emagged.
+
+ var/base_active_power_usage = 50 // Power usage when the computer is open (screen is active) and can be interacted with. Remember hardware can use power too.
+ var/base_idle_power_usage = 5 // Power usage when the computer is idle and screen is off (currently only applies to laptops)
+
+ // Modular computers can run on various devices. Each DEVICE (Laptop, Console, Tablet,..)
+ // must have it's own DMI file. Icon states must be called exactly the same in all files, but may look differently
+ // If you create a program which is limited to Laptops and Consoles you don't have to add it's icon_state overlay for Tablets too, for example.
+
+ icon = 'icons/obj/computer.dmi'
+ icon_state = "laptop-open"
+ var/icon_state_unpowered = null // Icon state when the computer is turned off.
+ var/icon_state_powered = null // Icon state when the computer is turned on.
+ var/icon_state_menu = "menu" // Icon state overlay when the computer is turned on, but no program is loaded that would override the screen.
+ var/max_hardware_size = 0 // Maximal hardware w_class. Tablets/PDAs have 1, laptops 2, consoles 4.
+ var/steel_sheet_cost = 5 // Amount of steel sheets refunded when disassembling an empty frame of this computer.
+
+ var/obj_integrity = 100
+ var/integrity_failure = 50
+ var/max_integrity = 100
+ armor = list(melee = 0, bullet = 20, laser = 20, energy = 100, bomb = 0, bio = 100, rad = 100, fire = 0, acid = 0)
+
+ // Important hardware (must be installed for computer to work)
+
+ // Optional hardware (improves functionality, but is not critical for computer to work)
+
+ var/list/all_components // List of "connection ports" in this computer and the components with which they are plugged
+
+ var/list/idle_threads // Idle programs on background. They still receive process calls but can't be interacted with.
+ var/obj/physical = null // Object that represents our computer. It's used for Adjacent() and UI visibility checks.
+
+
+
+/obj/item/device/modular_computer/New()
+ update_icon()
+ if(!physical)
+ physical = src
+ ..()
+ processing_objects += src
+ all_components = list()
+ idle_threads = list()
+
+/obj/item/device/modular_computer/Destroy()
+ kill_program(forced = TRUE)
+ for(var/H in all_components)
+ var/obj/item/weapon/computer_hardware/CH = all_components[H]
+ if(CH.holder == src)
+ CH.on_remove(src)
+ CH.holder = null
+ all_components.Remove(CH.device_type)
+ qdel(CH)
+ physical = null
+ processing_objects -= src
+ return ..()
+
+
+/obj/item/device/modular_computer/proc/add_verb(var/path)
+ switch(path)
+ if(MC_CARD)
+ verbs += /obj/item/device/modular_computer/proc/eject_id
+ if(MC_SDD)
+ verbs += /obj/item/device/modular_computer/proc/eject_disk
+ if(MC_AI)
+ verbs += /obj/item/device/modular_computer/proc/eject_card
+
+/obj/item/device/modular_computer/proc/remove_verb(path)
+ switch(path)
+ if(MC_CARD)
+ verbs -= /obj/item/device/modular_computer/proc/eject_id
+ if(MC_SDD)
+ verbs -= /obj/item/device/modular_computer/proc/eject_disk
+ if(MC_AI)
+ verbs -= /obj/item/device/modular_computer/proc/eject_card
+
+// Eject ID card from computer, if it has ID slot with card inside.
+/obj/item/device/modular_computer/proc/eject_id()
+ set name = "Eject ID"
+ set category = "Object"
+ set src in view(1)
+
+ if(issilicon(usr))
+ return
+ var/obj/item/weapon/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
+ if(!usr.incapacitated())
+ card_slot.try_eject(null, usr)
+
+// Eject ID card from computer, if it has ID slot with card inside.
+/obj/item/device/modular_computer/proc/eject_card()
+ set name = "Eject Intellicard"
+ set category = "Object"
+ set src in view(1)
+
+ if(issilicon(usr))
+ return
+ var/obj/item/weapon/computer_hardware/ai_slot/ai_slot = all_components[MC_AI]
+ if(!usr.incapacitated())
+ ai_slot.try_eject(null, usr, 1)
+
+
+// Eject ID card from computer, if it has ID slot with card inside.
+/obj/item/device/modular_computer/proc/eject_disk()
+ set name = "Eject Data Disk"
+ set category = "Object"
+ set src in view(1)
+
+ if(issilicon(usr))
+ return
+
+ if(!usr.incapacitated())
+ var/obj/item/weapon/computer_hardware/hard_drive/portable/portable_drive = all_components[MC_SDD]
+ if(uninstall_component(portable_drive, usr))
+ portable_drive.verb_pickup()
+
+/obj/item/device/modular_computer/AltClick(mob/user)
+ ..()
+ if(issilicon(user))
+ return
+
+ if(!user.incapacitated() && Adjacent(user))
+ var/obj/item/weapon/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
+ var/obj/item/weapon/computer_hardware/ai_slot/ai_slot = all_components[MC_AI]
+ var/obj/item/weapon/computer_hardware/hard_drive/portable/portable_drive = all_components[MC_SDD]
+ if(portable_drive)
+ if(uninstall_component(portable_drive, user))
+ portable_drive.verb_pickup()
+ else
+ if(card_slot && card_slot.try_eject(null, user))
+ return
+ if(ai_slot)
+ ai_slot.try_eject(null, user)
+
+
+// Gets IDs/access levels from card slot. Would be useful when/if PDAs would become modular PCs.
+/obj/item/device/modular_computer/GetAccess()
+ var/obj/item/weapon/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
+ if(card_slot)
+ return card_slot.GetAccess()
+ return ..()
+
+/obj/item/device/modular_computer/GetID()
+ var/obj/item/weapon/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
+ if(card_slot)
+ return card_slot.GetID()
+ return ..()
+
+/obj/item/device/modular_computer/attack_ai(mob/user)
+ return attack_self(user)
+
+/obj/item/device/modular_computer/attack_ghost(mob/dead/observer/user)
+ if(enabled)
+ ui_interact(user)
+ else if(user.can_admin_interact())
+ var/response = alert(user, "This computer is turned off. Would you like to turn it on?", "Admin Override", "Yes", "No")
+ if(response == "Yes")
+ turn_on(user)
+
+/obj/item/device/modular_computer/emag_act(mob/user)
+ if(emagged)
+ to_chat(user, "\The [src] was already emagged.")
+ return 0
+ else
+ emagged = 1
+ to_chat(user, "You emag \the [src]. It's screen briefly shows a \"OVERRIDE ACCEPTED: New software downloads available.\" message.")
+ return 1
+
+/obj/item/device/modular_computer/examine(mob/user)
+ ..()
+ if(obj_integrity <= integrity_failure)
+ to_chat(user, "It is heavily damaged!")
+ else if(obj_integrity < max_integrity)
+ to_chat(user, "It is damaged.")
+
+/obj/item/device/modular_computer/update_icon()
+ overlays.Cut()
+ if(!enabled)
+ icon_state = icon_state_unpowered
+ else
+ icon_state = icon_state_powered
+ if(active_program && active_program.program_state != PROGRAM_STATE_KILLED)
+ overlays += active_program.program_icon_state ? active_program.program_icon_state : icon_state_menu
+ else
+ overlays += icon_state_menu
+
+ if(obj_integrity <= integrity_failure)
+ overlays += "bsod"
+ overlays += "broken"
+
+
+// On-click handling. Turns on the computer if it's off and opens the GUI.
+/obj/item/device/modular_computer/attack_self(mob/user)
+ if(enabled)
+ ui_interact(user)
+ else
+ turn_on(user)
+
+/obj/item/device/modular_computer/proc/turn_on(mob/user)
+ var/issynth = issilicon(user) // Robots and AIs get different activation messages.
+ if(obj_integrity <= integrity_failure)
+ if(issynth)
+ to_chat(user, "You send an activation signal to \the [src], but it responds with an error code. It must be damaged.")
+ else
+ to_chat(user, "You press the power button, but the computer fails to boot up, displaying variety of errors before shutting down again.")
+ return
+
+ // If we have a recharger, enable it automatically. Lets computer without a battery work.
+ var/obj/item/weapon/computer_hardware/recharger/recharger = all_components[MC_CHARGE]
+ if(recharger)
+ recharger.enabled = 1
+
+ if(all_components[MC_CPU] && use_power()) // use_power() checks if the PC is powered
+ if(issynth)
+ to_chat(user, "You send an activation signal to \the [src], turning it on.")
+ else
+ to_chat(user, "You press the power button and start up \the [src].")
+ enabled = 1
+ update_icon()
+ ui_interact(user)
+ else // Unpowered
+ if(issynth)
+ to_chat(user, "You send an activation signal to \the [src] but it does not respond.")
+ else
+ to_chat(user, "You press the power button but \the [src] does not respond.")
+
+// Process currently calls handle_power(), may be expanded in future if more things are added.
+/obj/item/device/modular_computer/process()
+ if(!enabled) // The computer is turned off
+ last_power_usage = 0
+ return 0
+
+ if(obj_integrity <= integrity_failure)
+ shutdown_computer()
+ return 0
+
+ if(active_program && active_program.requires_ntnet && !get_ntnet_status(active_program.requires_ntnet_feature))
+ active_program.event_networkfailure(0) // Active program requires NTNet to run but we've just lost connection. Crash.
+
+ if(active_program)
+ if(active_program.program_state != PROGRAM_STATE_KILLED)
+ active_program.process_tick()
+ active_program.ntnet_status = get_ntnet_status()
+ else
+ active_program = null
+
+ for(var/I in idle_threads)
+ var/datum/computer_file/program/P = I
+ if(P.program_state != PROGRAM_STATE_KILLED)
+ if(P.requires_ntnet && !get_ntnet_status(P.requires_ntnet_feature))
+ P.event_networkfailure(1)
+ P.process_tick()
+ P.ntnet_status = get_ntnet_status()
+ else
+ idle_threads.Remove(P)
+
+ handle_power() // Handles all computer power interaction
+
+// Relays kill program request to currently active program. Use this to quit current program.
+/obj/item/device/modular_computer/proc/kill_program(forced = FALSE)
+ if(active_program && active_program.program_state != PROGRAM_STATE_KILLED)
+ active_program.kill_program(forced)
+ active_program = null
+ var/mob/user = usr
+ if(user && istype(user))
+ ui_interact(user) // Re-open the UI on this computer. It should show the main screen now.
+ update_icon()
+
+// Returns 0 for No Signal, 1 for Low Signal and 2 for Good Signal. 3 is for wired connection (always-on)
+/obj/item/device/modular_computer/proc/get_ntnet_status(specific_action = 0)
+ var/obj/item/weapon/computer_hardware/network_card/network_card = all_components[MC_NET]
+ if(network_card)
+ return network_card.get_signal(specific_action)
+ else
+ return 0
+
+/obj/item/device/modular_computer/proc/add_log(text)
+ if(!get_ntnet_status())
+ return FALSE
+ var/obj/item/weapon/computer_hardware/network_card/network_card = all_components[MC_NET]
+ return ntnet_global.add_log(text, network_card)
+
+/obj/item/device/modular_computer/proc/shutdown_computer(loud = 1)
+ if(enabled)
+ kill_program(forced = TRUE)
+ for(var/datum/computer_file/program/P in idle_threads)
+ P.kill_program(forced = TRUE)
+ idle_threads.Remove(P)
+ if(loud)
+ physical.visible_message("\The [src] shuts down.")
+ enabled = 0
+ update_icon()
+
+
+/obj/item/device/modular_computer/attackby(obj/item/weapon/W, mob/user)
+ // Insert items into the components
+ for(var/h in all_components)
+ var/obj/item/weapon/computer_hardware/H = all_components[h]
+ if(H.try_insert(W, user))
+ return
+
+ // Insert new hardware
+ if(istype(W, /obj/item/weapon/computer_hardware))
+ if(install_component(W, user))
+ return
+
+ if(istype(W, /obj/item/weapon/wrench))
+ if(all_components.len)
+ to_chat(user, "Remove all components from \the [src] before disassembling it.")
+ return
+ new /obj/item/stack/sheet/metal(get_turf(loc), steel_sheet_cost)
+ physical.visible_message("\The [src] has been disassembled by [user].")
+ relay_qdel()
+ qdel(src)
+ return
+
+ if(istype(W, /obj/item/weapon/weldingtool))
+ var/obj/item/weapon/weldingtool/WT = W
+ if(!WT.isOn())
+ to_chat(user, "\The [W] is off.")
+ return
+
+ if(obj_integrity == max_integrity)
+ to_chat(user, "\The [src] does not require repairs.")
+ return
+
+ to_chat(user, "You begin repairing damage to \the [src]...")
+ var/dmg = round(max_integrity - obj_integrity)
+ if(WT.remove_fuel(round(dmg/75)) && do_after(usr, dmg/10))
+ obj_integrity = max_integrity
+ to_chat(user, "You repair \the [src].")
+ return
+
+ if(istype(W, /obj/item/weapon/screwdriver))
+ if(!all_components.len)
+ to_chat(user, "This device doesn't have any components installed.")
+ return
+ var/list/component_names = list()
+ for(var/h in all_components)
+ var/obj/item/weapon/computer_hardware/H = all_components[h]
+ component_names.Add(H.name)
+
+ var/choice = input(user, "Which component do you want to uninstall?", "Computer maintenance", null) as null|anything in component_names
+
+ if(!choice)
+ return
+
+ if(!Adjacent(user))
+ return
+
+ var/obj/item/weapon/computer_hardware/H = find_hardware_by_name(choice)
+
+ if(!H)
+ return
+
+ uninstall_component(H, user)
+ return
+
+ ..()
+
+// Used by processor to relay qdel() to machinery type.
+/obj/item/device/modular_computer/proc/relay_qdel()
+ return
+
+// Perform adjacency checks on our physical counterpart, if any.
+/obj/item/device/modular_computer/Adjacent(atom/neighbor)
+ if(physical && physical != src)
+ return physical.Adjacent(neighbor)
+ return ..()
diff --git a/code/modules/modular_computers/computers/item/computer_components.dm b/code/modules/modular_computers/computers/item/computer_components.dm
new file mode 100644
index 00000000000..09f027f2301
--- /dev/null
+++ b/code/modules/modular_computers/computers/item/computer_components.dm
@@ -0,0 +1,58 @@
+/obj/item/device/modular_computer/proc/can_install_component(obj/item/weapon/computer_hardware/H, mob/living/user = null)
+ if(!H.can_install(src, user))
+ return FALSE
+
+ if(H.w_class > max_hardware_size)
+ if(user)
+ to_chat(user, "This component is too large for \the [src]!")
+ return FALSE
+
+ if(all_components[H.device_type])
+ if(user)
+ to_chat(user, "This computer's hardware slot is already occupied by \the [all_components[H.device_type]].")
+ return FALSE
+ return TRUE
+
+
+// Installs component.
+/obj/item/device/modular_computer/proc/install_component(obj/item/weapon/computer_hardware/H, mob/living/user = null)
+ if(!can_install_component(H, user))
+ return FALSE
+
+ if(user && !user.unEquip(H))
+ return FALSE
+ H.forceMove(src)
+
+ all_components[H.device_type] = H
+
+ if(user)
+ to_chat(user, "You install \the [H] into \the [src].")
+ H.holder = src
+ H.on_install(src, user)
+
+
+// Uninstalls component.
+/obj/item/device/modular_computer/proc/uninstall_component(obj/item/weapon/computer_hardware/H, mob/living/user = null)
+ if(H.holder != src) // Not our component at all.
+ return FALSE
+
+ all_components.Remove(H.device_type)
+
+ if(user)
+ to_chat(user, "You remove \the [H] from \the [src].")
+
+ H.forceMove(get_turf(src))
+ H.holder = null
+ H.on_remove(src, user)
+ if(enabled && !use_power())
+ shutdown_computer()
+ update_icon()
+
+
+// Checks all hardware pieces to determine if name matches, if yes, returns the hardware piece, otherwise returns null
+/obj/item/device/modular_computer/proc/find_hardware_by_name(name)
+ for(var/i in all_components)
+ var/obj/O = all_components[i]
+ if(O.name == name)
+ return O
+ return null
diff --git a/code/modules/modular_computers/computers/item/computer_damage.dm b/code/modules/modular_computers/computers/item/computer_damage.dm
new file mode 100644
index 00000000000..689e8c99ab7
--- /dev/null
+++ b/code/modules/modular_computers/computers/item/computer_damage.dm
@@ -0,0 +1,52 @@
+/obj/item/device/modular_computer/emp_act(severity)
+ if(prob(20 / severity))
+ take_damage(obj_integrity, BURN)
+ ..()
+
+/obj/item/device/modular_computer/ex_act(severity)
+ switch(severity)
+ if(1)
+ qdel(src)
+ if(2)
+ if(prob(25))
+ qdel(src)
+ else if(prob(50))
+ obj_integrity = 0
+ if(3)
+ if(prob(25))
+ obj_integrity = 0
+
+/obj/item/device/modular_computer/bullet_act(obj/item/projectile/P)
+ take_damage(P.damage, P.damage_type)
+ ..()
+
+/obj/item/device/modular_computer/blob_act()
+ if(prob(75))
+ take_damage(obj_integrity, BRUTE)
+
+/obj/item/device/modular_computer/proc/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1)
+ . = ..()
+ var/component_probability = min(50, max(damage_amount*0.1, 1 - obj_integrity/max_integrity))
+ switch(damage_flag)
+ if("bullet")
+ component_probability = damage_amount * 0.5
+ if("laser")
+ component_probability = damage_amount * 0.66
+ if(component_probability)
+ for(var/I in all_components)
+ var/obj/item/weapon/computer_hardware/H = all_components[I]
+ if(prob(component_probability))
+ H.take_damage(round(damage_amount*0.5))
+
+/obj/item/device/modular_computer/proc/break_apart(damage = TRUE)
+ physical.visible_message("\The [src] breaks apart!")
+ var/turf/newloc = get_turf(src)
+ new /obj/item/stack/sheet/metal(newloc, round(steel_sheet_cost/2))
+ for(var/C in all_components)
+ var/obj/item/weapon/computer_hardware/H = all_components[C]
+ uninstall_component(H)
+ H.forceMove(newloc)
+ if(damage && prob(25))
+ H.take_damage(rand(10, 30))
+ relay_qdel()
+ qdel(src)
diff --git a/code/modules/modular_computers/computers/item/computer_power.dm b/code/modules/modular_computers/computers/item/computer_power.dm
new file mode 100644
index 00000000000..8483e9c4fc6
--- /dev/null
+++ b/code/modules/modular_computers/computers/item/computer_power.dm
@@ -0,0 +1,73 @@
+// Tries to draw power from charger or, if no operational charger is present, from power cell.
+/obj/item/device/modular_computer/proc/use_power(amount = 0)
+ if(check_power_override())
+ return TRUE
+
+ var/obj/item/weapon/computer_hardware/recharger/recharger = all_components[MC_CHARGE]
+
+ if(recharger && recharger.check_functionality())
+ if(recharger.use_power(amount))
+ return TRUE
+
+ var/obj/item/weapon/computer_hardware/battery/battery_module = all_components[MC_CELL]
+
+ if(battery_module && battery_module.battery && battery_module.battery.charge)
+ var/obj/item/weapon/stock_parts/cell/cell = battery_module.battery
+ if(cell.use(amount * CELLRATE))
+ return TRUE
+ else // Discharge the cell anyway.
+ cell.use(min(amount*CELLRATE, cell.charge))
+ return FALSE
+ return FALSE
+
+/obj/item/device/modular_computer/proc/give_power(amount)
+ var/obj/item/weapon/computer_hardware/battery/battery_module = all_components[MC_CELL]
+ if(battery_module && battery_module.battery)
+ return battery_module.battery.give(amount)
+ return 0
+
+
+// Used in following function to reduce copypaste
+/obj/item/device/modular_computer/proc/power_failure()
+ if(enabled) // Shut down the computer
+ if(active_program)
+ active_program.event_powerfailure(0)
+ for(var/I in idle_threads)
+ var/datum/computer_file/program/PRG = I
+ PRG.event_powerfailure(1)
+ shutdown_computer(0)
+
+// Handles power-related things, such as battery interaction, recharging, shutdown when it's discharged
+/obj/item/device/modular_computer/proc/handle_power()
+ var/obj/item/weapon/computer_hardware/recharger/recharger = all_components[MC_CHARGE]
+ if(recharger)
+ recharger.process()
+
+ var/power_usage = screen_on ? base_active_power_usage : base_idle_power_usage
+
+ for(var/obj/item/weapon/computer_hardware/H in all_components)
+ if(H.enabled)
+ power_usage += H.power_usage
+
+ if(use_power(power_usage))
+ last_power_usage = power_usage
+ return TRUE
+ else
+ power_failure()
+ return FALSE
+
+/obj/item/device/modular_computer/proc/get_power_eta()
+ var/obj/item/weapon/computer_hardware/battery/battery_module = all_components[MC_CELL]
+ if(battery_module && battery_module.battery)
+ var/hours = 0
+ var/minutes = (battery_module.battery.charge) / (last_power_usage / 20) // 20 = obj processing interval
+ if(minutes > 60)
+ hours = minutes/60
+ minutes = (hours - round(hours)) * 60
+ var/seconds = (minutes - round(minutes)) * 60
+ return list("hours" = hours, "minutes" = minutes, "seconds" = seconds)
+ return list()
+
+// Used by child types if they have other power source than battery or recharger
+/obj/item/device/modular_computer/proc/check_power_override()
+ return FALSE
diff --git a/code/modules/modular_computers/computers/item/computer_ui.dm b/code/modules/modular_computers/computers/item/computer_ui.dm
new file mode 100644
index 00000000000..4044e2530bf
--- /dev/null
+++ b/code/modules/modular_computers/computers/item/computer_ui.dm
@@ -0,0 +1,194 @@
+// Operates NanoUI
+/obj/item/device/modular_computer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ if(!enabled)
+ if(ui)
+ ui.close()
+ return 0
+ if(!use_power())
+ if(ui)
+ ui.close()
+ return 0
+
+ // Robots don't really need to see the screen, their wireless connection works as long as computer is on.
+ if(!screen_on && !issilicon(user))
+ if(ui)
+ ui.close()
+ return 0
+
+ // If we have an active program switch to it now.
+ if(active_program)
+ if(ui) // This is the main laptop screen. Since we are switching to program's UI close it for now.
+ ui.close()
+ active_program.ui_interact(user)
+ return
+
+ // We are still here, that means there is no program loaded. Load the BIOS/ROM/OS/whatever you want to call it.
+ // This screen simply lists available programs and user may select them.
+ var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD]
+ if(!hard_drive || !hard_drive.stored_files || !hard_drive.stored_files.len)
+ to_chat(user, "\The [src] beeps three times, it's screen displaying a \"DISK ERROR\" warning.")
+ return // No HDD, No HDD files list or no stored files. Something is very broken.
+
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers)
+ assets.send(user)
+ ui = new(user, src, ui_key, "computer_main.tmpl", "NTOS Main menu", 400, 500)
+ ui.set_auto_update(1)
+ ui.set_layout_key("program")
+ ui.open()
+
+
+/obj/item/device/modular_computer/ui_data(mob/user)
+ var/list/data = get_header_data()
+ data["programs"] = list()
+ var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD]
+ for(var/datum/computer_file/program/P in hard_drive.stored_files)
+ var/running = 0
+ if(P in idle_threads)
+ running = 1
+
+ data["programs"] += list(list("name" = P.filename, "desc" = P.filedesc, "running" = running))
+
+ return data
+
+// Function used by NanoUI's to obtain data for header. All relevant entries begin with "PC_"
+/obj/item/device/modular_computer/proc/get_header_data()
+ var/list/data = list()
+
+ var/obj/item/weapon/computer_hardware/battery/battery_module = all_components[MC_CELL]
+ var/obj/item/weapon/computer_hardware/recharger/recharger = all_components[MC_CHARGE]
+
+ if(battery_module && battery_module.battery)
+ switch(battery_module.battery.percent())
+ if(80 to 200) // 100 should be maximal but just in case..
+ data["PC_batteryicon"] = "batt_100.gif"
+ if(60 to 80)
+ data["PC_batteryicon"] = "batt_80.gif"
+ if(40 to 60)
+ data["PC_batteryicon"] = "batt_60.gif"
+ if(20 to 40)
+ data["PC_batteryicon"] = "batt_40.gif"
+ if(5 to 20)
+ data["PC_batteryicon"] = "batt_20.gif"
+ else
+ data["PC_batteryicon"] = "batt_5.gif"
+ data["PC_batterypercent"] = "[round(battery_module.battery.percent())] %"
+ data["PC_showbatteryicon"] = 1
+ else
+ data["PC_batteryicon"] = "batt_5.gif"
+ data["PC_batterypercent"] = "N/C"
+ data["PC_showbatteryicon"] = battery_module ? 1 : 0
+
+ if(recharger && recharger.enabled && recharger.check_functionality() && recharger.use_power(0))
+ data["PC_apclinkicon"] = "charging.gif"
+
+ switch(get_ntnet_status())
+ if(0)
+ data["PC_ntneticon"] = "sig_none.gif"
+ if(1)
+ data["PC_ntneticon"] = "sig_low.gif"
+ if(2)
+ data["PC_ntneticon"] = "sig_high.gif"
+ if(3)
+ data["PC_ntneticon"] = "sig_lan.gif"
+
+ if(idle_threads.len)
+ var/list/program_headers = list()
+ for(var/I in idle_threads)
+ var/datum/computer_file/program/P = I
+ if(!P.ui_header)
+ continue
+ program_headers.Add(list(list(
+ "icon" = P.ui_header
+ )))
+
+ data["PC_programheaders"] = program_headers
+
+ data["PC_stationtime"] = worldtime2text()
+ data["PC_showexitprogram"] = active_program ? 1 : 0 // Hides "Exit Program" button on mainscreen
+ return data
+
+
+// Handles user's GUI input
+/obj/item/device/modular_computer/Topic(href, list/href_list)
+ if(..())
+ return
+ var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD]
+ switch(href_list["action"])
+ if("PC_exit")
+ kill_program()
+ return 1
+ if("PC_shutdown")
+ shutdown_computer()
+ return 1
+ if("PC_minimize")
+ var/mob/user = usr
+ if(!active_program || !all_components[MC_CPU])
+ return 1
+
+ idle_threads.Add(active_program)
+ active_program.program_state = PROGRAM_STATE_BACKGROUND // Should close any existing UIs
+
+ active_program = null
+ update_icon()
+ if(user && istype(user))
+ ui_interact(user) // Re-open the UI on this computer. It should show the main screen now.
+
+ if("PC_killprogram")
+ var/prog = href_list["name"]
+ var/datum/computer_file/program/P = null
+ var/mob/user = usr
+ if(hard_drive)
+ P = hard_drive.find_file_by_name(prog)
+
+ if(!istype(P) || P.program_state == PROGRAM_STATE_KILLED)
+ return 1
+
+ P.kill_program(forced = TRUE)
+ to_chat(user, "Program [P.filename].[P.filetype] with PID [rand(100,999)] has been killed.")
+
+ if("PC_runprogram")
+ var/prog = href_list["name"]
+ var/datum/computer_file/program/P = null
+ var/mob/user = usr
+ if(hard_drive)
+ P = hard_drive.find_file_by_name(prog)
+
+ if(!P || !istype(P)) // Program not found or it's not executable program.
+ to_chat(user, "\The [src]'s screen shows \"I/O ERROR - Unable to run program\" warning.")
+ return 1
+
+ P.computer = src
+
+ if(!P.is_supported_by_hardware(hardware_flag, 1, user))
+ return 1
+
+ // The program is already running. Resume it.
+ if(P in idle_threads)
+ P.program_state = PROGRAM_STATE_ACTIVE
+ active_program = P
+ idle_threads.Remove(P)
+ update_icon()
+ return
+
+ var/obj/item/weapon/computer_hardware/processor_unit/PU = all_components[MC_CPU]
+
+ if(idle_threads.len > PU.max_idle_programs)
+ to_chat(user, "\The [src] displays a \"Maximal CPU load reached. Unable to run another program.\" error.")
+ return 1
+
+ if(P.requires_ntnet && !get_ntnet_status(P.requires_ntnet_feature)) // The program requires NTNet connection, but we are not connected to NTNet.
+ to_chat(user, "\The [src]'s screen shows \"Unable to connect to NTNet. Please retry. If problem persists contact your system administrator.\" warning.")
+ return 1
+ if(P.run_program(user))
+ active_program = P
+ update_icon()
+ return 1
+ else
+ return
+
+/obj/item/device/modular_computer/nano_host()
+ if(physical)
+ return physical
+ return src
diff --git a/code/modules/modular_computers/computers/item/laptop.dm b/code/modules/modular_computers/computers/item/laptop.dm
new file mode 100644
index 00000000000..7a7d27acd45
--- /dev/null
+++ b/code/modules/modular_computers/computers/item/laptop.dm
@@ -0,0 +1,107 @@
+/obj/item/device/modular_computer/laptop
+ name = "laptop"
+ desc = "A portable laptop computer."
+
+ icon = 'icons/obj/modular_laptop.dmi'
+ icon_state = "laptop-closed"
+ icon_state_powered = "laptop"
+ icon_state_unpowered = "laptop-off"
+ icon_state_menu = "menu"
+
+ hardware_flag = PROGRAM_LAPTOP
+ max_hardware_size = 2
+ w_class = WEIGHT_CLASS_NORMAL
+
+ flags = HANDSLOW // No running around with open laptops in hands.
+
+ screen_on = 0 // Starts closed
+ var/start_open = 1 // unless this var is set to 1
+ var/icon_state_closed = "laptop-closed"
+ var/w_class_open = WEIGHT_CLASS_BULKY
+ var/slowdown_open = 1
+
+/obj/item/device/modular_computer/laptop/New()
+ ..()
+ if(start_open && !screen_on)
+ toggle_open()
+
+/obj/item/device/modular_computer/laptop/update_icon()
+ if(screen_on)
+ ..()
+ else
+ overlays.Cut()
+ icon_state = icon_state_closed
+
+/obj/item/device/modular_computer/laptop/attack_self(mob/user)
+ if(!screen_on)
+ try_toggle_open(user)
+ else
+ return ..()
+
+/obj/item/device/modular_computer/laptop/verb/open_computer()
+ set name = "Toggle Open"
+ set category = "Object"
+ set src in view(1)
+
+ try_toggle_open(usr)
+
+/obj/item/device/modular_computer/laptop/MouseDrop(obj/over_object, src_location, over_location)
+ if(over_object == usr || over_object == src)
+ try_toggle_open(usr)
+ if(ishuman(usr))
+ if(!isturf(loc) || !Adjacent(usr))
+ return
+ if(over_object && !usr.incapacitated())
+ if(!usr.canUnEquip(src))
+ to_chat(usr, "[src] appears stuck on you!")
+ return
+ switch(over_object.name)
+ if("r_hand")
+ usr.unEquip(src)
+ usr.put_in_r_hand(src)
+ if("l_hand")
+ usr.unEquip(src)
+ usr.put_in_l_hand(src)
+
+/obj/item/device/modular_computer/laptop/attack_hand(mob/user)
+ if(screen_on && isturf(loc))
+ return attack_self(user)
+
+ return ..()
+
+
+/obj/item/device/modular_computer/laptop/proc/try_toggle_open(mob/living/user)
+ if(issilicon(user))
+ return
+ if(!isturf(loc) && !ismob(loc)) // No opening it in backpack.
+ return
+ if(user.incapacitated() || !Adjacent(user))
+ return
+
+ toggle_open(user)
+
+
+/obj/item/device/modular_computer/laptop/AltClick(mob/user)
+ if(screen_on) // Close it.
+ try_toggle_open(user)
+ else
+ return ..()
+
+/obj/item/device/modular_computer/laptop/proc/toggle_open(mob/living/user=null)
+ if(screen_on)
+ to_chat(user, "You close \the [src].")
+ slowdown = initial(slowdown)
+ w_class = initial(w_class)
+ else
+ to_chat(user, "You open \the [src].")
+ slowdown = slowdown_open
+ w_class = w_class_open
+
+ screen_on = !screen_on
+ update_icon()
+
+
+
+// Laptop frame, starts empty and closed.
+/obj/item/device/modular_computer/laptop/buildable
+ start_open = 0
diff --git a/code/modules/modular_computers/computers/item/laptop_presets.dm b/code/modules/modular_computers/computers/item/laptop_presets.dm
new file mode 100644
index 00000000000..31519e70d6b
--- /dev/null
+++ b/code/modules/modular_computers/computers/item/laptop_presets.dm
@@ -0,0 +1,21 @@
+/obj/item/device/modular_computer/laptop/preset/New()
+ . = ..()
+ install_component(new /obj/item/weapon/computer_hardware/processor_unit/small)
+ install_component(new /obj/item/weapon/computer_hardware/battery(src, /obj/item/weapon/stock_parts/cell/computer))
+ install_component(new /obj/item/weapon/computer_hardware/hard_drive)
+ install_component(new /obj/item/weapon/computer_hardware/network_card)
+ install_programs()
+
+
+/obj/item/device/modular_computer/laptop/preset/proc/install_programs()
+ return
+
+
+/obj/item/device/modular_computer/laptop/preset/civillian
+ desc = "A low-end laptop often used for personal recreation."
+
+
+/obj/item/device/modular_computer/laptop/preset/civillian/install_programs()
+ var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD]
+ hard_drive.store_file(new/datum/computer_file/program/chatclient())
+ hard_drive.store_file(new/datum/computer_file/program/nttransfer())
\ No newline at end of file
diff --git a/code/modules/modular_computers/computers/item/processor.dm b/code/modules/modular_computers/computers/item/processor.dm
new file mode 100644
index 00000000000..3c81c43e824
--- /dev/null
+++ b/code/modules/modular_computers/computers/item/processor.dm
@@ -0,0 +1,74 @@
+// Held by /obj/machinery/modular_computer to reduce amount of copy-pasted code.
+/obj/item/device/modular_computer/processor
+ name = "processing unit"
+ desc = "You shouldn't see this. If you do, report it."
+ icon = null
+ icon_state = null
+ icon_state_unpowered = null
+ icon_state_menu = null
+ hardware_flag = 0
+
+ var/obj/machinery/modular_computer/machinery_computer = null
+
+/obj/item/device/modular_computer/processor/Destroy()
+ . = ..()
+ if(machinery_computer && (machinery_computer.cpu == src))
+ machinery_computer.cpu = null
+ machinery_computer = null
+
+/obj/item/device/modular_computer/processor/New(comp)
+ if(!comp || !istype(comp, /obj/machinery/modular_computer))
+ CRASH("Inapropriate type passed to obj/item/device/modular_computer/processor/New()! Aborting.")
+ return
+ // Obtain reference to machinery computer
+ all_components = list()
+ idle_threads = list()
+ machinery_computer = comp
+ machinery_computer.cpu = src
+ hardware_flag = machinery_computer.hardware_flag
+ max_hardware_size = machinery_computer.max_hardware_size
+ steel_sheet_cost = machinery_computer.steel_sheet_cost
+ obj_integrity = machinery_computer.obj_integrity
+ max_integrity = machinery_computer.max_integrity
+ integrity_failure = machinery_computer.integrity_failure
+ base_active_power_usage = machinery_computer.base_active_power_usage
+ base_idle_power_usage = machinery_computer.base_idle_power_usage
+
+/obj/item/device/modular_computer/processor/relay_qdel()
+ qdel(machinery_computer)
+
+/obj/item/device/modular_computer/processor/update_icon()
+ if(machinery_computer)
+ return machinery_computer.update_icon()
+
+// This thing is not meant to be used on it's own, get topic data from our machinery owner.
+//obj/item/device/modular_computer/processor/canUseTopic(user, state)
+// if(!machinery_computer)
+// return 0
+
+// return machinery_computer.canUseTopic(user, state)
+
+/obj/item/device/modular_computer/processor/shutdown_computer()
+ if(!machinery_computer)
+ return
+ ..()
+ machinery_computer.update_icon()
+ return
+
+/obj/item/device/modular_computer/processor/add_verb(path)
+ switch(path)
+ if(MC_CARD)
+ machinery_computer.verbs += /obj/machinery/modular_computer/proc/eject_id
+ if(MC_SDD)
+ machinery_computer.verbs += /obj/machinery/modular_computer/proc/eject_disk
+ if(MC_AI)
+ machinery_computer.verbs += /obj/machinery/modular_computer/proc/eject_card
+
+/obj/item/device/modular_computer/processor/remove_verb(path)
+ switch(path)
+ if(MC_CARD)
+ machinery_computer.verbs -= /obj/machinery/modular_computer/proc/eject_id
+ if(MC_SDD)
+ machinery_computer.verbs -= /obj/machinery/modular_computer/proc/eject_disk
+ if(MC_AI)
+ machinery_computer.verbs -= /obj/machinery/modular_computer/proc/eject_card
\ No newline at end of file
diff --git a/code/modules/modular_computers/computers/item/tablet.dm b/code/modules/modular_computers/computers/item/tablet.dm
new file mode 100644
index 00000000000..6a2b5674a5b
--- /dev/null
+++ b/code/modules/modular_computers/computers/item/tablet.dm
@@ -0,0 +1,12 @@
+/obj/item/device/modular_computer/tablet //Its called tablet for theme of 90ies but actually its a "big smartphone" sized
+ name = "tablet computer"
+ icon = 'icons/obj/modular_tablet.dmi'
+ icon_state = "tablet"
+ icon_state_unpowered = "tablet"
+ icon_state_powered = "tablet"
+ icon_state_menu = "menu"
+ hardware_flag = PROGRAM_TABLET
+ max_hardware_size = 1
+ w_class = WEIGHT_CLASS_SMALL
+ steel_sheet_cost = 1
+ slot_flags = SLOT_ID | SLOT_BELT
\ No newline at end of file
diff --git a/code/modules/modular_computers/computers/item/tablet_presets.dm b/code/modules/modular_computers/computers/item/tablet_presets.dm
new file mode 100644
index 00000000000..6ac9ed4063b
--- /dev/null
+++ b/code/modules/modular_computers/computers/item/tablet_presets.dm
@@ -0,0 +1,29 @@
+
+// This is literally the worst possible cheap tablet
+/obj/item/device/modular_computer/tablet/preset/cheap
+ desc = "A low-end tablet often seen among low ranked station personnel."
+
+/obj/item/device/modular_computer/tablet/preset/cheap/New()
+ . = ..()
+ install_component(new /obj/item/weapon/computer_hardware/processor_unit/small)
+ install_component(new /obj/item/weapon/computer_hardware/battery(src, /obj/item/weapon/stock_parts/cell/computer/micro))
+ install_component(new /obj/item/weapon/computer_hardware/hard_drive/small)
+ install_component(new /obj/item/weapon/computer_hardware/network_card)
+
+// Alternative version, an average one, for higher ranked positions mostly
+/obj/item/device/modular_computer/tablet/preset/advanced/New()
+ . = ..()
+ install_component(new /obj/item/weapon/computer_hardware/processor_unit/small)
+ install_component(new /obj/item/weapon/computer_hardware/battery(src, /obj/item/weapon/stock_parts/cell/computer))
+ install_component(new /obj/item/weapon/computer_hardware/hard_drive/small)
+ install_component(new /obj/item/weapon/computer_hardware/network_card)
+ install_component(new /obj/item/weapon/computer_hardware/card_slot)
+ install_component(new /obj/item/weapon/computer_hardware/printer/mini)
+
+/obj/item/device/modular_computer/tablet/preset/cargo/New()
+ . = ..()
+ install_component(new /obj/item/weapon/computer_hardware/processor_unit/small)
+ install_component(new /obj/item/weapon/computer_hardware/battery(src, /obj/item/weapon/stock_parts/cell/computer))
+ install_component(new /obj/item/weapon/computer_hardware/hard_drive/small)
+ install_component(new /obj/item/weapon/computer_hardware/network_card)
+ install_component(new /obj/item/weapon/computer_hardware/printer/mini)
diff --git a/code/modules/modular_computers/computers/machinery/console_presets.dm b/code/modules/modular_computers/computers/machinery/console_presets.dm
new file mode 100644
index 00000000000..3f9d3de11ca
--- /dev/null
+++ b/code/modules/modular_computers/computers/machinery/console_presets.dm
@@ -0,0 +1,75 @@
+/obj/machinery/modular_computer/console/preset
+ // Can be changed to give devices specific hardware
+ var/_has_id_slot = 0
+ var/_has_printer = 0
+ var/_has_battery = 0
+ var/_has_ai = 0
+
+/obj/machinery/modular_computer/console/preset/New()
+ . = ..()
+ if(!cpu)
+ return
+ cpu.install_component(new /obj/item/weapon/computer_hardware/processor_unit)
+
+ if(_has_id_slot)
+ cpu.install_component(new /obj/item/weapon/computer_hardware/card_slot)
+ if(_has_printer)
+ cpu.install_component(new /obj/item/weapon/computer_hardware/printer)
+ if(_has_battery)
+ cpu.install_component(new /obj/item/weapon/computer_hardware/battery(cpu, /obj/item/weapon/stock_parts/cell/computer/super))
+ if(_has_ai)
+ cpu.install_component(new /obj/item/weapon/computer_hardware/ai_slot)
+ install_programs()
+
+// Override in child types to install preset-specific programs.
+/obj/machinery/modular_computer/console/preset/proc/install_programs()
+ return
+
+
+
+// ===== ENGINEERING CONSOLE =====
+/obj/machinery/modular_computer/console/preset/engineering
+ console_department = "Engineering"
+ desc = "A stationary computer. This one comes preloaded with engineering programs."
+
+/obj/machinery/modular_computer/console/preset/engineering/install_programs()
+ var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
+ hard_drive.store_file(new/datum/computer_file/program/power_monitor())
+ hard_drive.store_file(new/datum/computer_file/program/alarm_monitor())
+
+// ===== RESEARCH CONSOLE =====
+/obj/machinery/modular_computer/console/preset/research
+ console_department = "Research"
+ desc = "A stationary computer. This one comes preloaded with research programs."
+ _has_ai = 1
+
+/obj/machinery/modular_computer/console/preset/research/install_programs()
+ var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
+ hard_drive.store_file(new/datum/computer_file/program/ntnetmonitor())
+ hard_drive.store_file(new/datum/computer_file/program/nttransfer())
+ hard_drive.store_file(new/datum/computer_file/program/chatclient())
+ hard_drive.store_file(new/datum/computer_file/program/aidiag())
+
+
+// ===== COMMAND CONSOLE =====
+/obj/machinery/modular_computer/console/preset/command
+ console_department = "Command"
+ desc = "A stationary computer. This one comes preloaded with command programs."
+ _has_id_slot = 1
+ _has_printer = 1
+
+/obj/machinery/modular_computer/console/preset/command/install_programs()
+ var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
+ hard_drive.store_file(new/datum/computer_file/program/chatclient())
+ hard_drive.store_file(new/datum/computer_file/program/card_mod())
+ hard_drive.store_file(new/datum/computer_file/program/comm())
+
+// ===== CIVILIAN CONSOLE =====
+/obj/machinery/modular_computer/console/preset/civilian
+ console_department = "Civilian"
+ desc = "A stationary computer. This one comes preloaded with generic programs."
+
+/obj/machinery/modular_computer/console/preset/civilian/install_programs()
+ var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
+ hard_drive.store_file(new/datum/computer_file/program/chatclient())
+ hard_drive.store_file(new/datum/computer_file/program/nttransfer())
\ No newline at end of file
diff --git a/code/modules/modular_computers/computers/machinery/modular_computer.dm b/code/modules/modular_computers/computers/machinery/modular_computer.dm
new file mode 100644
index 00000000000..9e07fc19ddb
--- /dev/null
+++ b/code/modules/modular_computers/computers/machinery/modular_computer.dm
@@ -0,0 +1,158 @@
+// Global var to track modular computers
+var/list/global_modular_computers = list()
+
+// Modular Computer - device that runs various programs and operates with hardware
+// DO NOT SPAWN THIS TYPE. Use /laptop/ or /console/ instead.
+/obj/machinery/modular_computer
+ name = "modular computer"
+ desc = "An advanced computer."
+
+ use_power = 1
+ idle_power_usage = 5
+ var/hardware_flag = 0 // A flag that describes this device type
+ var/last_power_usage = 0 // Power usage during last tick
+
+ // Modular computers can run on various devices. Each DEVICE (Laptop, Console, Tablet,..)
+ // must have it's own DMI file. Icon states must be called exactly the same in all files, but may look differently
+ // If you create a program which is limited to Laptops and Consoles you don't have to add it's icon_state overlay for Tablets too, for example.
+
+ icon = null
+ icon_state = null
+ var/icon_state_unpowered = null // Icon state when the computer is turned off.
+ var/icon_state_powered = null // Icon state when the computer is turned on.
+ var/screen_icon_state_menu = "menu" // Icon state overlay when the computer is turned on, but no program is loaded that would override the screen.
+ var/screen_icon_screensaver = "standby" // Icon state overlay when the computer is powered, but not 'switched on'.
+ var/max_hardware_size = 0 // Maximal hardware size. Currently, tablets have 1, laptops 2 and consoles 3. Limits what hardware types can be installed.
+ var/steel_sheet_cost = 10 // Amount of steel sheets refunded when disassembling an empty frame of this computer.
+ var/light_strength = 0 // Light luminosity when turned on
+ var/base_active_power_usage = 100 // Power usage when the computer is open (screen is active) and can be interacted with. Remember hardware can use power too.
+ var/base_idle_power_usage = 10 // Power usage when the computer is idle and screen is off (currently only applies to laptops)
+
+ var/obj_integrity = 300
+ var/integrity_failure = 150
+ var/max_integrity = 300
+
+ var/obj/item/device/modular_computer/processor/cpu = null // CPU that handles most logic while this type only handles power and other specific things.
+
+/obj/machinery/modular_computer/New()
+ ..()
+ cpu = new(src)
+ cpu.physical = src
+ global_modular_computers.Add(src)
+
+/obj/machinery/modular_computer/Destroy()
+ QDEL_NULL(cpu)
+ return ..()
+
+/obj/machinery/modular_computer/attack_ghost(mob/dead/observer/user)
+ if(cpu)
+ cpu.attack_ghost(user)
+
+/obj/machinery/modular_computer/emag_act(mob/user)
+ return cpu ? cpu.emag_act(user) : 1
+
+/obj/machinery/modular_computer/update_icon()
+ overlays.Cut()
+ icon_state = icon_state_powered
+
+ if(!cpu || !cpu.enabled)
+ if (!(stat & NOPOWER) && (cpu && cpu.use_power()))
+ overlays += screen_icon_screensaver
+ else
+ icon_state = icon_state_unpowered
+ set_light(0)
+ else
+ set_light(light_strength)
+ if(cpu.active_program)
+ overlays += cpu.active_program.program_icon_state ? cpu.active_program.program_icon_state : screen_icon_state_menu
+ else
+ overlays += screen_icon_state_menu
+
+ if(cpu && cpu.obj_integrity <= cpu.integrity_failure)
+ overlays += "bsod"
+ overlays += "broken"
+
+// Eject ID card from computer, if it has ID slot with card inside.
+/obj/machinery/modular_computer/proc/eject_id()
+ set name = "Eject ID"
+ set category = "Object"
+
+ if(cpu)
+ cpu.eject_id()
+
+// Eject ID card from computer, if it has ID slot with card inside.
+/obj/machinery/modular_computer/proc/eject_disk()
+ set name = "Eject Data Disk"
+ set category = "Object"
+
+ if(cpu)
+ cpu.eject_disk()
+
+/obj/machinery/modular_computer/proc/eject_card()
+ set name = "Eject Intellicard"
+ set category = "Object"
+ set src in view(1)
+
+ if(cpu)
+ cpu.eject_card()
+
+/obj/machinery/modular_computer/AltClick(mob/user)
+ if(cpu)
+ cpu.AltClick(user)
+
+// On-click handling. Turns on the computer if it's off and opens the GUI.
+/obj/machinery/modular_computer/attack_hand(mob/user)
+ if(cpu)
+ cpu.attack_self(user) // CPU is an item, that's why we route attack_hand to attack_self
+
+// Process currently calls handle_power(), may be expanded in future if more things are added.
+/obj/machinery/modular_computer/process()
+ if(cpu)
+ // Keep names in sync.
+ cpu.name = src.name
+ cpu.process()
+
+// Used in following function to reduce copypaste
+/obj/machinery/modular_computer/proc/power_failure(malfunction = 0)
+ var/obj/item/weapon/computer_hardware/battery/battery_module = cpu.all_components[MC_CELL]
+ if(cpu && cpu.enabled) // Shut down the computer
+ visible_message("\The [src]'s screen flickers [battery_module ? "\"BATTERY [malfunction ? "MALFUNCTION" : "CRITICAL"]\"" : "\"EXTERNAL POWER LOSS\""] warning as it shuts down unexpectedly.")
+ if(cpu)
+ cpu.shutdown_computer(0)
+ stat |= NOPOWER
+ update_icon()
+
+
+// Modular computers can have battery in them, we handle power in previous proc, so prevent this from messing it up for us.
+/obj/machinery/modular_computer/power_change()
+ if(cpu && cpu.use_power()) // If MC_CPU still has a power source, PC wouldn't go offline.
+ stat &= ~NOPOWER
+ update_icon()
+ return
+ ..()
+ update_icon()
+
+/obj/machinery/modular_computer/attackby(obj/item/weapon/W, mob/user)
+ if(cpu)
+ return cpu.attackby(W, user)
+ return ..()
+
+
+// Stronger explosions cause serious damage to internal components
+// Minor explosions are mostly mitigitated by casing.
+/obj/machinery/modular_computer/ex_act(severity)
+ if(cpu)
+ cpu.ex_act(severity)
+ ..()
+
+// EMPs are similar to explosions, but don't cause physical damage to the casing. Instead they screw up the components
+/obj/machinery/modular_computer/emp_act(severity)
+ if(cpu)
+ cpu.emp_act(severity)
+
+// "Stun" weapons can cause minor damage to components (short-circuits?)
+// "Burn" damage is equally strong against internal components and exterior casing
+// "Brute" damage mostly damages the casing.
+/obj/machinery/modular_computer/bullet_act(obj/item/projectile/Proj)
+ if(cpu)
+ cpu.bullet_act(Proj)
diff --git a/code/modules/modular_computers/computers/machinery/modular_console.dm b/code/modules/modular_computers/computers/machinery/modular_console.dm
new file mode 100644
index 00000000000..2c330913353
--- /dev/null
+++ b/code/modules/modular_computers/computers/machinery/modular_console.dm
@@ -0,0 +1,54 @@
+/obj/machinery/modular_computer/console
+ name = "console"
+ desc = "A stationary computer."
+
+ icon = 'icons/obj/modular_console.dmi'
+ icon_state = "console"
+ icon_state_powered = "console"
+ icon_state_unpowered = "console-off"
+ screen_icon_state_menu = "menu"
+ hardware_flag = PROGRAM_CONSOLE
+ anchored = 1
+ density = 1
+ base_idle_power_usage = 100
+ base_active_power_usage = 500
+ max_hardware_size = 4
+ steel_sheet_cost = 10
+ light_strength = 2
+ obj_integrity = 300
+ max_integrity = 300
+ integrity_failure = 150
+
+ var/console_department = "" // Used in New() to set network tag according to our area.
+ var/components = TRUE // Install basic components?
+
+/obj/machinery/modular_computer/console/buildable
+ components = FALSE
+
+/obj/machinery/modular_computer/console/New()
+ ..()
+ var/obj/item/weapon/computer_hardware/battery/battery_module = cpu.all_components[MC_CELL]
+ if(battery_module)
+ qdel(battery_module)
+
+ if(components)
+ var/obj/item/weapon/computer_hardware/network_card/wired/network_card = new()
+
+ cpu.install_component(network_card)
+ cpu.install_component(new /obj/item/weapon/computer_hardware/recharger/APC)
+ cpu.install_component(new /obj/item/weapon/computer_hardware/hard_drive/super) // Consoles generally have better HDDs due to lower space limitations
+
+ var/area/A = get_area(src)
+ // Attempts to set this console's tag according to our area. Since some areas have stuff like "XX - YY" in their names we try to remove that too.
+ if(A && console_department)
+ network_card.identification_string = replacetext(replacetext(replacetext("[A.name] [console_department] Console", " ", "_"), "-", ""), "__", "_") // Replace spaces with "_"
+ else if(A)
+ network_card.identification_string = replacetext(replacetext(replacetext("[A.name] Console", " ", "_"), "-", ""), "__", "_")
+ else if(console_department)
+ network_card.identification_string = replacetext(replacetext(replacetext("[console_department] Console", " ", "_"), "-", ""), "__", "_")
+ else
+ network_card.identification_string = "Unknown Console"
+
+ if(cpu)
+ cpu.screen_on = 1
+ update_icon()
\ No newline at end of file
diff --git a/code/modules/modular_computers/documentation.md b/code/modules/modular_computers/documentation.md
new file mode 100644
index 00000000000..88d8602729d
--- /dev/null
+++ b/code/modules/modular_computers/documentation.md
@@ -0,0 +1,45 @@
+
+
+#Modular computer programs
+Ok. so a quick rundown on how to make a program. This is kind of a shitty documentation, but oh well I was asked to.
+
+
+## Base setup
+This is how the base program is setup. the rest is mostly tgui stuff. I'll use the ntnetmonitor as a base
+
+
+```DM
+/datum/computer_file/program/ntnetmonitor
+ filename = "ntmonitor" //This is obviously the name of the file itself. not much to be said
+ filedesc = "NTNet Diagnostics and Monitoring" // This is sort of the official name. it's what shows up on the main menu
+ program_icon_state = "comm_monitor" // This is what the screen will look like when the program is active
+ extended_desc = "This program is a dummy. // This is a sort of a description, visible when looking on the ntnet
+ size = 12 // size of the program. Big programs need more hard drive space. Don't make it too big though.
+ requires_ntnet = 1 // If this is set, the program will not run without an ntnet connection, and will close if the connection is lost. Mainly for primarily online programs.
+ required_access = access_network //This is access required to run the program itself. ONLY SET THIS FOR SUPER SECURE SHIT. This also acts as transfer_access as well.
+ transfer_access = access_change_ids // This is the access needed to download from ntnet or host on the ptp program. This is what you want to use most of the time.
+ available_on_ntnet = 1 //If it's available to download on ntnet. pretty self explanatory.
+ available_on_syndinet = 0 // ditto but on emagged syndie net. Use this for antag programs
+ usage_flags = PROGRAM_ALL // Bitflags (PROGRAM_CONSOLE, PROGRAM_LAPTOP, PROGRAM_TABLET combination) or PROGRAM_ALL
+ //^^- The comment above sorta explains it. Use this to limit what kind of machines can run the program. For example, comms program should be limited to consoles and laptops.
+ var/ui_header = "downloader_finished.gif" //This one is kinda cool. If you have the program minimized, this will show up in the header of the computer screen.
+ //you can even have the program change what the header is based on the situation! see alarm.dm for an example.
+```
+
+##Preinstalls
+Now. for pre-installing stuff.
+
+Primarily done for consoles, there's an install_programs() proc in the console presets file in the machines folder.
+
+for example, the command console one.
+
+```DM
+/obj/machinery/modular_computer/console/preset/command/install_programs()
+ cpu.hard_drive.store_file(new/datum/computer_file/program/chatclient())
+ cpu.hard_drive.store_file(new/datum/computer_file/program/card_mod())
+```
+Basically, you want to do cpu.hard_drive.store_file(new/*program path here*()) and put it in the subtype's install_programs().
+Probably pretty self explanatory, but just in case.
+
+Will probably be expanded when new features come around or I get asked to mention something.
+
diff --git a/code/modules/modular_computers/file_system/computer_file.dm b/code/modules/modular_computers/file_system/computer_file.dm
new file mode 100644
index 00000000000..40860cb58e0
--- /dev/null
+++ b/code/modules/modular_computers/file_system/computer_file.dm
@@ -0,0 +1,39 @@
+var/global/file_uid = 0
+
+/datum/computer_file
+ var/filename = "NewFile" // Placeholder. No spacebars
+ var/filetype = "XXX" // File full names are [filename].[filetype] so like NewFile.XXX in this case
+ var/size = 1 // File size in GQ. Integers only!
+ var/obj/item/weapon/computer_hardware/hard_drive/holder // Holder that contains this file.
+ var/unsendable = 0 // Whether the file may be sent to someone via NTNet transfer or other means.
+ var/undeletable = 0 // Whether the file may be deleted. Setting to 1 prevents deletion/renaming/etc.
+ var/uid // UID of this file
+
+/datum/computer_file/New()
+ ..()
+ uid = file_uid
+ file_uid++
+
+/datum/computer_file/Destroy()
+ if(!holder)
+ return ..()
+
+ holder.remove_file(src)
+ // holder.holder is the computer that has drive installed. If we are Destroy()ing program that's currently running kill it.
+ if(holder.holder && holder.holder.active_program == src)
+ holder.holder.kill_program(forced = TRUE)
+ holder = null
+ return ..()
+
+// Returns independent copy of this file.
+/datum/computer_file/proc/clone(rename = 0)
+ var/datum/computer_file/temp = new type
+ temp.unsendable = unsendable
+ temp.undeletable = undeletable
+ temp.size = size
+ if(rename)
+ temp.filename = filename + "(Copy)"
+ else
+ temp.filename = filename
+ temp.filetype = filetype
+ return temp
\ No newline at end of file
diff --git a/code/modules/modular_computers/file_system/data.dm b/code/modules/modular_computers/file_system/data.dm
new file mode 100644
index 00000000000..32ef6f53dd1
--- /dev/null
+++ b/code/modules/modular_computers/file_system/data.dm
@@ -0,0 +1,20 @@
+// /data/ files store data in string format.
+// They don't contain other logic for now.
+/datum/computer_file/data
+ var/stored_data = "" // Stored data in string format.
+ filetype = "DAT"
+ var/block_size = 250
+ var/do_not_edit = 0 // Whether the user will be reminded that the file probably shouldn't be edited.
+
+/datum/computer_file/data/clone()
+ var/datum/computer_file/data/temp = ..()
+ temp.stored_data = stored_data
+ return temp
+
+// Calculates file size from amount of characters in saved string
+/datum/computer_file/data/proc/calculate_size()
+ size = max(1, round(length(stored_data) / block_size))
+
+/datum/computer_file/data/logfile
+ filetype = "LOG"
+
diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm
new file mode 100644
index 00000000000..8d917e4cb81
--- /dev/null
+++ b/code/modules/modular_computers/file_system/program.dm
@@ -0,0 +1,200 @@
+// /program/ files are executable programs that do things.
+/datum/computer_file/program
+ filetype = "PRG"
+ filename = "UnknownProgram" // File name. FILE NAME MUST BE UNIQUE IF YOU WANT THE PROGRAM TO BE DOWNLOADABLE FROM NTNET!
+ var/required_access = null // List of required accesses to *run* the program.
+ var/transfer_access = null // List of required access to download or file host the program
+ var/program_state = PROGRAM_STATE_KILLED// PROGRAM_STATE_KILLED or PROGRAM_STATE_BACKGROUND or PROGRAM_STATE_ACTIVE - specifies whether this program is running.
+ var/obj/item/device/modular_computer/computer // Device that runs this program.
+ var/filedesc = "Unknown Program" // User-friendly name of this program.
+ var/extended_desc = "N/A" // Short description of this program's function.
+ var/program_icon_state = null // Program-specific screen icon state
+ var/requires_ntnet = 0 // Set to 1 for program to require nonstop NTNet connection to run. If NTNet connection is lost program crashes.
+ var/requires_ntnet_feature = 0 // Optional, if above is set to 1 checks for specific function of NTNet (currently NTNET_SOFTWAREDOWNLOAD, NTNET_PEERTOPEER, NTNET_SYSTEMCONTROL and NTNET_COMMUNICATION)
+ var/ntnet_status = 1 // NTNet status, updated every tick by computer running this program. Don't use this for checks if NTNet works, computers do that. Use this for calculations, etc.
+ var/usage_flags = PROGRAM_ALL // Bitflags (PROGRAM_CONSOLE, PROGRAM_LAPTOP, PROGRAM_TABLET combination) or PROGRAM_ALL
+ var/network_destination = null // Optional string that describes what NTNet server/system this program connects to. Used in default logging.
+ var/available_on_ntnet = 1 // Whether the program can be downloaded from NTNet. Set to 0 to disable.
+ var/available_on_syndinet = 0 // Whether the program can be downloaded from SyndiNet (accessible via emagging the computer). Set to 1 to enable.
+ var/ui_header = null // Example: "something.gif" - a header image that will be rendered in computer's UI when this program is running at background. Images are taken from /icons/program_icons. Be careful not to use too large images!
+
+/datum/computer_file/program/New(obj/item/device/modular_computer/comp = null)
+ ..()
+ if(comp && istype(comp))
+ computer = comp
+
+/datum/computer_file/program/Destroy()
+ computer = null
+ . = ..()
+
+/datum/computer_file/program/clone()
+ var/datum/computer_file/program/temp = ..()
+ temp.required_access = required_access
+ temp.filedesc = filedesc
+ temp.program_icon_state = program_icon_state
+ temp.requires_ntnet = requires_ntnet
+ temp.requires_ntnet_feature = requires_ntnet_feature
+ temp.usage_flags = usage_flags
+ return temp
+
+// Relays icon update to the computer.
+/datum/computer_file/program/proc/update_computer_icon()
+ if(computer)
+ computer.update_icon()
+
+// Attempts to create a log in global ntnet datum. Returns 1 on success, 0 on fail.
+/datum/computer_file/program/proc/generate_network_log(text)
+ if(computer)
+ return computer.add_log(text)
+ return 0
+
+/datum/computer_file/program/proc/is_supported_by_hardware(hardware_flag = 0, loud = 0, mob/user = null)
+ if(!(hardware_flag & usage_flags))
+ if(loud && computer && user)
+ to_chat(user, "\The [computer] flashes an \"Hardware Error - Incompatible software\" warning.")
+ return 0
+ return 1
+
+/datum/computer_file/program/proc/get_signal(specific_action = 0)
+ if(computer)
+ return computer.get_ntnet_status(specific_action)
+ return 0
+
+// Called by Process() on device that runs us, once every tick.
+/datum/computer_file/program/proc/process_tick()
+ return 1
+
+// Check if the user can run program. Only humans can operate computer. Automatically called in run_program()
+// User has to wear their ID for ID Scan to work.
+// Can also be called manually, with optional parameter being access_to_check to scan the user's ID
+/datum/computer_file/program/proc/can_run(mob/user, loud = 0, access_to_check, transfer = 0)
+ // Defaults to required_access
+ if(!access_to_check)
+ if(transfer && transfer_access)
+ access_to_check = transfer_access
+ else
+ access_to_check = required_access
+ if(!access_to_check) // No required_access, allow it.
+ return 1
+
+ if(!transfer && computer && computer.emagged) //emags can bypass the execution locks but not the download ones.
+ return 1
+
+ if(user.can_admin_interact())
+ return 1
+
+ if(issilicon(user))
+ return 1
+
+ if(ishuman(user))
+ var/obj/item/weapon/card/id/D
+ var/obj/item/weapon/computer_hardware/card_slot/card_slot
+ if(computer && card_slot)
+ card_slot = computer.all_components[MC_CARD]
+ D = card_slot.GetID()
+ var/mob/living/carbon/human/h = user
+ var/obj/item/weapon/card/id/I = h.get_idcard()
+ var/obj/item/weapon/card/id/C = h.get_active_hand()
+ if(C)
+ C = C.GetID()
+ if(!(C && istype(C)))
+ C = null
+
+ if(!I && !C && !D)
+ if(loud)
+ to_chat(user, "\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.")
+ return 0
+
+ if(I)
+ if(access_to_check in I.GetAccess())
+ return 1
+ else if(C)
+ if(access_to_check in C.GetAccess())
+ return 1
+ else if(D)
+ if(access_to_check in D.GetAccess())
+ return 1
+ if(loud)
+ to_chat(user, "\The [computer] flashes an \"Access Denied\" warning.")
+ return 0
+
+// This attempts to retrieve header data for UIs. If implementing completely new device of different type than existing ones
+// always include the device here in this proc. This proc basically relays the request to whatever is running the program.
+/datum/computer_file/program/proc/get_header_data()
+ if(computer)
+ return computer.get_header_data()
+ return list()
+
+// This is performed on program startup. May be overriden to add extra logic. Remember to include ..() call. Return 1 on success, 0 on failure.
+// When implementing new program based device, use this to run the program.
+/datum/computer_file/program/proc/run_program(mob/living/user)
+ if(can_run(user, 1))
+ if(requires_ntnet && network_destination)
+ generate_network_log("Connection opened to [network_destination].")
+ program_state = PROGRAM_STATE_ACTIVE
+ return 1
+ return 0
+
+// Use this proc to kill the program. Designed to be implemented by each program if it requires on-quit logic, such as the NTNRC client.
+/datum/computer_file/program/proc/kill_program(forced = FALSE)
+ program_state = PROGRAM_STATE_KILLED
+ computer.update_icon()
+ if(network_destination)
+ generate_network_log("Connection to [network_destination] closed.")
+ return 1
+
+// This is called every tick when the program is enabled. Ensure you do parent call if you override it. If parent returns 1 continue with UI initialisation.
+
+/datum/computer_file/program/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ if(program_state != PROGRAM_STATE_ACTIVE) // Our program was closed. Close the ui if it exists.
+ return computer.ui_interact(user)
+ return 1
+
+
+// CONVENTIONS, READ THIS WHEN CREATING NEW PROGRAM AND OVERRIDING THIS PROC:
+// Topic calls are automagically forwarded from NanoModule this program contains.
+// Calls beginning with "PRG_" are reserved for programs handling.
+// Calls beginning with "PC_" are reserved for computer handling (by whatever runs the program)
+// ALWAYS INCLUDE PARENT CALL ..() OR DIE IN FIRE.
+/datum/computer_file/program/Topic(href, list/href_list)
+ if(..())
+ return 1
+
+ var/datum/nanoui/ui = nanomanager.get_open_ui(usr, src, "main")
+
+ if(computer)
+ switch(href_list["action"])
+ if("PC_exit")
+ computer.kill_program()
+ ui.close()
+ return 1
+ if("PC_shutdown")
+ computer.shutdown_computer()
+ ui.close()
+ return 1
+ if("PC_minimize")
+ var/mob/user = usr
+ if(!computer.active_program || !computer.all_components[MC_CPU])
+ return
+
+ computer.idle_threads.Add(computer.active_program)
+ program_state = PROGRAM_STATE_BACKGROUND // Should close any existing UIs
+
+ computer.active_program = null
+ computer.update_icon()
+ ui.close()
+
+ if(user && istype(user))
+ computer.ui_interact(user) // Re-open the UI on this computer. It should show the main screen now.
+
+
+/datum/computer_file/program/nano_host()
+ if(computer.physical)
+ return computer.physical
+ else
+ return computer
+
+/datum/computer_file/program/CanUseTopic(mob/user)
+ if(program_state != PROGRAM_STATE_ACTIVE) // Our program was closed. Close the ui if it exists.
+ return STATUS_CLOSE
+ return ..()
diff --git a/code/modules/modular_computers/file_system/program_events.dm b/code/modules/modular_computers/file_system/program_events.dm
new file mode 100644
index 00000000000..279d646cfd7
--- /dev/null
+++ b/code/modules/modular_computers/file_system/program_events.dm
@@ -0,0 +1,18 @@
+// Events are sent to the program by the computer.
+// Always include a parent call when overriding an event.
+
+// Called when the ID card is removed from computer. ID is removed AFTER this proc.
+/datum/computer_file/program/proc/event_idremoved(background, slot)
+ return
+
+// Called when the computer fails due to power loss. Override when program wants to specifically react to power loss.
+/datum/computer_file/program/proc/event_powerfailure(background)
+ kill_program(forced = TRUE)
+
+// Called when the network connectivity fails. Computer does necessary checks and only calls this when requires_ntnet_feature and similar variables are not met.
+/datum/computer_file/program/proc/event_networkfailure(background)
+ kill_program(forced = TRUE)
+ if(background)
+ computer.visible_message("\The [computer]'s screen displays an \"Process [filename].[filetype] (PID [rand(100,999)]) terminated - Network Error\" error")
+ else
+ computer.visible_message("\The [computer]'s screen briefly freezes and then shows \"NETWORK ERROR - NTNet connection lost. Please retry. If problem persists contact your system administrator.\" error.")
diff --git a/code/modules/modular_computers/file_system/programs/antagonist/dos.dm b/code/modules/modular_computers/file_system/programs/antagonist/dos.dm
new file mode 100644
index 00000000000..feaee3be63d
--- /dev/null
+++ b/code/modules/modular_computers/file_system/programs/antagonist/dos.dm
@@ -0,0 +1,103 @@
+/datum/computer_file/program/ntnet_dos
+ filename = "ntn_dos"
+ filedesc = "DoS Traffic Generator"
+ program_icon_state = "hostile"
+ extended_desc = "This advanced script can perform denial of service attacks against NTNet quantum relays. The system administrator will probably notice this. Multiple devices can run this program together against same relay for increased effect"
+ size = 20
+ requires_ntnet = 1
+ available_on_ntnet = 0
+ available_on_syndinet = 1
+ var/obj/machinery/ntnet_relay/target = null
+ var/dos_speed = 0
+ var/error = ""
+ var/executed = 0
+
+/datum/computer_file/program/ntnet_dos/process_tick()
+ dos_speed = 0
+ switch(ntnet_status)
+ if(1)
+ dos_speed = NTNETSPEED_LOWSIGNAL * 10
+ if(2)
+ dos_speed = NTNETSPEED_HIGHSIGNAL * 10
+ if(3)
+ dos_speed = NTNETSPEED_ETHERNET * 10
+ if(target && executed)
+ target.dos_overload += dos_speed
+ if(target.inoperable())
+ target.dos_sources.Remove(src)
+ target = null
+ error = "Connection to destination relay lost."
+
+/datum/computer_file/program/ntnet_dos/kill_program(forced = FALSE)
+ if(target)
+ target.dos_sources.Remove(src)
+ target = null
+ executed = 0
+ ..()
+
+/datum/computer_file/program/ntnet_dos/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers)
+ assets.send(user)
+ ui = new(user, src, ui_key, "ntnet_dos.tmpl", "DoS Traffic Generator", 575, 250)
+ ui.set_auto_update(1)
+ ui.set_layout_key("program")
+ ui.open()
+
+
+/datum/computer_file/program/ntnet_dos/Topic(href, list/href_list)
+ if(..())
+ return 1
+ switch(href_list["action"])
+ if("PRG_target_relay")
+ for(var/obj/machinery/ntnet_relay/R in ntnet_global.relays)
+ if("[R.uid]" == href_list["targid"])
+ target = R
+ return 1
+ if("PRG_reset")
+ if(target)
+ target.dos_sources.Remove(src)
+ target = null
+ executed = 0
+ error = ""
+ return 1
+ if("PRG_execute")
+ if(target)
+ executed = 1
+ target.dos_sources.Add(src)
+ if(ntnet_global.intrusion_detection_enabled)
+ var/obj/item/weapon/computer_hardware/network_card/network_card = computer.all_components[MC_NET]
+ ntnet_global.add_log("IDS WARNING - Excess traffic flood targeting relay [target.uid] detected from device: [network_card.get_network_tag()]")
+ ntnet_global.intrusion_detection_alarm = 1
+ return 1
+
+/datum/computer_file/program/ntnet_dos/ui_data(mob/user)
+ if(!ntnet_global)
+ return
+
+ var/list/data = get_header_data()
+
+ if(error)
+ data["error"] = error
+ else if(target && executed)
+ data["target"] = 1
+ data["speed"] = dos_speed
+
+ // This is mostly visual, generate some strings of 1s and 0s
+ // Probability of 1 is equal of completion percentage of DoS attack on this relay.
+ // Combined with UI updates this adds quite nice effect to the UI
+ var/percentage = target.dos_overload * 100 / target.dos_capacity
+ data["dos_strings"] = list()
+ for(var/j, j<10, j++)
+ var/string = ""
+ for(var/i, i<20, i++)
+ string = "[string][prob(percentage)]"
+ data["dos_strings"] += list(list("nums" = string))
+ else
+ data["relays"] = list()
+ for(var/obj/machinery/ntnet_relay/R in ntnet_global.relays)
+ data["relays"] += list(list("id" = R.uid))
+ data["focus"] = target ? target.uid : null
+
+ return data
\ No newline at end of file
diff --git a/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm b/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm
new file mode 100644
index 00000000000..148766ef59d
--- /dev/null
+++ b/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm
@@ -0,0 +1,78 @@
+/datum/computer_file/program/revelation
+ filename = "revelation"
+ filedesc = "Revelation"
+ program_icon_state = "hostile"
+ extended_desc = "This virus can destroy hard drive of system it is executed on. It may be obfuscated to look like another non-malicious program. Once armed, it will destroy the system upon next execution."
+ size = 13
+ requires_ntnet = 0
+ available_on_ntnet = 0
+ available_on_syndinet = 1
+ var/armed = 0
+
+/datum/computer_file/program/revelation/run_program(var/mob/living/user)
+ . = ..(user)
+ if(armed)
+ activate()
+
+/datum/computer_file/program/revelation/proc/activate()
+ if(computer)
+ computer.visible_message("\The [computer]'s screen brightly flashes and loud electrical buzzing is heard.")
+ computer.enabled = 0
+ computer.update_icon()
+ var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD]
+ var/obj/item/weapon/computer_hardware/battery/battery_module = computer.all_components[MC_CELL]
+ var/obj/item/weapon/computer_hardware/recharger/recharger = computer.all_components[MC_CHARGE]
+ qdel(hard_drive)
+ computer.take_damage(25, BRUTE, 0, 0)
+ if(battery_module && prob(25))
+ qdel(battery_module)
+ computer.visible_message("\The [computer]'s battery explodes in rain of sparks.")
+ var/datum/effect/system/spark_spread/spark_system = new /datum/effect/system/spark_spread()
+ spark_system.set_up(5, 0, computer.loc)
+ spark_system.start()
+
+ if(recharger && prob(50))
+ qdel(recharger)
+ computer.visible_message("\The [computer]'s recharger explodes in rain of sparks.")
+ var/datum/effect/system/spark_spread/spark_system = new /datum/effect/system/spark_spread()
+ spark_system.set_up(5, 0, computer.loc)
+ spark_system.start()
+
+
+/datum/computer_file/program/revelation/Topic(href, list/href_list)
+ if(..())
+ return 1
+ switch(href_list["action"])
+ if("PRG_arm")
+ armed = !armed
+ if("PRG_activate")
+ activate()
+ if("PRG_obfuscate")
+ var/mob/living/user = usr
+ var/newname = sanitize(input(user, "Enter new program name: "))
+ if(!newname)
+ return
+ filedesc = newname
+
+
+/datum/computer_file/program/revelation/clone()
+ var/datum/computer_file/program/revelation/temp = ..()
+ temp.armed = armed
+ return temp
+
+/datum/computer_file/program/revelation/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers)
+ assets.send(user)
+ ui = new(user, src, ui_key, "revelation.tmpl", "Revelation Virus", 575, 250)
+ ui.set_auto_update(1)
+ ui.set_layout_key("program")
+ ui.open()
+
+/datum/computer_file/program/revelation/ui_data(mob/user)
+ var/list/data = get_header_data()
+
+ data["armed"] = armed
+
+ return data
\ No newline at end of file
diff --git a/code/modules/modular_computers/file_system/programs/command/card.dm b/code/modules/modular_computers/file_system/programs/command/card.dm
new file mode 100644
index 00000000000..8cd1043bea6
--- /dev/null
+++ b/code/modules/modular_computers/file_system/programs/command/card.dm
@@ -0,0 +1,413 @@
+/datum/computer_file/program/card_mod
+ filename = "cardmod"
+ filedesc = "ID card modification program"
+ program_icon_state = "id"
+ extended_desc = "Program for programming employee ID cards to access parts of the station."
+ transfer_access = access_change_ids
+ requires_ntnet = 0
+ size = 8
+ var/is_centcom = 0
+ var/mode = 0
+ var/printing = 0
+
+ //Cooldown for closing positions in seconds
+ //if set to -1: No cooldown... probably a bad idea
+ //if set to 0: Not able to close "original" positions. You can only close positions that you have opened before
+ var/change_position_cooldown = 60
+ //Jobs you cannot open new positions for
+ var/list/blacklisted = list(
+ /datum/job/ai,
+ /datum/job/cyborg,
+ /datum/job/captain,
+ /datum/job/hop,
+ /datum/job/hos,
+ /datum/job/chief_engineer,
+ /datum/job/rd,
+ /datum/job/cmo,
+ /datum/job/judge,
+ /datum/job/blueshield,
+ /datum/job/nanotrasenrep,
+ /datum/job/pilot,
+ /datum/job/brigdoc,
+ /datum/job/mechanic,
+ /datum/job/barber,
+ /datum/job/chaplain,
+ /datum/job/ntnavyofficer,
+ /datum/job/ntspecops,
+ /datum/job/civilian
+ )
+
+ //The scaling factor of max total positions in relation to the total amount of people on board the station in %
+ var/max_relative_positions = 30 //30%: Seems reasonable, limit of 6 @ 20 players
+
+ //This is used to keep track of opened positions for jobs to allow instant closing
+ //Assoc array: "JobName" = (int)
+ var/list/opened_positions = list()
+
+/datum/computer_file/program/card_mod/proc/is_authenticated(var/mob/user)
+ if(user.can_admin_interact())
+ return 1
+ if(computer)
+ var/obj/item/weapon/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD]
+ if(card_slot)
+ var/obj/item/weapon/card/id/auth_card = card_slot.stored_card2
+ if(auth_card)
+ return check_access(auth_card)
+ return 0
+
+/datum/computer_file/program/card_mod/proc/check_access(obj/item/I)
+ if(access_change_ids in I.GetAccess())
+ return 1
+ return 0
+
+/datum/computer_file/program/card_mod/proc/get_target_rank()
+ if(computer)
+ var/obj/item/weapon/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD]
+ if(card_slot)
+ var/obj/item/weapon/card/id/id_card = card_slot.stored_card
+ if(id_card && id_card.assignment)
+ return id_card.assignment
+ return "Unassigned"
+
+/datum/computer_file/program/card_mod/proc/format_job_slots()
+ var/list/formatted = list()
+ for(var/datum/job/job in job_master.occupations)
+ if(job_blacklisted(job))
+ continue
+ formatted.Add(list(list(
+ "title" = job.title,
+ "current_positions" = job.current_positions,
+ "total_positions" = job.total_positions,
+ "can_open" = can_open_job(job),
+ "can_close" = can_close_job(job))))
+
+ return formatted
+
+/datum/computer_file/program/card_mod/proc/format_card_skins(list/card_skins)
+ var/list/formatted = list()
+ for(var/skin in card_skins)
+ formatted.Add(list(list(
+ "display_name" = get_skin_desc(skin),
+ "skin" = skin)))
+
+ return formatted
+
+
+/datum/computer_file/program/card_mod/proc/job_blacklisted(datum/job/job)
+ return (job.type in blacklisted)
+
+
+//Logic check for if you can open the job
+/datum/computer_file/program/card_mod/proc/can_open_job(datum/job/job)
+ if(job)
+ if(!job_blacklisted(job))
+ if((job.total_positions <= player_list.len * (max_relative_positions / 100)))
+ var/delta = (world.time / 10) - time_last_changed_position
+ if((change_position_cooldown < delta) || (opened_positions[job.title] < 0))
+ return 1
+ return -2
+ return -1
+ return 0
+
+//Logic check for if you can close the job
+/datum/computer_file/program/card_mod/proc/can_close_job(datum/job/job)
+ if(job)
+ if(!job_blacklisted(job))
+ if(job.total_positions > job.current_positions)
+ var/delta = (world.time / 10) - time_last_changed_position
+ if((change_position_cooldown < delta) || (opened_positions[job.title] > 0))
+ return 1
+ return -2
+ return -1
+ return 0
+
+/datum/computer_file/program/card_mod/proc/format_jobs(list/jobs)
+ var/obj/item/weapon/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD]
+ if(!card_slot || !card_slot.stored_card)
+ return null
+ var/obj/item/weapon/card/id/id_card = card_slot.stored_card
+ var/list/formatted = list()
+ for(var/job in jobs)
+ formatted.Add(list(list(
+ "display_name" = replacetext(job, " ", " "),
+ "target_rank" = id_card && id_card.assignment ? id_card.assignment : "Unassigned",
+ "job" = job)))
+
+ return formatted
+
+
+/datum/computer_file/program/card_mod/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers)
+ assets.send(user)
+ ui = new(user, src, ui_key, "card_prog.tmpl", "ID card modification program", 775, 700)
+ ui.set_layout_key("program")
+ ui.open()
+
+/datum/computer_file/program/card_mod/Topic(href, href_list)
+ if(..())
+ return 1
+
+ var/obj/item/weapon/computer_hardware/card_slot/card_slot
+ var/obj/item/weapon/computer_hardware/printer/printer
+ if(computer)
+ card_slot = computer.all_components[MC_CARD]
+ printer = computer.all_components[MC_PRINT]
+ if(!card_slot)
+ return
+
+ var/mob/user = usr
+
+ var/obj/item/weapon/card/id/modify = card_slot.stored_card
+ var/obj/item/weapon/card/id/scan = card_slot.stored_card2
+
+ switch(href_list["action"])
+ if("PRG_modify")
+ if(modify)
+ data_core.manifest_modify(modify.registered_name, modify.assignment)
+ modify.name = "[modify.registered_name]'s ID Card ([modify.assignment])"
+ card_slot.try_eject(1, user)
+ else
+ var/obj/item/I = usr.get_active_hand()
+ if(istype(I, /obj/item/weapon/card/id))
+ if(!usr.drop_item())
+ return
+ I.forceMove(computer)
+ card_slot.stored_card = I
+
+ if("PRG_scan")
+ if(scan)
+ card_slot.try_eject(2, user)
+ else
+ var/obj/item/I = usr.get_active_hand()
+ if(istype(I, /obj/item/weapon/card/id))
+ if(!usr.drop_item())
+ return
+ I.forceMove(computer)
+ card_slot.stored_card2 = I
+
+ if("PRG_access")
+ if(href_list["allowed"])
+ if(is_authenticated(usr))
+ var/access_type = text2num(href_list["access_target"])
+ var/access_allowed = text2num(href_list["allowed"])
+ if(access_type in (is_centcom ? get_all_centcom_access() : get_all_accesses()))
+ modify.access -= access_type
+ if(!access_allowed)
+ modify.access += access_type
+
+ if("PRG_skin")
+ var/skin = href_list["skin_target"]
+ if(is_authenticated(usr) && modify && ((skin in get_station_card_skins()) || ((skin in get_centcom_card_skins()) && is_centcom)))
+ modify.icon_state = href_list["skin_target"]
+
+ if("PRG_assign")
+ if(is_authenticated(usr) && modify)
+ var/t1 = href_list["assign_target"]
+ if(t1 == "Custom")
+ var/temp_t = sanitize(copytext(input("Enter a custom job assignment.","Assignment"),1,MAX_MESSAGE_LEN))
+ //let custom jobs function as an impromptu alt title, mainly for sechuds
+ if(temp_t && modify)
+ modify.assignment = temp_t
+ else
+ var/list/access = list()
+ if(is_centcom)
+ access = get_centcom_access(t1)
+ else
+ var/datum/job/jobdatum
+ for(var/jobtype in typesof(/datum/job))
+ var/datum/job/J = new jobtype
+ if(ckey(J.title) == ckey(t1))
+ jobdatum = J
+ break
+ if(!jobdatum)
+ to_chat(usr, "\red No log exists for this job: [t1]")
+ return
+
+ access = jobdatum.get_access()
+
+ modify.access = access
+ modify.assignment = t1
+ modify.rank = t1
+
+ callHook("reassign_employee", list(modify))
+
+ if("PRG_reg")
+ if(is_authenticated(usr))
+ var/temp_name = reject_bad_name(href_list["reg"])
+ if(temp_name)
+ modify.registered_name = temp_name
+ else
+ computer.visible_message("[src] buzzes rudely.")
+
+ if("PRG_account")
+ if(is_authenticated(usr))
+ var/account_num = text2num(href_list["account"])
+ modify.associated_account_number = account_num
+
+ if("PRG_mode")
+ mode = text2num(href_list["mode_target"])
+
+ if("PRG_print")
+ if(!printing && computer)
+ printing = 1
+ playsound(computer.loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1)
+ spawn(50)
+ printing = 0
+ nanomanager.update_uis(src)
+ var/title
+ var/content
+ if(mode == 2)
+ title = "crew manifest ([worldtime2text()])"
+ content = "
")
- popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state))
- popup.open()
+ return data
/obj/machinery/computer/shuttle/Topic(href, href_list)
if(..())
return 1
- usr.set_machine(src)
- src.add_fingerprint(usr)
+
if(!allowed(usr))
to_chat(usr, "Access denied.")
return
@@ -728,7 +729,7 @@
to_chat(usr, "Invalid shuttle requested.")
else
to_chat(usr, "Unable to comply.")
- updateUsrDialog()
+ return 1
/obj/machinery/computer/shuttle/emag_act(mob/user)
if(!emagged)
@@ -760,10 +761,11 @@
to_chat(usr, "Your request has been recieved by Centcom.")
log_admin("[key_name(usr)] requested to move the transport ferry to Centcom.")
message_admins("FERRY: [key_name_admin(usr)] (Move Ferry) is requesting to move the transport ferry to Centcom.")
+ . = 1
+ nanomanager.update_uis(src)
spawn(600) //One minute cooldown
cooldown = 0
-
/obj/machinery/computer/shuttle/ert
name = "specops shuttle console"
//circuit = /obj/item/weapon/circuitboard/ert
@@ -846,6 +848,7 @@ var/global/trade_dockrequest_timelimit = 0
to_chat(usr, "Request sent.")
event_announcement.Announce(docking_request_message, "Docking Request")
trade_dockrequest_timelimit = world.time + 1200 // They have 2 minutes to approve the request.
+ return 1
/obj/machinery/computer/shuttle/trade/sol
req_access = list(access_trade_sol)
diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm
index 5e57fb4eff9..24d76267b13 100644
--- a/code/modules/shuttle/supply.dm
+++ b/code/modules/shuttle/supply.dm
@@ -236,8 +236,8 @@
/proc/forbidden_atoms_check(atom/A)
var/list/blacklist = list(
/mob/living,
- /obj/effect/blob,
- /obj/effect/spider/spiderling,
+ /obj/structure/blob,
+ /obj/structure/spider/spiderling,
/obj/item/weapon/disk/nuclear,
/obj/machinery/nuclearbomb,
/obj/item/device/radio/beacon,
@@ -662,6 +662,13 @@
investigate_log("[key_name(usr)] has sent the supply shuttle away. Remaining points: [shuttle_master.points]. Shuttle contents: [shuttle_master.sold_atoms]", "cargo")
else if(!shuttle_master.supply.request(shuttle_master.getDock("supply_home")))
post_signal("supply")
+ if(LAZYLEN(shuttle_master.shoppinglist) && prob(10))
+ var/datum/supply_order/O = new /datum/supply_order()
+ O.ordernum = shuttle_master.ordernum
+ O.object = shuttle_master.supply_packs[pick(shuttle_master.supply_packs)]
+ O.orderedby = random_name(pick(MALE,FEMALE), species = "Human")
+ shuttle_master.shoppinglist += O
+ investigate_log("Random [O.object] crate added to supply shuttle")
else if(href_list["doorder"])
if(world.time < reqtime)
@@ -789,6 +796,54 @@
/mob/living/silicon/robot/drone,
/mob/living/simple_animal/bot/mulebot
)
+ var/state = PLASTIC_FLAPS_NORMAL
+ var/can_deconstruct = TRUE
+
+/obj/structure/plasticflaps/examine(mob/user)
+ . = ..()
+ switch(state)
+ if(PLASTIC_FLAPS_NORMAL)
+ to_chat(user, "[src] are screwed to the floor.")
+ if(PLASTIC_FLAPS_DETACHED)
+ to_chat(user, "[src] are no longer screwed to the floor, and the flaps can be sliced apart.")
+
+/obj/structure/plasticflaps/attackby(obj/item/W, mob/user, params)
+ add_fingerprint(user)
+ if(isscrewdriver(W))
+ if(state == PLASTIC_FLAPS_NORMAL)
+ playsound(loc, W.usesound, 100, 1)
+ user.visible_message("[user] unscrews [src] from the floor.", "You start to unscrew [src] from the floor...", "You hear rustling noises.")
+ if(do_after(user, 180*W.toolspeed, target = src))
+ if(state != PLASTIC_FLAPS_NORMAL)
+ return
+ state = PLASTIC_FLAPS_DETACHED
+ anchored = FALSE
+ to_chat(user, "You unscrew [src] from the floor.")
+ else if(state == PLASTIC_FLAPS_DETACHED)
+ playsound(loc, W.usesound, 100, 1)
+ user.visible_message("[user] screws [src] to the floor.", "You start to screw [src] to the floor...", "You hear rustling noises.")
+ if(do_after(user, 40*W.toolspeed, target = src))
+ if(state != PLASTIC_FLAPS_DETACHED)
+ return
+ state = PLASTIC_FLAPS_NORMAL
+ anchored = TRUE
+ to_chat(user, "You screw [src] from the floor.")
+ else if(iswelder(W))
+ if(state == PLASTIC_FLAPS_DETACHED)
+ var/obj/item/weapon/weldingtool/WT = W
+ if(!WT.remove_fuel(0, user))
+ return
+ playsound(loc, WT.usesound, 100, 1)
+ user.visible_message("[user] slices apart [src].", "You start to slice apart [src].", "You hear welding.")
+ if(do_after(user, 120*WT.toolspeed, target = src))
+ if(state != PLASTIC_FLAPS_DETACHED)
+ return
+ to_chat(user, "You slice apart [src].")
+ var/obj/item/stack/sheet/plastic/five/P = new(loc)
+ P.add_fingerprint(user)
+ qdel(src)
+ else
+ . = ..()
/obj/structure/plasticflaps/CanPass(atom/A, turf/T)
if(istype(A) && A.checkpass(PASSGLASS))
@@ -844,6 +899,11 @@
if(prob(5))
qdel(src)
+/obj/structure/plasticflaps/proc/deconstruct(disassembled = TRUE)
+ if(can_deconstruct)
+ new /obj/item/stack/sheet/plastic/five(loc)
+ qdel(src)
+
/obj/structure/plasticflaps/mining //A specific type for mining that doesn't allow airflow because of them damn crates
name = "\improper Airtight plastic flaps"
desc = "Heavy duty, airtight, plastic flaps."
diff --git a/code/modules/space_management/heap_space_level.dm b/code/modules/space_management/heap_space_level.dm
index 8d5a3971ba1..640080095a3 100644
--- a/code/modules/space_management/heap_space_level.dm
+++ b/code/modules/space_management/heap_space_level.dm
@@ -1,15 +1,62 @@
// This represents a level we can carve up as we please, and hand out
// chunks of to whatever requests it
/datum/space_level/heap
- var/datum/space_chunk/top
- linkage = UNAFFECTED
+ name = "Heap level #ERROR"
+ var/datum/space_chunk/top
+ linkage = UNAFFECTED
-/datum/space_level/heap/New()
- ..()
- top = new
+/datum/space_level/heap/New(z, name, transition_type, traits)
+ ..(z, "Heap level #[z]", UNAFFECTED, traits)
+ top = new(1, 1, zpos, world.maxx, world.maxy)
+ flags = traits
/datum/space_level/heap/proc/request(width, height)
- return 1 // All are welcome! At least until I add code for this
+ return top.can_fit_space(width, height)
-/datum/zlevel/heap/proc/allocate(width, height)
- return
+// Returns a space chunk datum for some nerd to work with - tells them what's safe to write into, and such
+/datum/space_level/heap/proc/allocate(width, height)
+ if(!request(width, height))
+ return null
+
+ var/datum/space_chunk/C = top.get_optimal_chunk(width, height)
+ if(!C)
+ return null
+ C.children.Cut()
+
+ if(C.width == width && C.height == height && C.is_empty)
+ C.set_occupied(TRUE)
+ return C
+
+ // Split the chunk into 4 pieces
+ var/datum/space_chunk/return_chunk = new(C.x, C.y, C.zpos, width, height)
+ C.children += return_chunk
+ C.children += new /datum/space_chunk(C.x+width, C.y, C.zpos, C.width-width, height)
+ C.children += new /datum/space_chunk(C.x, C.y+height, C.zpos, width, C.height-height)
+ C.children += new /datum/space_chunk(C.x+width, C.y+height, C.zpos, C.width-width, C.height-height)
+
+ for(var/datum/space_chunk/C2 in C.children)
+ C2.parent = C
+ return_chunk.set_occupied(TRUE)
+ return return_chunk
+
+/datum/space_level/heap/proc/free(datum/space_chunk/C)
+ if(!istype(C))
+ return
+ if(C.zpos != zpos)
+ return
+ C.set_occupied(FALSE)
+ for(var/turf/T in block(locate(C.x, C.y, C.zpos), locate(C.x+C.width-1, C.y+C.height-1, C.zpos)))
+ for(var/atom/movable/M in T)
+ if(istype(M, /mob/dead/observer))
+ continue
+ M.loc = null
+ qdel(M, TRUE)
+ T.ChangeTurf(/turf/space)
+ var/datum/space_chunk/last_empty_parent = C
+ while(last_empty_parent.parent && last_empty_parent.parent.is_empty)
+ last_empty_parent = last_empty_parent.parent
+ // Prevent a self-qdel from killing this proc
+ src = null
+ for(var/datum/space_chunk/child in last_empty_parent.children)
+ qdel(child)
+ last_empty_parent.children.Cut()
diff --git a/code/modules/space_management/space_chunk.dm b/code/modules/space_management/space_chunk.dm
index a150d25d2f3..e139394e963 100644
--- a/code/modules/space_management/space_chunk.dm
+++ b/code/modules/space_management/space_chunk.dm
@@ -10,14 +10,81 @@
var/width
var/height
var/zpos
+ // Whether dedicated for use or not
+ var/occupied = FALSE
+ // Whether the chunk contains used children or not
+ var/is_empty = TRUE
+ var/list/children = list()
+ var/datum/space_chunk/parent = null
-/datum/space_chunk/New(w, h, z, new_x, new_y)
+/datum/space_chunk/New(new_x, new_y, z, w, h)
x = new_x
y = new_y
zpos = z
width = w
height = h
+/datum/space_chunk/Destroy()
+ set_occupied(FALSE)
+ if(parent)
+ parent.children -= src
+ for(var/datum/space_chunk/child in children)
+ qdel(child)
+ children.Cut()
+ parent = null
+ . = ..()
+
+/datum/space_chunk/proc/can_fit_space(w, h)
+ if(w > width || h > height)
+ return FALSE
+ if(occupied)
+ return FALSE
+ if(is_empty)
+ return TRUE
+ for(var/datum/space_chunk/C in children)
+ if(C.can_fit_space(w, h))
+ return TRUE
+ return FALSE
+
+// Recursively drops down the tree and finds the most efficient chunk to use
+/datum/space_chunk/proc/get_optimal_chunk(w, h)
+ if(w > width || h > height)
+ return null
+ if(occupied)
+ return null
+ if(is_empty)
+ return src
+ var/datum/space_chunk/optimal_chunk
+ var/optimal_chunk_optimalness = 99999
+ for(var/datum/space_chunk/C in children)
+ var/datum/space_chunk/C2 = C.get_optimal_chunk(w, h)
+ if(!C2)
+ continue
+ var/optimalness = C2.width + C2.height-w-h
+ if(optimalness < optimal_chunk_optimalness)
+ optimal_chunk_optimalness = optimalness
+ optimal_chunk = C2
+ return optimal_chunk
+
+/datum/space_chunk/proc/set_occupied(new_occupied)
+ var/datum/space_chunk/C = parent
+ if(new_occupied)
+ occupied = TRUE
+ while(C)
+ C.is_empty = FALSE
+ C = C.parent
+ else
+ occupied = FALSE
+ while(C)
+ var/is_children_empty = TRUE
+ for(var/datum/space_chunk/C2 in C.children)
+ if(!C2.is_empty || C2.occupied)
+ is_children_empty = FALSE
+ if(!is_children_empty)
+ break
+ C.is_empty = TRUE
+ C = C.parent
+
/datum/space_chunk/proc/check_sanity()
var/i_am_sane = 1
i_am_sane |= (x > 0)
@@ -29,6 +96,13 @@
/datum/space_chunk/proc/return_turfs()
return
+/datum/space_chunk/proc/search_chunk(object_list)
+ var/list/located = list()
+ for(var/atom/object in object_list)
+ if(((object.x >= x) && (object.x <= (x + width))) && ((object.y >= y) && (object.y <= (y + height))) && (object.z == zpos))
+ located.Add(object)
+ return located
+
#undef BOTTOM_LEFT_CHUNK
#undef BOTTOM_RIGHT_CHUNK
#undef TOP_LEFT_CHUNK
diff --git a/code/modules/space_management/zlevel_manager.dm b/code/modules/space_management/zlevel_manager.dm
index d0bb9455eb8..087a70657ed 100644
--- a/code/modules/space_management/zlevel_manager.dm
+++ b/code/modules/space_management/zlevel_manager.dm
@@ -134,18 +134,36 @@ var/global/datum/zlev_manager/space_manager = new
/datum/zlev_manager/proc/add_new_heap()
world.maxz++
var/our_z = world.maxz
- var/datum/space_level/yup = new /datum/space_level/heap(our_z)
+ var/datum/space_level/yup = new /datum/space_level/heap(our_z, traits = list(BLOCK_TELEPORT, ADMIN_LEVEL))
z_list["[our_z]"] = yup
return yup
// This is what you can call to allocate a section of space
// Later, I'll add an argument to let you define the flags on the region
/datum/zlev_manager/proc/allocate_space(width, height)
+ if(width > world.maxx || height > world.maxy)
+ throw EXCEPTION("Too much space requested! \[[width],[height]\]")
if(!heaps.len)
heaps.len++
heaps[heaps.len] = add_new_heap()
var/datum/space_level/heap/our_heap
+ var/weve_got_vacancy = 0
for(our_heap in heaps)
- var/weve_got_vacancy = our_heap.request(width, height)
+ weve_got_vacancy = our_heap.request(width, height)
if(weve_got_vacancy)
break // We're sticking with the present value of `our_heap` - it's got room
+ // This loop will also run out if no vacancies are found
+
+ if(!weve_got_vacancy)
+ heaps.len++
+ our_heap = add_new_heap()
+ heaps[heaps.len] = our_heap
+ return our_heap.allocate(width, height)
+
+/datum/zlev_manager/proc/free_space(datum/space_chunk/C)
+ if(!istype(C))
+ return
+ var/datum/space_level/heap/heap = z_list["[C.zpos]"]
+ if(!istype(heap))
+ throw EXCEPTION("Attempted to free chunk at invalid z-level ([C.x],[C.y],[C.zpos]) [C.width]x[C.height]")
+ heap.free(C)
diff --git a/code/modules/spacepods/construction.dm b/code/modules/spacepods/construction.dm
index 0426b940d0b..a997a23f585 100644
--- a/code/modules/spacepods/construction.dm
+++ b/code/modules/spacepods/construction.dm
@@ -19,6 +19,10 @@
dir = EAST
+/obj/structure/spacepod_frame/Destroy()
+ QDEL_NULL(construct)
+ return ..()
+
/obj/structure/spacepod_frame/attackby(obj/item/W as obj, mob/user as mob, params)
if(!construct || !construct.action(W, user))
..()
diff --git a/code/modules/spacepods/equipment.dm b/code/modules/spacepods/equipment.dm
index 752c90f5db4..65b3b9232b8 100644
--- a/code/modules/spacepods/equipment.dm
+++ b/code/modules/spacepods/equipment.dm
@@ -28,9 +28,8 @@
firstloc = get_turf(my_atom)
secondloc = get_step(firstloc,NORTH)
olddir = dir
- var/proj_type = text2path(projectile_type)
- var/obj/item/projectile/projone = new proj_type(firstloc)
- var/obj/item/projectile/projtwo = new proj_type(secondloc)
+ var/obj/item/projectile/projone = new projectile_type(firstloc)
+ var/obj/item/projectile/projtwo = new projectile_type(secondloc)
projone.starting = get_turf(my_atom)
projone.firer = usr
projone.def_zone = "chest"
@@ -79,7 +78,7 @@
desc = "You shouldn't be seeing this"
icon = 'icons/vehicles/spacepod.dmi'
icon_state = "blank"
- var/projectile_type
+ var/obj/item/projectile/projectile_type
var/shot_cost = 0
var/shots_per = 1
var/fire_sound
@@ -89,7 +88,7 @@
name = "disabler system"
desc = "A weak taser system for space pods, fires disabler beams."
icon_state = "weapon_taser"
- projectile_type = "/obj/item/projectile/beam/disabler"
+ projectile_type = /obj/item/projectile/beam/disabler
shot_cost = 400
fire_sound = 'sound/weapons/Taser.ogg'
@@ -97,7 +96,7 @@
name = "burst taser system"
desc = "A weak taser system for space pods, this one fires 3 at a time."
icon_state = "weapon_burst_taser"
- projectile_type = "/obj/item/projectile/beam/disabler"
+ projectile_type = /obj/item/projectile/beam/disabler
shot_cost = 1200
shots_per = 3
fire_sound = 'sound/weapons/Taser.ogg'
@@ -107,7 +106,7 @@
name = "laser system"
desc = "A weak laser system for space pods, fires concentrated bursts of energy"
icon_state = "weapon_laser"
- projectile_type = "/obj/item/projectile/beam"
+ projectile_type = /obj/item/projectile/beam
shot_cost = 600
fire_sound = 'sound/weapons/Laser.ogg'
@@ -117,7 +116,7 @@
desc = "A weak mining laser system for space pods, fires bursts of energy that cut through rock"
icon = 'icons/goonstation/pods/ship.dmi'
icon_state = "pod_taser"
- projectile_type = "/obj/item/projectile/kinetic"
+ projectile_type = /obj/item/projectile/kinetic/pod
shot_cost = 300
fire_delay = 14
fire_sound = 'sound/weapons/Kenetic_accel.ogg'
@@ -127,7 +126,7 @@
desc = "A mining laser system for space pods, fires bursts of energy that cut through rock"
icon = 'icons/goonstation/pods/ship.dmi'
icon_state = "pod_m_laser"
- projectile_type = "/obj/item/projectile/kinetic/super"
+ projectile_type = /obj/item/projectile/kinetic/pod/regular
shot_cost = 250
fire_delay = 10
fire_sound = 'sound/weapons/Kenetic_accel.ogg'
@@ -137,7 +136,7 @@
desc = "An enhanced mining laser system for space pods, fires bursts of energy that cut through rock"
icon = 'icons/goonstation/pods/ship.dmi'
icon_state = "pod_w_laser"
- projectile_type = "/obj/item/projectile/kinetic/hyper"
+ projectile_type = /obj/item/projectile/kinetic/pod/enhanced
shot_cost = 200
fire_delay = 8
fire_sound = 'sound/weapons/Kenetic_accel.ogg'
diff --git a/code/modules/spacepods/parts.dm b/code/modules/spacepods/parts.dm
index d1aefb535e6..757d7a95dcc 100644
--- a/code/modules/spacepods/parts.dm
+++ b/code/modules/spacepods/parts.dm
@@ -55,7 +55,7 @@
return 0
return connectedparts
-/obj/item/pod_parts/pod_frame/attackby(var/obj/O, mob/user)
+/obj/item/pod_parts/pod_frame/attackby(var/obj/item/O, mob/user)
if(istype(O, /obj/item/stack/rods))
var/obj/item/stack/rods/R = O
var/list/linkedparts = find_square()
@@ -71,12 +71,12 @@
//log_admin("Repositioning")
pod.loc = F.loc
qdel(F)
- playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(get_turf(src), O.usesound, 50, 1)
if(istype(O, /obj/item/weapon/wrench))
to_chat(user, "You [!anchored ? "secure \the [src] in place." : "remove the securing bolts."]")
anchored = !anchored
density = anchored
- playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(get_turf(src), O.usesound, 50, 1)
/obj/item/pod_parts/pod_frame/verb/rotate()
set name = "Rotate Frame"
diff --git a/code/modules/spacepods/spacepod.dm b/code/modules/spacepods/spacepod.dm
index af18daa893a..0881c821431 100644
--- a/code/modules/spacepods/spacepod.dm
+++ b/code/modules/spacepods/spacepod.dm
@@ -124,22 +124,14 @@
/obj/spacepod/Destroy()
if(equipment_system.cargo_system)
equipment_system.cargo_system.removed(null)
- qdel(equipment_system)
- equipment_system = null
- qdel(cargo_hold)
- cargo_hold = null
- qdel(battery)
- battery = null
- qdel(cabin_air)
- cabin_air = null
- qdel(internal_tank)
- internal_tank = null
- qdel(pr_int_temp_processor)
- pr_int_temp_processor = null
- qdel(pr_give_air)
- pr_give_air = null
- qdel(ion_trail)
- ion_trail = null
+ QDEL_NULL(equipment_system)
+ QDEL_NULL(cargo_hold)
+ QDEL_NULL(battery)
+ QDEL_NULL(cabin_air)
+ QDEL_NULL(internal_tank)
+ QDEL_NULL(pr_int_temp_processor)
+ QDEL_NULL(pr_give_air)
+ QDEL_NULL(ion_trail)
occupant_sanity_check()
if(pilot)
pilot.forceMove(get_turf(src))
@@ -220,8 +212,8 @@
user.changeNext_move(CLICK_CD_MELEE)
deal_damage(15)
playsound(src.loc, 'sound/weapons/slash.ogg', 50, 1, -1)
- to_chat(user, "\red You slash at \the [src]!")
- visible_message("\red The [user] slashes at [src.name]'s armor!")
+ to_chat(user, "You slash at \the [src]!")
+ visible_message("The [user] slashes at [src.name]'s armor!")
return
/obj/spacepod/proc/deal_damage(var/damage)
@@ -275,7 +267,7 @@
cargo_hold.emp_act(severity)
if(battery && battery.charge > 0)
- battery.use((battery.charge / 2) / severity)
+ battery.use((battery.charge/3)/(severity*2))
deal_damage(80 / severity)
if(empcounter < (40 / severity))
empcounter = 40 / severity
@@ -311,14 +303,14 @@
if(iscrowbar(W))
if(!equipment_system.lock_system || unlocked || hatch_open)
hatch_open = !hatch_open
- playsound(loc, 'sound/items/Crowbar.ogg', 50, 1)
+ playsound(loc, W.usesound, 50, 1)
to_chat(user, "You [hatch_open ? "open" : "close"] the maintenance hatch.")
else
to_chat(user, "The hatch is locked shut!")
return
if(istype(W, /obj/item/weapon/stock_parts/cell))
if(!hatch_open)
- to_chat(user, "\red The maintenance hatch is closed!")
+ to_chat(user, "The maintenance hatch is closed!")
return
if(battery)
to_chat(user, "The pod already has a battery.")
@@ -329,7 +321,7 @@
return
if(istype(W, /obj/item/device/spacepod_equipment))
if(!hatch_open)
- to_chat(user, "\red The maintenance hatch is closed!")
+ to_chat(user, "The maintenance hatch is closed!")
return
if(!equipment_system)
to_chat(user, "The pod has no equipment datum, yell at the coders")
@@ -361,19 +353,19 @@
if(istype(W, /obj/item/weapon/weldingtool))
if(!hatch_open)
- to_chat(user, "\red You must open the maintenance hatch before attempting repairs.")
+ to_chat(user, "You must open the maintenance hatch before attempting repairs.")
return
var/obj/item/weapon/weldingtool/WT = W
if(!WT.isOn())
- to_chat(user, "\red The welder must be on for this task.")
+ to_chat(user, "The welder must be on for this task.")
return
if(health < initial(health))
- to_chat(user, "\blue You start welding the spacepod...")
- playsound(loc, 'sound/items/Welder.ogg', 50, 1)
- if(do_after(user, 20, target = src))
+ to_chat(user, "You start welding the spacepod...")
+ playsound(loc, W.usesound, 50, 1)
+ if(do_after(user, 20 * W.toolspeed, target = src))
if(!src || !WT.remove_fuel(3, user)) return
repair_damage(10)
- to_chat(user, "\blue You mend some [pick("dents","bumps","damage")] with \the [WT]")
+ to_chat(user, "You mend some [pick("dents","bumps","damage")] with \the [WT]")
return
to_chat(user, "\The [src] is fully repaired!")
return
@@ -383,7 +375,7 @@
if(L.on && equipment_system.lock_system)
user.visible_message(user, "[user] is drilling through the [src]'s lock!",
"You start drilling through the [src]'s lock!")
- if(do_after(user, 100, target = src))
+ if(do_after(user, 100 * W.toolspeed, target = src))
qdel(equipment_system.lock_system)
equipment_system.lock_system = null
user.visible_message(user, "[user] has destroyed the [src]'s lock!",
diff --git a/code/modules/station_goals/bsa.dm b/code/modules/station_goals/bsa.dm
index 89a58d7cc9e..38d04b527db 100644
--- a/code/modules/station_goals/bsa.dm
+++ b/code/modules/station_goals/bsa.dm
@@ -7,7 +7,7 @@
/datum/station_goal/bluespace_cannon/get_report()
return {"Bluespace Artillery position construction
- Our military presence is inadequate in your sector. We need you to construct BSA-[rand(1,99)] Artillery position aboard your station.
+ Our military presence is inadequate in your sector. We need you to construct a BSA-[rand(1,99)] Artillery position aboard your station.
Its base parts should be available for shipping by your cargo shuttle.
@@ -312,7 +312,7 @@
ui.open()
ui.set_auto_update(1)
-/obj/machinery/computer/bsa_control/ui_data(mob/user, ui_key = "main", datum/topic_state/state = physical_state)
+/obj/machinery/computer/bsa_control/ui_data(mob/user, ui_key = "main", datum/topic_state/state = default_state)
var/list/data = list()
data["connected"] = cannon
data["notice"] = notice
diff --git a/code/modules/station_goals/dna_vault.dm b/code/modules/station_goals/dna_vault.dm
index 26d00e6360d..d77455cd8e7 100644
--- a/code/modules/station_goals/dna_vault.dm
+++ b/code/modules/station_goals/dna_vault.dm
@@ -177,6 +177,8 @@ var/list/non_simple_animals = typecacheof(list(/mob/living/carbon/human/monkey,/
plants_max = G.plant_count
dna_max = G.human_count
break
+
+ ..()
/obj/machinery/dna_vault/Destroy()
for(var/V in fillers)
@@ -211,7 +213,7 @@ var/list/non_simple_animals = typecacheof(list(/mob/living/carbon/human/monkey,/
L += pick_n_take(possible_powers)
power_lottery[user] = L
-/obj/machinery/dna_vault/ui_data(mob/user, ui_key = "main", datum/topic_state/state = physical_state) //TODO Make it % bars maybe
+/obj/machinery/dna_vault/ui_data(mob/user, ui_key = "main", datum/topic_state/state = default_state) //TODO Make it % bars maybe
var/list/data = list()
data["plants"] = plants.len
data["plants_max"] = plants_max
diff --git a/code/modules/station_goals/shield.dm b/code/modules/station_goals/shield.dm
index 2090b34baa5..5a19fcb67cc 100644
--- a/code/modules/station_goals/shield.dm
+++ b/code/modules/station_goals/shield.dm
@@ -3,13 +3,13 @@
// Satellites be actived to generate a shield that will block unorganic matter from passing it.
/datum/station_goal/station_shield
name = "Station Shield"
- var/coverage_goal = 500
+ var/coverage_goal = 5000
/datum/station_goal/station_shield/get_report()
return {"Station Shield construction
The station is located in a zone full of space debris. We have a prototype shielding system you will deploy to reduce collision related accidents.
- You can order the satellites and control systems through cargo shuttle."}
+ You can order the satellites and control systems through the cargo shuttle."}
/datum/station_goal/station_shield/on_report()
//Unlock
@@ -71,7 +71,7 @@
if(S.id == id && atoms_share_level(src, S))
S.toggle()
-/obj/machinery/computer/sat_control/ui_data(mob/user, ui_key = "main", datum/topic_state/state = physical_state)
+/obj/machinery/computer/sat_control/ui_data(mob/user, ui_key = "main", datum/topic_state/state = default_state)
var/list/data = list()
data["satellites"] = list()
diff --git a/code/modules/surgery/encased.dm b/code/modules/surgery/encased.dm
index 7d9152e01ff..fbcd9a21c69 100644
--- a/code/modules/surgery/encased.dm
+++ b/code/modules/surgery/encased.dm
@@ -70,7 +70,7 @@
/datum/surgery_step/open_encased/retract
name = "retract bone"
allowed_tools = list(
- /obj/item/weapon/scalpel/manager = 120, \
+ /obj/item/weapon/scalpel/laser/manager = 100, \
/obj/item/weapon/retractor = 100, \
/obj/item/weapon/crowbar = 75
)
@@ -121,7 +121,7 @@
/datum/surgery_step/open_encased/close
name = "unretract bone" //i suck at names okay? give me a new one
allowed_tools = list(
- /obj/item/weapon/scalpel/manager = 120, \
+ /obj/item/weapon/scalpel/laser/manager = 100, \
/obj/item/weapon/retractor = 100, \
/obj/item/weapon/crowbar = 75
)
diff --git a/code/modules/surgery/face.dm b/code/modules/surgery/face.dm
index 6c2f7354b43..c17f318e748 100644
--- a/code/modules/surgery/face.dm
+++ b/code/modules/surgery/face.dm
@@ -28,10 +28,6 @@
/datum/surgery_step/generic/cut_face
name = "make incision"
allowed_tools = list(
- /obj/item/weapon/scalpel/laser3 = 115, \
- /obj/item/weapon/scalpel/laser2 = 110, \
- /obj/item/weapon/scalpel/laser1 = 105, \
- /obj/item/weapon/scalpel/manager = 120, \
/obj/item/weapon/scalpel = 100, \
/obj/item/weapon/kitchen/knife = 75, \
/obj/item/weapon/shard = 50, \
@@ -62,7 +58,7 @@
/datum/surgery_step/face/mend_vocal
name = "mend vocal cords"
allowed_tools = list(
- /obj/item/weapon/scalpel/manager = 120, \
+ /obj/item/weapon/scalpel/laser/manager = 100, \
/obj/item/weapon/hemostat = 100, \
/obj/item/stack/cable_coil = 75, \
/obj/item/device/assembly/mousetrap = 10 //I don't know. Don't ask me. But I'm leaving it because hilarity.
@@ -89,7 +85,7 @@
/datum/surgery_step/face/fix_face
name = "reshape face"
allowed_tools = list(
- /obj/item/weapon/scalpel/manager = 120, \
+ /obj/item/weapon/scalpel/laser/manager = 100, \
/obj/item/weapon/retractor = 100, \
/obj/item/weapon/crowbar = 55, \
/obj/item/weapon/kitchen/utensil/fork = 75)
@@ -116,9 +112,7 @@
/datum/surgery_step/face/cauterize
name = "close incision"
allowed_tools = list(
- /obj/item/weapon/scalpel/laser3 = 115, \
- /obj/item/weapon/scalpel/laser2 = 110, \
- /obj/item/weapon/scalpel/laser1 = 105, \
+ /obj/item/weapon/scalpel/laser = 100, \
/obj/item/weapon/cautery = 100, \
/obj/item/clothing/mask/cigarette = 75, \
/obj/item/weapon/lighter = 50, \
diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm
index 8d5f7669ecd..3ff6020af26 100644
--- a/code/modules/surgery/generic.dm
+++ b/code/modules/surgery/generic.dm
@@ -23,10 +23,6 @@
name = "make incision"
allowed_tools = list(
- /obj/item/weapon/scalpel/laser3 = 115, \
- /obj/item/weapon/scalpel/laser2 = 110, \
- /obj/item/weapon/scalpel/laser1 = 105, \
- /obj/item/weapon/scalpel/manager = 120, \
/obj/item/weapon/scalpel = 100, \
/obj/item/weapon/kitchen/knife = 75, \
/obj/item/weapon/shard = 50, \
@@ -65,10 +61,7 @@
name = "clamp bleeders"
allowed_tools = list(
- /obj/item/weapon/scalpel/laser3 = 115, \
- /obj/item/weapon/scalpel/laser2 = 110, \
- /obj/item/weapon/scalpel/laser1 = 105, \
- /obj/item/weapon/scalpel/manager = 120, \
+ /obj/item/weapon/scalpel/laser = 100, \
/obj/item/weapon/hemostat = 100, \
/obj/item/stack/cable_coil = 75, \
/obj/item/device/assembly/mousetrap = 20
@@ -103,7 +96,7 @@
name = "retract skin"
allowed_tools = list(
- /obj/item/weapon/scalpel/manager = 120, \
+ /obj/item/weapon/scalpel/laser/manager = 100, \
/obj/item/weapon/retractor = 100, \
/obj/item/weapon/crowbar = 75, \
/obj/item/weapon/kitchen/utensil/fork = 50
@@ -158,9 +151,7 @@
name = "cauterize incision"
allowed_tools = list(
- /obj/item/weapon/scalpel/laser3 = 115, \
- /obj/item/weapon/scalpel/laser2 = 110, \
- /obj/item/weapon/scalpel/laser1 = 105, \
+ /obj/item/weapon/scalpel/laser = 100, \
/obj/item/weapon/cautery = 100, \
/obj/item/clothing/mask/cigarette = 75, \
/obj/item/weapon/lighter = 50, \
diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm
index 35a30674e3e..b952ddd0f79 100644
--- a/code/modules/surgery/implant.dm
+++ b/code/modules/surgery/implant.dm
@@ -97,10 +97,7 @@
/datum/surgery_step/cavity/close_space
name = "close cavity space"
allowed_tools = list(
- /obj/item/weapon/scalpel/laser3 = 115, \
- /obj/item/weapon/scalpel/laser2 = 110, \
- /obj/item/weapon/scalpel/laser1 = 105, \
- /obj/item/weapon/scalpel/manager = 120, \
+ /obj/item/weapon/scalpel/laser = 100, \
/obj/item/weapon/cautery = 100, \
/obj/item/clothing/mask/cigarette = 75, \
/obj/item/weapon/lighter = 50, \
@@ -354,7 +351,7 @@
name = "remove embedded objects"
time = 32
allowed_tools = list(
- /obj/item/weapon/scalpel/manager = 120, \
+ /obj/item/weapon/scalpel/laser/manager = 100, \
/obj/item/weapon/hemostat = 100, \
/obj/item/stack/cable_coil = 75, \
/obj/item/device/assembly/mousetrap = 20
@@ -386,7 +383,7 @@
var/mob/living/simple_animal/borer/worm = H.has_brain_worms()
if(worm.controlling)
target.release_control()
- worm.detatch()
+ worm.detach()
worm.leave_host()
user.visible_message("a slug like creature wiggles out of [H]'s [target_zone]!")
diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm
index 153f169efca..ffd0b4f0b1e 100644
--- a/code/modules/surgery/organs/augments_internal.dm
+++ b/code/modules/surgery/organs/augments_internal.dm
@@ -8,17 +8,17 @@
var/implant_overlay
tough = 1 //not easyly broken by combat damage
sterile = 1 //not very germy
+ robotic = 2 // these are cybernetic after all
/obj/item/organ/internal/cyberimp/New(var/mob/M = null)
- if(iscarbon(M))
- src.insert(M)
+ . = ..()
if(implant_overlay)
var/image/overlay = new /image(icon, implant_overlay)
overlay.color = implant_color
overlays |= overlay
- return ..()
-
+/obj/item/organ/internal/cyberimp/emp_act()
+ return // These shouldn't be hurt by EMPs in the standard way
//[[[[BRAIN]]]]
@@ -270,9 +270,15 @@
var/lasthand = null
/obj/item/organ/internal/cyberimp/chest/arm_mod/ui_action_click()
+ toggle_item()
+
+/obj/item/organ/internal/cyberimp/chest/arm_mod/proc/toggle_item()
if(overloaded)//ensure the implant isn't broken
to_chat(owner, "The implant doesn't respond. It seems to be broken...")
return
+ owner.changeNext_move(CLICK_CD_MELEE)
+ if(owner.next_move < world.time)
+ return // No spam
if(out)//check if the owner has the item out already
owner.unEquip(holder, 1)//if he does, take it away. then,
holder.loc = null//stash it in nullspace
@@ -297,6 +303,9 @@
holder.loc = null
out = 0
owner.visible_message("[holder] forcibly retracts into [owner]'s arm.")
+ overload() // Make sure this doesn't happen again
+
+/obj/item/organ/internal/cyberimp/chest/arm_mod/proc/overload()
owner.visible_message("A loud bang comes from [owner]...")
playsound(get_turf(owner), 'sound/effects/bang.ogg', 100, 1)
to_chat(owner, "You feel an explosion erupt inside you as your chest implant breaks. Is it hot in here?")
@@ -312,7 +321,7 @@
limb.droplimb(0, DROPLIMB_EDGE)
owner.say("I HAVE BEEN DISARMED!!!")
owner.adjustFireLoss(25)//severely injure him!
- overloaded = 1//then make sure this can't happen again by breaking the implant.
+ overloaded = TRUE
/obj/item/organ/internal/cyberimp/chest/arm_mod/tase//mounted, self-charging taser!
name = "Arm-cannon taser implant"
@@ -322,6 +331,7 @@
actions_types = list(/datum/action/item_action/organ_action/toggle)
/obj/item/organ/internal/cyberimp/chest/arm_mod/tase/New()//when the implant is created...
+ ..()
holder = new /obj/item/weapon/gun/energy/gun/advtaser/mounted(src)//assign a brand new item to it. (in this case, a gun)
/obj/item/organ/internal/cyberimp/chest/arm_mod/lase//mounted, self-charging laser!
@@ -332,8 +342,88 @@
actions_types = list(/datum/action/item_action/organ_action/toggle)
/obj/item/organ/internal/cyberimp/chest/arm_mod/lase/New()
+ ..()
holder = new /obj/item/weapon/gun/energy/laser/mounted(src)
+// lets make IPCs even *more* vulnerable to EMPs!
+/obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord
+ name = "APC-compatible power adapter implant"
+ desc = "An implant commonly installed inside IPCs in order to allow them to easily collect energy from their environment"
+ origin_tech = "materials=3;biotech=2;powerstorage=3"
+ slot = "shoulders2"
+ actions_types = list(/datum/action/item_action/organ_action/toggle)
+
+
+/obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord/New()
+ ..()
+ holder = new /obj/item/apc_powercord(src)
+
+/obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord/overload()
+ // To allow repair via nanopaste/screwdriver
+ // also so IPCs don't also catch on fire and fall even more apart upon EMP
+ damage = 1
+ overloaded = TRUE
+
+/obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord/surgeryize()
+ if(overloaded && owner)
+ to_chat(owner, "Your [src] feels functional again.")
+ overloaded = FALSE
+
+
+/obj/item/apc_powercord
+ name = "power cable"
+ desc = "Insert into a nearby APC to draw power from it."
+ icon = 'icons/obj/power.dmi'
+ icon_state = "wire1"
+ flags = NODROP | NOBLUDGEON
+
+/obj/item/apc_powercord/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
+ if(!istype(target, /obj/machinery/power/apc) || !ishuman(user) || !proximity_flag)
+ return ..()
+ user.changeNext_move(CLICK_CD_MELEE)
+ var/obj/machinery/power/apc/A = target
+ var/mob/living/carbon/human/H = user
+ if(H.get_int_organ(/obj/item/organ/internal/cell))
+ if(A.emagged || A.stat & BROKEN)
+ var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
+ s.set_up(3, 1, A)
+ s.start()
+ to_chat(H, "The APC power currents surge erratically, damaging your chassis!")
+ H.adjustFireLoss(10,0)
+ else if(A.cell && A.cell.charge > 0)
+ if(H.nutrition >= NUTRITION_LEVEL_WELL_FED)
+ to_chat(user, "You are already fully charged!")
+ else
+ addtimer(src, "powerdraw_loop", 0, TRUE, A, H)
+ else
+ to_chat(user, "There is no charge to draw from that APC.")
+ else
+ to_chat(user, "You lack a cell in which to store charge!")
+
+/obj/item/apc_powercord/proc/powerdraw_loop(obj/machinery/power/apc/A, mob/living/carbon/human/H)
+ H.visible_message("[H] inserts a power connector into \the [A].", "You begin to draw power from \the [A].")
+ while(do_after(H, 10, target = A))
+ if(loc != H)
+ to_chat(H, "You must keep your connector out while charging!")
+ break
+ if(A.cell.charge == 0)
+ to_chat(H, "\The [A] has no more charge.")
+ break
+ A.charging = 1
+ if(A.cell.charge >= 500)
+ H.nutrition += 50
+ A.cell.charge -= 500
+ to_chat(H, "You siphon off some of the stored charge for your own use.")
+ else
+ H.nutrition += A.cell.charge/10
+ A.cell.charge = 0
+ to_chat(H, "You siphon off the last of \the [A]'s charge.")
+ break
+ if(H.nutrition > NUTRITION_LEVEL_WELL_FED)
+ to_chat(H, "You are now fully charged.")
+ break
+ H.visible_message("[H] unplugs from \the [A].", "You unplug from \the [A].")
+
//BOX O' IMPLANTS
/obj/item/weapon/storage/box/cyber_implants
diff --git a/code/modules/surgery/organs/autoimplanter.dm b/code/modules/surgery/organs/autoimplanter.dm
index 5c2aa1193d9..4af88abc52f 100644
--- a/code/modules/surgery/organs/autoimplanter.dm
+++ b/code/modules/surgery/organs/autoimplanter.dm
@@ -4,6 +4,7 @@
icon_state = "autoimplanter"
item_state = "walkietalkie"//left as this so as to intentionally not have inhands
w_class = 2
+ usesound = 'sound/weapons/circsawhit.ogg'
var/obj/item/organ/internal/cyberimp/storedorgan
/obj/item/device/autoimplanter/attack_self(mob/user)//when the object it used...
@@ -12,7 +13,7 @@
return
storedorgan.insert(user)//insert stored organ into the user
user.visible_message("[user] presses a button on [src], and you hear a short mechanical noise.", "You feel a sharp sting as [src] plunges into your body.")
- playsound(get_turf(user), 'sound/weapons/circsawhit.ogg', 50, 1)
+ playsound(get_turf(user), usesound, 50, 1)
storedorgan = null
/obj/item/device/autoimplanter/attackby(obj/item/I, mob/user, params)
@@ -32,4 +33,4 @@
storedorgan.forceMove(get_turf(user))
storedorgan = null
to_chat(user, "You remove the [storedorgan] from [src].")
- playsound(get_turf(user), 'sound/items/Screwdriver.ogg', 50, 1)
+ playsound(get_turf(user), I.usesound, 50, 1)
diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm
index 16a22ea81f6..aa32375792e 100644
--- a/code/modules/surgery/organs/organ.dm
+++ b/code/modules/surgery/organs/organ.dm
@@ -66,7 +66,7 @@ var/list/organ_cache = list()
blood_DNA = list()
blood_DNA[dna.unique_enzymes] = dna.b_type
-/obj/item/organ/proc/die()
+/obj/item/organ/proc/necrotize(update_sprite=TRUE)
if(status & ORGAN_ROBOT)
return
damage = max_damage
@@ -105,10 +105,10 @@ var/list/organ_cache = list()
if(germ_level >= INFECTION_LEVEL_TWO)
germ_level += rand(2,6)
if(germ_level >= INFECTION_LEVEL_THREE)
- die()
+ necrotize()
if(damage >= max_damage)
- die()
+ necrotize()
else if(owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs
//** Handle antibiotics and curing infections
@@ -117,7 +117,7 @@ var/list/organ_cache = list()
//check if we've hit max_damage
if(damage >= max_damage)
- die()
+ necrotize()
/obj/item/organ/proc/is_preserved()
if(istype(loc,/obj/item/device/mmi))
diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm
index 110584d5d2a..a077853a5fc 100644
--- a/code/modules/surgery/organs/organ_external.dm
+++ b/code/modules/surgery/organs/organ_external.dm
@@ -50,7 +50,7 @@
// Internal organs of this body part
var/list/internal_organs = list()
- var/damage_msg = "\red You feel an intense pain"
+ var/damage_msg = "You feel an intense pain"
var/broken_description
var/open = 0
@@ -68,6 +68,19 @@
var/can_stand
var/wound_cleanup_timer
+/obj/item/organ/external/necrotize(update_sprite=TRUE)
+ if(status & (ORGAN_ROBOT|ORGAN_DEAD))
+ return
+ to_chat(owner, "You can't feel your [name] anymore...")
+ status |= ORGAN_DEAD
+ if(dead_icon)
+ icon_state = dead_icon
+ if(owner)
+ owner.update_body(update_sprite)
+ owner.bad_external_organs |= src
+ if(vital)
+ owner.death()
+
/obj/item/organ/external/Destroy()
if(parent && parent.children)
parent.children -= src
@@ -541,10 +554,7 @@ Note that amputating the affected organ does in fact remove the infection from t
parent.germ_level++
if(germ_level >= INFECTION_LEVEL_THREE && antibiotics < 30) //overdosing is necessary to stop severe infections
- if(!(status & ORGAN_DEAD))
- status |= ORGAN_DEAD
- to_chat(owner, "You can't feel your [name] anymore...")
- owner.update_body(1)
+ necrotize()
germ_level++
owner.adjustToxLoss(1)
@@ -808,7 +818,7 @@ Note that amputating the affected organ does in fact remove the infection from t
return
if(owner)
owner.visible_message(\
- "\red You hear a loud cracking sound coming from \the [owner].",\
+ "You hear a loud cracking sound coming from \the [owner].",\
"Something feels like it shattered in your [name]!",\
"You hear a sickening crack.")
if(owner.species && !(owner.species.flags & NO_PAIN))
@@ -960,13 +970,13 @@ Note that amputating the affected organ does in fact remove the infection from t
return
if(owner)
if(type == "brute")
- owner.visible_message("\red You hear a sickening cracking sound coming from \the [owner]'s [name].", \
+ owner.visible_message("You hear a sickening cracking sound coming from \the [owner]'s [name].", \
"Your [name] becomes a mangled mess!", \
- "\red You hear a sickening crack.")
+ "You hear a sickening crack.")
else
- owner.visible_message("\red \The [owner]'s [name] melts away, turning into mangled mess!", \
+ owner.visible_message("\The [owner]'s [name] melts away, turning into mangled mess!", \
"Your [name] melts away!", \
- "\red You hear a sickening sizzle.")
+ "You hear a sickening sizzle.")
disfigured = 1
/obj/item/organ/external/is_primary_organ(var/mob/living/carbon/human/O = null)
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index 8de7cccd2d6..0906b3c63c5 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -11,9 +11,9 @@
var/non_primary = 0
/obj/item/organ/internal/New(var/mob/living/carbon/holder)
+ ..()
if(istype(holder))
insert(holder)
- ..()
/obj/item/organ/internal/Destroy()
if(owner)
@@ -412,7 +412,8 @@
colourmatrix = null
dark_view = 2
..() //Make sure the organ's got the robotic status indicators before updating the client colour.
- owner.update_client_colour(0) //Since both mechassisted and mechanical eyes give dark_view of 2 and full colour vision atm, just having this here is fine as mechassist() will call it anyway.
+ if(owner)
+ owner.update_client_colour(0) //Since both mechassisted and mechanical eyes give dark_view of 2 and full colour vision atm, just having this here is fine as mechassist() will call it anyway.
/obj/item/organ/internal/mechassist()
..() //Go back, call robotize(), adjust the robotic status indicators and the organ damage parameters.
diff --git a/code/modules/surgery/organs/pain.dm b/code/modules/surgery/organs/pain.dm
index f0b4b912eaf..7852ac05a5b 100644
--- a/code/modules/surgery/organs/pain.dm
+++ b/code/modules/surgery/organs/pain.dm
@@ -55,7 +55,7 @@ mob/living/carbon/human/proc/custom_pain(var/message, var/flash_strength)
return
var/msg = "[message]"
if(flash_strength >= 1)
- msg = "\red [message]"
+ msg = "[message]"
// Anti message spam checks
if(msg && ((msg != last_pain_message) || (world.time >= next_pain_time)))
diff --git a/code/modules/surgery/organs/parasites.dm b/code/modules/surgery/organs/parasites.dm
index 3d1917fe258..0adca48bfd0 100644
--- a/code/modules/surgery/organs/parasites.dm
+++ b/code/modules/surgery/organs/parasites.dm
@@ -28,7 +28,7 @@
owner.emote("scream")
var/spiders = rand(3,5)
for(var/i in 1 to spiders)
- new/obj/effect/spider/spiderling(get_turf(owner))
+ new/obj/structure/spider/spiderling(get_turf(owner))
owner.visible_message("[owner] bursts open! Holy fuck!")
owner.gib()
@@ -60,23 +60,23 @@
// the spider eggs secrete stimulants to keep their host alive until they hatch
switch(current_cycle)
if(1) // immediately
- to_chat(owner,"Your spider bite wound hurts horribly! ")
- if(istype(get_area(owner), /area/awaycontent) || istype(get_area(owner), /area/awaymission))
+ to_chat(owner,"Your wound hurts horribly! ")
+ if(is_away_level(owner.z))
awaymission_infection = 1
- if(15) // 30 seconds... enough time for the nerve agent to kick in, the pain to be blocked, and healing to begin
+ if(15) // 30s... enough time for the nerve agent to kick in, the pain to be blocked, and healing to begin
to_chat(owner,"The pain has faded, and stopped bleeding, though the skin around it has turned black.")
owner.adjustBruteLoss(-10)
- if(60) // 2 minutes... the point where the venom uses and accellerates the healing process, to feed the eggs
+ if(30) // 1m... the point where the venom uses and accellerates the healing process, to feed the eggs
to_chat(owner,"Your bite wound has completely sealed up, though the skin is still black. You feel significantly better.")
owner.adjustBruteLoss(-20)
- if(120) // 4 minutes... where the eggs are developing, and the wound is turning into a hatching site, but invisibly
+ if(90) // 3m... where the eggs are developing, and the wound is turning into a hatching site, but invisibly
to_chat(owner,"The black flesh around your old spider bite wound has started to peel off.")
- if(150) // 5 minutes... where the victim realizes something is wrong - this is not a normal wound
+ if(100) // 3m20s... where the victim realizes something is wrong - this is not a normal wound
to_chat(owner,"The black flesh around your spider bite wound has cracked, and started to split open!")
- if(165) // 5m 30s
+ if(110) // 3m40s...
to_chat(owner,"The black flesh splits open completely, revealing a cluster of small black oval shapes inside you, shapes that seem to be moving!")
- if(180) // 6m
- if(awaymission_infection && is_away_level(owner.z))
+ if(120) // 4m...
+ if(awaymission_infection && !is_away_level(owner.z))
// we started in the awaymission, we ended on the station.
// To prevent someone bringing an infection back, we're going to trigger an alternate, equally-bad result here.
// Actually, let's make it slightly worse... just to discourage people from bringing back infections.
@@ -86,17 +86,17 @@
owner.Stun(20)
owner.Weaken(20)
// yes, this is a long stun - that's intentional. Gotta give the spiderlings time to escape.
- var/obj/effect/spider/spiderling/terror_spiderling/S1 = new(get_turf(owner))
+ var/obj/structure/spider/spiderling/terror_spiderling/S1 = new(get_turf(owner))
S1.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/red
S1.name = "red spiderling"
if(prob(50))
S1.stillborn = 1
- var/obj/effect/spider/spiderling/terror_spiderling/S2 = new(get_turf(owner))
+ var/obj/structure/spider/spiderling/terror_spiderling/S2 = new(get_turf(owner))
S2.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/gray
S2.name = "gray spiderling"
if(prob(50))
S2.stillborn = 1
- var/obj/effect/spider/spiderling/terror_spiderling/S3 = new(get_turf(owner))
+ var/obj/structure/spider/spiderling/terror_spiderling/S3 = new(get_turf(owner))
S3.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/green
S3.name = "green spiderling"
if(prob(50))
@@ -108,7 +108,7 @@
owner.gib()
else
owner.adjustToxLoss(rand(100,180)) // normal case, range: 100-180, average 140, almost crit (150).
- if(190) // 6m 30s
+ if(130) // 4m 20s
to_chat(owner,"The spiderlings are gone. Your wound, though, looks worse than ever. Remnants of tiny spider eggs, and dead spiders, inside your flesh. Disgusting.")
qdel(src)
diff --git a/code/modules/surgery/organs/robolimbs.dm b/code/modules/surgery/organs/robolimbs.dm
index c3d7f1c3828..2d31942059c 100644
--- a/code/modules/surgery/organs/robolimbs.dm
+++ b/code/modules/surgery/organs/robolimbs.dm
@@ -119,4 +119,23 @@ var/global/datum/robolimb/basic_robolimb
company = "Zeng-Hu Pharmaceuticals"
desc = "This limb has a rubbery fleshtone covering with visible seams."
icon = 'icons/mob/human_races/cyberlimbs/zenghu/zenghu_main.dmi'
- has_subtypes = 2
\ No newline at end of file
+ has_subtypes = 2
+
+/datum/robolimb/shellguard
+ company = "Shellguard Munitions Standard Series"
+ desc = "This limb features exposed robust steel and paint to match Shellguards motifs"
+ icon = 'icons/mob/human_races/cyberlimbs/shellguard/shellguard_main.dmi'
+ has_subtypes = 1
+
+/datum/robolimb/shellguard/alt1
+ company = "Shellguard Munitions Elite Series"
+ icon = 'icons/mob/human_races/cyberlimbs/shellguard/shellguard_alt1.dmi'
+ parts = list("head")
+ has_subtypes = null
+
+/datum/robolimb/shellguard/monitor
+ company = "Shellguard Munitions Monitor Series"
+ icon = 'icons/mob/human_races/cyberlimbs/shellguard/shellguard_monitor.dmi'
+ parts = list("head")
+ is_monitor = 1
+ has_subtypes = null
\ No newline at end of file
diff --git a/code/modules/surgery/organs/subtypes/machine.dm b/code/modules/surgery/organs/subtypes/machine.dm
index b3bb3f61e07..44d7a7f1315 100644
--- a/code/modules/surgery/organs/subtypes/machine.dm
+++ b/code/modules/surgery/organs/subtypes/machine.dm
@@ -150,8 +150,7 @@
var/obj/item/device/mmi/stored_mmi
/obj/item/organ/internal/brain/mmi_holder/Destroy()
- if(stored_mmi)
- qdel(stored_mmi)
+ QDEL_NULL(stored_mmi)
return ..()
/obj/item/organ/internal/brain/mmi_holder/insert(var/mob/living/target,special = 0)
diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm
index 73416045624..df9ab4dde20 100644
--- a/code/modules/surgery/organs_internal.dm
+++ b/code/modules/surgery/organs_internal.dm
@@ -69,7 +69,7 @@
var/implements_extract = list(/obj/item/weapon/hemostat = 100, /obj/item/weapon/kitchen/utensil/fork = 55)
var/implements_mend = list(/obj/item/stack/medical/bruise_pack = 20,/obj/item/stack/medical/bruise_pack/advanced = 100,/obj/item/stack/nanopaste = 100)
//Finish is just so you can close up after you do other things.
- var/implements_finsh = list(/obj/item/weapon/scalpel/manager = 120,/obj/item/weapon/retractor = 100 ,/obj/item/weapon/crowbar = 75)
+ var/implements_finsh = list(/obj/item/weapon/scalpel/laser/manager = 100,/obj/item/weapon/retractor = 100 ,/obj/item/weapon/crowbar = 75)
var/current_type
var/obj/item/organ/internal/I = null
var/obj/item/organ/external/affected = null
@@ -368,10 +368,6 @@
/datum/surgery_step/cut_carapace
name = "cut carapace"
allowed_tools = list(
- /obj/item/weapon/scalpel/laser3 = 115, \
- /obj/item/weapon/scalpel/laser2 = 110, \
- /obj/item/weapon/scalpel/laser1 = 105, \
- /obj/item/weapon/scalpel/manager = 120, \
/obj/item/weapon/scalpel = 100, \
/obj/item/weapon/kitchen/knife = 75, \
/obj/item/weapon/shard = 50, \
@@ -406,7 +402,7 @@
name = "retract carapace"
allowed_tools = list(
- /obj/item/weapon/scalpel/manager = 120, \
+ /obj/item/weapon/scalpel/laser/manager = 100, \
/obj/item/weapon/retractor = 100, \
/obj/item/weapon/crowbar = 75, \
/obj/item/weapon/kitchen/utensil/fork = 50
diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm
index 8caac8e70eb..87f676c7903 100644
--- a/code/modules/surgery/other.dm
+++ b/code/modules/surgery/other.dm
@@ -4,7 +4,7 @@
//////////////////////////////////////////////////////////////////
/datum/surgery/infection
- name = "External Infection Treatment/Autopsy"
+ name = "External Infection Treatment"
steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/cauterize)
possible_locs = list("chest","head","groin", "l_arm", "r_arm", "l_leg", "r_leg", "r_hand", "l_hand", "r_foot", "l_foot")
diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm
index d3d5345cb0b..e1dc252412d 100644
--- a/code/modules/surgery/robotics.dm
+++ b/code/modules/surgery/robotics.dm
@@ -398,11 +398,16 @@
return
var/obj/item/organ/external/affected = target.get_organ(target_zone)
+ var/found_damaged_organ = FALSE
for(var/obj/item/organ/internal/I in affected.internal_organs)
- if(I && I.damage > 0)
- if(I.robotic >= 2)
- user.visible_message("[user] starts mending the damage to [target]'s [I.name]'s mechanisms.", \
- "You start mending the damage to [target]'s [I.name]'s mechanisms." )
+ if(I && I.damage > 0 && I.robotic >= 2)
+ user.visible_message("[user] starts mending the damage to [target]'s [I.name]'s mechanisms.", \
+ "You start mending the damage to [target]'s [I.name]'s mechanisms.")
+ found_damaged_organ = TRUE
+
+ if(!found_damaged_organ)
+ to_chat(user, "There are no damaged components in [affected].")
+ return -1
target.custom_pain("The pain in your [affected.name] is living hell!",1)
@@ -425,6 +430,7 @@
user.visible_message(" [user] repairs [target]'s [I.name] with [tool].", \
" You repair [target]'s [I.name] with [tool]." )
I.damage = 0
+ I.surgeryize()
else if(current_type == "insert")
var/obj/item/organ/internal/I = tool
diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm
index defa57b3ca4..de3d84796f4 100644
--- a/code/modules/surgery/surgery.dm
+++ b/code/modules/surgery/surgery.dm
@@ -99,22 +99,22 @@
return
surgery.step_in_progress = 1
+ var/speed_mod = 1
+
if(begin_step(user, target, target_zone, tool, surgery) == -1)
surgery.step_in_progress = 0
return
- var/advance = 0
- var/prob_chance = 100
+ if(tool)
+ speed_mod = tool.toolspeed
- if(implement_type) //this means it isn't a require nd or any item step.
- prob_chance = min(allowed_tools[implement_type], 100)
- prob_chance *= get_location_modifier(target)
-
- if(prob_chance > 100)//if we are using a super tool
- time = time/prob_chance //PLACEHOLDER VALUES
-
- if(do_after(user, time, target = target))
+ if(do_after(user, time * speed_mod, target = target))
+ var/advance = 0
+ var/prob_chance = 100
+ if(implement_type) //this means it isn't a require nd or any item step.
+ prob_chance = allowed_tools[implement_type]
+ prob_chance *= get_location_modifier(target)
if(prob(prob_chance) || isrobot(user))
if(end_step(user, target, target_zone, tool, surgery))
diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm
index 2e47438eb44..b0014a391a3 100644
--- a/code/modules/surgery/tools.dm
+++ b/code/modules/surgery/tools.dm
@@ -59,6 +59,7 @@
desc = "Cut, cut, and once more cut."
icon = 'icons/obj/surgery.dmi'
icon_state = "scalpel"
+ item_state = "scalpel"
flags = CONDUCT
force = 10.0
sharp = 1
@@ -82,37 +83,36 @@
/*
* Researchable Scalpels
*/
-/obj/item/weapon/scalpel/laser1 //lasers also count as catuarys
+/obj/item/weapon/scalpel/laser //parent type
+ name = "laser scalpel"
+ desc = "A scalpel augmented with a directed laser."
+ icon_state = "scalpel_laser1_on"
+ damtype = "fire"
+ hitsound = 'sound/weapons/sear.ogg'
+
+/obj/item/weapon/scalpel/laser/laser1 //lasers also count as catuarys
name = "laser scalpel"
desc = "A scalpel augmented with a directed laser. This one looks basic and could be improved."
icon_state = "scalpel_laser1_on"
- item_state = "scalpel"
- damtype = "fire"
- hitsound = 'sound/weapons/sear.ogg'
+ toolspeed = 0.8
-/obj/item/weapon/scalpel/laser2
+/obj/item/weapon/scalpel/laser/laser2
name = "laser scalpel"
desc = "A scalpel augmented with a directed laser. This one looks somewhat advanced."
icon_state = "scalpel_laser2_on"
- item_state = "scalpel"
- damtype = "fire"
- hitsound = 'sound/weapons/sear.ogg'
+ toolspeed = 0.6
-/obj/item/weapon/scalpel/laser3
+/obj/item/weapon/scalpel/laser/laser3
name = "laser scalpel"
desc = "A scalpel augmented with a directed laser. This one looks to be the pinnacle of precision energy cutlery!"
icon_state = "scalpel_laser3_on"
- item_state = "scalpel"
- damtype = "fire"
- hitsound = 'sound/weapons/sear.ogg'
+ toolspeed = 0.4
-/obj/item/weapon/scalpel/manager //super tool! Retractor/hemostat
+/obj/item/weapon/scalpel/laser/manager //super tool! Retractor/hemostat
name = "incision management system"
desc = "A true extension of the surgeon's body, this marvel instantly and completely prepares an incision allowing for the immediate commencement of therapeutic steps."
icon_state = "scalpel_manager_on"
- item_state = "scalpel"
- damtype = "fire"
- hitsound = 'sound/weapons/sear.ogg'
+ toolspeed = 0.2
/obj/item/weapon/circular_saw
name = "circular saw"
diff --git a/code/modules/telesci/bscrystal.dm b/code/modules/telesci/bscrystal.dm
index a2ee8cc85ca..113d2abd751 100644
--- a/code/modules/telesci/bscrystal.dm
+++ b/code/modules/telesci/bscrystal.dm
@@ -9,6 +9,8 @@
points = 50
var/blink_range = 8 // The teleport range when crushed/thrown at someone.
refined_type = /obj/item/stack/sheet/bluespace_crystal
+ toolspeed = 1
+ usesound = 'sound/items/Deconstruct.ogg'
/obj/item/weapon/ore/bluespace_crystal/New()
..()
@@ -58,6 +60,8 @@ var/global/list/datum/stack_recipe/bluespace_crystal_recipes = list(new/datum/st
desc = "A stable polycrystal, made of fused-together bluespace crystals. You could probably break one off."
origin_tech = "bluespace=4;materials=3"
attack_verb = list("bluespace polybashed", "bluespace polybattered", "bluespace polybludgeoned", "bluespace polythrashed", "bluespace polysmashed")
+ toolspeed = 1
+ usesound = 'sound/items/Deconstruct.ogg'
/obj/item/stack/sheet/bluespace_crystal/New()
..()
diff --git a/code/modules/telesci/telepad.dm b/code/modules/telesci/telepad.dm
index 0f1f7c8f582..f8a177e413d 100644
--- a/code/modules/telesci/telepad.dm
+++ b/code/modules/telesci/telepad.dm
@@ -67,7 +67,7 @@
var/stage = 0
/obj/machinery/telepad_cargo/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/weapon/wrench))
- playsound(src, 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(src, W.usesound, 50, 1)
if(anchored)
anchored = 0
to_chat(user, " The [src] can now be moved.")
@@ -76,15 +76,15 @@
to_chat(user, " The [src] is now secured.")
if(istype(W, /obj/item/weapon/screwdriver))
if(stage == 0)
- playsound(src, 'sound/items/Screwdriver.ogg', 50, 1)
+ playsound(src, W.usesound, 50, 1)
to_chat(user, " You unscrew the telepad's tracking beacon.")
stage = 1
else if(stage == 1)
- playsound(src, 'sound/items/Screwdriver.ogg', 50, 1)
+ playsound(src, W.usesound, 50, 1)
to_chat(user, " You screw in the telepad's tracking beacon.")
stage = 0
if(istype(W, /obj/item/weapon/weldingtool) && stage == 1)
- playsound(src, 'sound/items/Welder.ogg', 50, 1)
+ playsound(src, W.usesound, 50, 1)
to_chat(user, " You disassemble the telepad.")
new /obj/item/stack/sheet/metal(get_turf(src))
new /obj/item/stack/sheet/glass(get_turf(src))
@@ -119,6 +119,8 @@
throwforce = 10.0
throw_speed = 2
throw_range = 5
+ toolspeed = 1
+ usesound = 'sound/machines/click.ogg'
var/obj/item/weapon/stock_parts/cell/high/rcell = null
var/obj/machinery/pad = null
var/mode = 0
@@ -126,7 +128,7 @@
var/rand_y = 0
var/emagged = 0
var/teleporting = 0
- var/chargecost = 1500
+ var/chargecost = 1000
/obj/item/weapon/rcs/New()
..()
@@ -138,9 +140,7 @@
to_chat(user, "There are [round(rcell.charge/chargecost)] charge\s left.")
/obj/item/weapon/rcs/Destroy()
- if(rcell)
- qdel(rcell)
- rcell = null
+ QDEL_NULL(rcell)
return ..()
/obj/item/weapon/rcs/attack_self(mob/user)
diff --git a/code/modules/telesci/telesci_computer.dm b/code/modules/telesci/telesci_computer.dm
index b35968625e5..aa65b6337d5 100644
--- a/code/modules/telesci/telesci_computer.dm
+++ b/code/modules/telesci/telesci_computer.dm
@@ -80,10 +80,10 @@
/obj/machinery/computer/telescience/emag_act(user as mob)
if(!emagged)
- to_chat(user, "\blue You scramble the Telescience authentication key to an unknown signal. You should be able to teleport to more places now!")
+ to_chat(user, "You scramble the Telescience authentication key to an unknown signal. You should be able to teleport to more places now!")
emagged = 1
else
- to_chat(user, "\red The machine seems unaffected by the card swipe...")
+ to_chat(user, "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/vehicle/ambulance.dm b/code/modules/vehicle/ambulance.dm
index 7d3f9084f5f..ab64ac1252d 100644
--- a/code/modules/vehicle/ambulance.dm
+++ b/code/modules/vehicle/ambulance.dm
@@ -31,6 +31,8 @@
/obj/vehicle/ambulance/Move(newloc, Dir)
var/oldloc = loc
+ if(bed && !Adjacent(bed))
+ bed = null
. = ..()
if(bed && get_dist(oldloc, loc) <= 2)
bed.Move(oldloc)
diff --git a/code/modules/vehicle/vehicle.dm b/code/modules/vehicle/vehicle.dm
index edfa68f2dbd..2a1ea4c7d64 100644
--- a/code/modules/vehicle/vehicle.dm
+++ b/code/modules/vehicle/vehicle.dm
@@ -16,6 +16,7 @@
//Pixels
var/generic_pixel_x = 0 //All dirs show this pixel_x for the driver
var/generic_pixel_y = 0 //All dirs shwo this pixel_y for the driver
+ var/spaceworthy = FALSE
/obj/vehicle/New()
@@ -130,6 +131,8 @@
/obj/vehicle/Bump(atom/movable/M)
+ if(!spaceworthy && isspaceturf(get_turf(src)))
+ return 0
. = ..()
if(auto_door_open)
if(istype(M, /obj/machinery/door) && buckled_mob)
@@ -153,6 +156,7 @@
/obj/vehicle/space
pressure_resistance = INFINITY
+ spaceworthy = TRUE
/obj/vehicle/space/Process_Spacemove(direction)
return 1
\ No newline at end of file
diff --git a/code/modules/vr/vr_controller.dm b/code/modules/vr/vr_controller.dm
new file mode 100644
index 00000000000..45bf2a6cc74
--- /dev/null
+++ b/code/modules/vr/vr_controller.dm
@@ -0,0 +1,63 @@
+//Control file with the backbone for the vr rooms and avatars
+
+var/datum/vr_rooms = list()
+var/roomcap = 20
+
+/datum/vr_room
+ var/name = null
+ var/datum/map_template/vr/template = null
+ var/datum/space_chunk/chunk = null
+ var/list/spawn_points = list()
+ var/expires = 1
+
+proc/make_vr_room(name, template, expires)
+ var/datum/vr_room/R = new
+ R.name = name
+ R.template = template
+ R.template = vr_templates[R.template]
+ R.chunk = space_manager.allocate_space(R.template.width, R.template.height)
+ R.expires = expires
+ vr_rooms[R.name] = R
+ R.template.load(locate(R.chunk.x,R.chunk.y,R.chunk.zpos), centered = FALSE)
+
+ for(var/atom/landmark in R.chunk.search_chunk(landmarks_list))
+ if(landmark.name == "avatarspawn")
+ R.spawn_points.Add(landmark)
+
+//Control code for the avatars
+proc/build_virtual_avatar(mob/living/carbon/human/H, location, datum/map_template/vr/level/template)
+ if(!location)
+ return
+ var/mob/living/carbon/human/virtual_reality/vr_avatar
+ location = get_turf(location)
+ vr_avatar = new /mob/living/carbon/human/virtual_reality(location)
+ vr_avatar.set_species(H.species.name)
+ if(istype(H, /mob/living/carbon/human/virtual_reality))
+ var/mob/living/carbon/human/virtual_reality/V = H
+ vr_avatar.real_me = V.real_me
+ else
+ vr_avatar.real_me = H
+ vr_avatar.dna = H.dna.Clone()
+ vr_avatar.name = H.name
+ vr_avatar.real_name = H.real_name
+ vr_avatar.undershirt = H.undershirt
+ vr_avatar.underwear = H.underwear
+ vr_avatar.UpdateAppearance()
+ vr_avatar.equipOutfit(template.outfit)
+ return vr_avatar
+
+proc/control_remote(mob/living/carbon/human/H, mob/living/carbon/human/virtual_reality/vr_avatar)
+ if(H.mind)
+ H.mind.transfer_to(vr_avatar)
+
+proc/spawn_vr_avatar(mob/living/carbon/human/H, datum/vr_room/room)
+ room = vr_rooms[room]
+ var/mob/living/carbon/human/virtual_reality/vr_human
+ vr_human = build_virtual_avatar(H, pick(room.spawn_points), room.template)
+ control_remote(H, vr_human)
+ return vr_human
+
+//Preloaded rooms
+/hook/roundstart/proc/starting_levels()
+ make_vr_room("Lobby", "lobby", 0)
+ return 1
\ No newline at end of file
diff --git a/code/modules/vr/vr_outfits.dm b/code/modules/vr/vr_outfits.dm
new file mode 100644
index 00000000000..4f673fd4e8c
--- /dev/null
+++ b/code/modules/vr/vr_outfits.dm
@@ -0,0 +1,15 @@
+//place all the outfits for your levels in here.
+
+/datum/outfit/vr/vr_basic
+ name = "basic vr"
+ uniform = /obj/item/clothing/under/psysuit
+ shoes = /obj/item/clothing/shoes/black
+
+/datum/outfit/vr/roman
+ name = "roman"
+ uniform = /obj/item/clothing/under/roman
+ shoes = /obj/item/clothing/shoes/roman
+ l_hand = /obj/item/weapon/shield/riot/roman
+ r_hand = /obj/item/weapon/twohanded/spear
+ head = /obj/item/clothing/head/helmet/roman
+ back = /obj/item/weapon/twohanded/spear
\ No newline at end of file
diff --git a/code/world.dm b/code/world.dm
index c33b41388f4..ebf4865a1a8 100644
--- a/code/world.dm
+++ b/code/world.dm
@@ -261,7 +261,15 @@ var/world_topic_spam_protect_time = world.timeofday
log_admin("[key_name(usr)] has requested an immediate world restart via client side debugging tools")
spawn(0)
to_chat(world, "Rebooting world immediately due to host request")
- return ..(1)
+ if(config && config.shutdown_on_reboot)
+ sleep(0)
+ if(shutdown_shell_command)
+ shell(shutdown_shell_command)
+ del(world)
+ return
+ else
+ return ..(1)
+
var/delay
if(!isnull(time))
delay = max(0,time)
@@ -271,6 +279,13 @@ var/world_topic_spam_protect_time = world.timeofday
to_chat(world, "An admin has delayed the round end.")
return
to_chat(world, "Rebooting world in [delay/10] [delay > 10 ? "seconds" : "second"]. [reason]")
+
+ var/round_end_sound = pick(round_end_sounds)
+ var/sound_length = round_end_sounds[round_end_sound]
+ if(delay > sound_length) // If there's time, play the round-end sound before rebooting
+ spawn(delay - sound_length)
+ if(!ticker.delay_end)
+ world << round_end_sound
sleep(delay)
if(blackbox)
blackbox.save_all_data_to_sql()
@@ -281,16 +296,19 @@ var/world_topic_spam_protect_time = world.timeofday
log_game("Rebooting world. [reason]")
//kick_clients_in_lobby("The round came to an end with you in the lobby.", 1)
- spawn(0)
- world << sound(pick('sound/AI/newroundsexy.ogg','sound/misc/apcdestroyed.ogg','sound/misc/bangindonk.ogg', 'sound/goonstation/misc/newround1.ogg', 'sound/goonstation/misc/newround2.ogg'))// random end sounds!! - LastyBatsy
-
-
processScheduler.stop()
- for(var/client/C in clients)
- if(config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
- C << link("byond://[config.server]")
- ..(0)
+ if(config && config.shutdown_on_reboot)
+ sleep(0)
+ if(shutdown_shell_command)
+ shell(shutdown_shell_command)
+ del(world)
+ return
+ else
+ for(var/client/C in clients)
+ if(config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
+ C << link("byond://[config.server]")
+ ..(0)
#define INACTIVITY_KICK 6000 //10 minutes in ticks (approx.)
/world/proc/KickInactiveClients()
@@ -309,7 +327,7 @@ var/world_topic_spam_protect_time = world.timeofday
if(C.is_afk(INACTIVITY_KICK))
if(!istype(C.mob, /mob/dead))
log_access("AFK: [key_name(C)]")
- to_chat(C, "\red You have been inactive for more than 10 minutes and have been disconnected.")
+ to_chat(C, "You have been inactive for more than 10 minutes and have been disconnected.")
del(C)
if( ((world.timeofday - sleep_check) > work_length) || ((world.timeofday - sleep_check) < 0) )
sleep(sleep_length)
diff --git a/config/example/away_mission_config.txt b/config/example/away_mission_config.txt
index f440c9a231a..d06e581e04b 100644
--- a/config/example/away_mission_config.txt
+++ b/config/example/away_mission_config.txt
@@ -10,9 +10,7 @@
#===================================#
# BROKEN / INCOMPLETE AWAY MISSIONS #
#===================================#
-#_maps/map_files/RandomZLevels/challenge.dmm
#_maps/map_files/RandomZLevels/centcomAway.dmm
-#_maps/map_files/RandomZLevels/clownplanet.dmm
#_maps/map_files/RandomZLevels/example.dmm
#_maps/map_files/RandomZLevels/spacebattle.dmm
#_maps/map_files/RandomZLevels/stationCollision.dmm
@@ -20,14 +18,15 @@
#===================================#
# USABLE AWAY MISSIONS #
#===================================#
+
_maps/map_files/RandomZLevels/beach.dmm
-_maps/map_files/RandomZLevels/listeningpost.dmm
_maps/map_files/RandomZLevels/moonoutpost19.dmm
_maps/map_files/RandomZLevels/undergroundoutpost45.dmm
_maps/map_files/RandomZLevels/academy.dmm
_maps/map_files/RandomZLevels/blackmarketpackers.dmm
_maps/map_files/RandomZLevels/spacehotel.dmm
_maps/map_files/RandomZLevels/wildwest.dmm
+_maps/map_files/RandomZLevels/terrorspiders.dmm
#===================================#
# SPECIAL AWAY MISSIONS #
diff --git a/config/example/config.txt b/config/example/config.txt
index 4f1a9102c20..b1810dea483 100644
--- a/config/example/config.txt
+++ b/config/example/config.txt
@@ -334,4 +334,10 @@ DISABLE_SPACE_RUINS
#MEDAL_HUB_PASSWORD
## Uncomment this if you want to disable usage of emoji in OOC
-#DISABLE_OOC_EMOJI
\ No newline at end of file
+#DISABLE_OOC_EMOJI
+
+## Uncomment this to shut down the world any time it would normally reboot
+#SHUTDOWN_ON_REBOOT
+## A command to run prior to the world shutting down, only used if the above option is enabled
+## This default value will kill Dream Daemon on Windows machines
+#SHUTDOWN_SHELL_COMMAND taskkill /f /im dreamdaemon.exe
\ No newline at end of file
diff --git a/config/example/custom_sprites.txt b/config/example/custom_sprites.txt
index db3930a4ae2..471764270d4 100644
--- a/config/example/custom_sprites.txt
+++ b/config/example/custom_sprites.txt
@@ -1 +1,5 @@
-ckey-state
\ No newline at end of file
+Each entry should be composed of 2 parts, divided by a colon (:) with no spaces, in order to work. Failure to do so will result in that entry being disregarded by the code.
+- The first part should be either "cyborg", "ai", "hologram", "pai", or "drone". This tells the code what type of custom sprite this entry is for. The "ai" option is for AI core displays, while "hologram" is for AI hologram projections.
+- The second part should be the ckey of the player this entry is for. This tells the code who it works for and also is used to retrieve the proper sprite for them to use.
+
+example:example
\ No newline at end of file
diff --git a/config/names/death_commando.txt b/config/names/death_commando.txt
index e3d1f34f327..fbb7a17e6f6 100644
--- a/config/names/death_commando.txt
+++ b/config/names/death_commando.txt
@@ -67,4 +67,4 @@ AMERICA
Toolboxl Rose
Zombie Gandhi
A whole bunch of spiders in a SWAT suit
-THAT DAMN FAGGOT TRAITOR GEORGE MELONS
\ No newline at end of file
+THAT DAMN TRAITOR GEORGE MELONS
\ No newline at end of file
diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css
index 77984467afb..113fb45df05 100644
--- a/goon/browserassets/css/browserOutput.css
+++ b/goon/browserassets/css/browserOutput.css
@@ -242,20 +242,20 @@ em {font-style: normal; font-weight: bold;}
.yell { font-weight: bold;}
.siliconsay {font-family: 'Courier New', Courier, monospace;}
.deadsay {color: #5c00e6;}
-.radio {color: #008000;}
+.radio {color: #408010;}
.deptradio {color: #993399;}
-.comradio {color: #193A7A;}
-.syndradio {color: #6d3f40;}
+.comradio {color: #204090;}
+.syndradio {color: #6D3F40;}
.dsquadradio {color: #686868;}
.resteamradio {color: #18BC46;}
.airadio {color: #FF00FF;}
-.centradio {color: #5C5C8A;}
+.centradio {color: #5C5C7C;}
.secradio {color: #A30000;}
.engradio {color: #A66300;}
-.medradio {color: #008160;}
+.medradio {color: #009190;}
.sciradio {color: #993399;}
-.supradio {color: #5F4519;}
-.srvradio {color: #6eaa2c;}
+.supradio {color: #7F6539;}
+.srvradio {color: #80A000;}
.admin_channel {color: #9A04D1; font-weight: bold;}
.mentor_channel {color: #775BFF; font-weight: bold;}
.mentor_channel_admin {color: #A35CFF; font-weight: bold;}
diff --git a/html/changelog.html b/html/changelog.html
index a0c2cfa1aa4..c46b02ff232 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -55,6 +55,923 @@
-->
+
21 April 2017
+
Anticept updated:
+
+
Alternate Job Preference now defaults to "Return to Lobby if Preferences Unavailable". Only affects new players.
+
+
Fox McCloud updated:
+
+
Tesla can now damage blobs
+
Tesla causes machinery to overload and explode when zapping it
+
Tesla dissipates energy more slowly and is easier to charge up (making it more deadly when released)
+
Tesla will now dust mobs it bumps into
+
Tesla coils now have wires that can be pulsed to generate a tesla zap
+
+
Lady-Luck updated:
+
+
Makes several balance adjustments to existing syndicate bundles, generally making them more worthwhile.
+
Adds an Allies Cocktail object for the Bond bundle.
+
Adds the 'gadgets' syndicate bundle.
+
Removes the 'lordsingulo' and 'murder' syndicate bundles.
+
+
Spacemanspark updated:
+
+
Permits hoodies to carry flashlights.
+
+
Twinmold93 updated:
+
+
Adds attack options for deep fryers, grills, and ovens. Those breaking into the kitchen beware.
+
+
+
19 April 2017
+
IK3I updated:
+
+
Chaplain now spawns with his bible
+
+
Xantholne updated:
+
+
You now correctly spawn with the CMO Skirt if selected in loadout menu
+
+
+
17 April 2017
+
KasparoVy updated:
+
+
The God-emperor of Mankind diskette's UI works again.
+
DNA UI injectors will now immediately update a person's eye colour.
+
+
Krausus updated:
+
+
You can no longer squeeze non-match objects into matchboxes.
+
+
+
16 April 2017
+
FalseIncarnate updated:
+
+
Potential collaborators for traitors now are informed they are potentially a collaborator for a potential increase in them potentially helping the traitors potentially do potentially bad things. Potentially.
+
Potential collaborators are given a single code word and response set so they can discretely find out that their best friend is a filthy traitor.
+
+
KasparoVy updated:
+
+
Adds secondary (facial) hair colours to the genome (UI). There are 6 new blocks.
+
Characters with secondary (facial) hair colours won't find they've turned black after cloning anymore.
+
+
Kyep updated:
+
+
Plasma dust no longer creates plasma gas on objects or turfs during reactions.
+
+
Twinmold93 updated:
+
+
Missing sprite for pod pilot Drask now added.
+
+
Xantholne updated:
+
+
Adds Medical Beret available via loadout menu
+
+
ZomgPonies updated:
+
+
Fixes Superhero ID cards
+
Fixes Griffin missing his Freedom Implant
+
Fixes ElectroNegmatic's Ability not working at all.
+
Changes LightnIan's ability into a non-damaging stun lasting 2 ticks, with the amount of people affected depending on how long you hold the power in for.
+
+
uraniummeltdown updated:
+
+
You can now create heat-proof glass airlocks by using a sheet of reinforced glass on the assembly during construction. Regular glass airlocks just require a sheet of glass.
+
+
+
11 April 2017
+
FalseIncarnate updated:
+
+
Damage done to the shuttle engines by a shadowling's "Extend Shuttle" ability now prevent the shuttle from being recalled to CentComm.
+
+
+
09 April 2017
+
Fox McCloud updated:
+
+
abductor glands now act as actual hearts; removing them induces heart failure
+
plasma gland no longer gibs you, but makes you vomit plasma instead
+
bodysnatcher gland no longer gibs you, but will deal brute damage instead
+
bloody gland will now drain blood instead of dealing brute damage
+
species change gland will now change your species until the gland is removed
+
adjusted the origin tech on a few gland
+
heart attacks will once again paralyse you and do slightly more brute damage
+
body snatch clones look more like their originator
+
Abductors can no longer use guns (minus their own alien energy gun)
+
Sending someone with an abductor teleport via the console will stun them for 3 cycles (doesn't apply with the advanced camera console)
+
Abductors can now purchase additional abductor vests
+
Abductors can lock/unlock vests
+
Purchasing supplies from the abductor console will no longer increase the amount of experiments you must do
+
Wonderprods will not induce sleep in those who are stunned OR sleeping
+
altered the origin tech of abductor tools
+
Can make abductor surgery tables from regular tables by adding silver sheets to an abductor table frame
+
Added a bunch more abductee objectives
+
abductors no long scream like girls
+
High capacity cells have 10,000 charge instead of 15,000
+
Mech equipment power costs minorly adjusted
+
APCs charge a bit faster
+
EMPs less effective against pods and mechs
+
Fixes not being able to recharge modular laptops/tablets
+
+
Purpose2 updated:
+
+
Welders must now been fueled and active to cut lattices.
+
+
+
06 April 2017
+
Fox McCloud updated:
+
+
Fixes autopsy report printing; print reports by clicking the device itself
+
+
davipatury updated:
+
+
Rapid Cable Layer now have an autolathe design.
+
+
+
05 April 2017
+
KasparoVy updated:
+
+
Adds a Tajaran facial hair style.
+
Adds a few new frill styles for Unathi.
+
Adds some new horn styles for Unathi.
+
Adds a couple new facial hair styles for Vulpkanin.
+
Adds a few new hair styles for Vulpkanin.
+
Updates Vulpkanin Adhara & Kajam hairstyles.
+
+
Purpose2 updated:
+
+
Can now take photos of the Blueprints to count as a completed objective.
+
Cryostorage console now stores the Null Rod & all variations.
+
Mime mech is now 'Reticence' as it should be
+
Fixes missing cult's Berserker Robe sprite.
+
Cryostorage console no longer stores hundreds of bomber jackets, and now stores hardsuits
+
Cryostorage console now catches and stores most unique objective items.
+
Corrects some typos and grammar.
+
You can now light cigarettes with Wands of Fireball, at the cost of your eyebrows.
+
+
Twinmold93 updated:
+
+
Buying poison pen will actually give you the poison pen now.
+
+
+
04 April 2017
+
FalseIncarnate updated:
+
+
Adds FullofSkittles's custom pAI sprites. Thanks FoS!
+
Custom sprites for cyborgs, AI, AI holograms, and pAI units no longer are restricted to a single name. Get your money's worth by using that borg sprite regardless of your version number!
+
+
+
03 April 2017
+
Kyep updated:
+
+
Ghosts manifested by cultists are no longer invincible, and an exploit allowing them to be made permanent has been fixed.
+
+
+
02 April 2017
+
KasparoVy updated:
+
+
Nuclear Operatives/ERT Members/Abductors will no longer spawn in with genetic quirks.
+
Thrown objects that cross a tile with non-full windows will no longer hit the window even if it isn't visually obstructing the path.
+
Shooting guns (i.e. tasers) in the above circumstances means that the taser shots won't be blocked by windows that aren't visually obstructing the path.
+
+
Kyep updated:
+
+
Adjusted Black Market Packers away mission. It now has some danger to it (carp), some more interesting stuff to find (syndi lab) and a challenge (fix the ship powergrid).
+
Slight adjustment to word lists based on our rules.
+
Removed thunderdome armor from centcom away mission.
+
Cultists now get a new sacrifice target when the current one cryos.
+
+
+
31 March 2017
+
Krausus updated:
+
+
Blobs are no longer nearly guaranteed to immediately tear themselves apart upon spawning.
+
+
Kyep updated:
+
+
Access to jobs is now based solely on Playtime, NOT days since BYOND account was registered.
+
+
+
30 March 2017
+
Crazylemon64 updated:
+
+
Cult shifter should work now
+
+
FlattestGuitar updated:
+
+
Strange Reagent only deals clone damage on a successful revival.
+
+
Fox McCloud updated:
+
+
Non-designated drinks now mix their colors from the reagents within them
+
Autopsies can now be performed without needing to cut someone open
+
Adds modular receiver to the maintenance loot system
+
Receivers can now be produced in hacked autolathes; no longer available in R&D protolathes.
+
removes the random "scary" sounds that play when walking about
+
+
KasparoVy updated:
+
+
You can now slam drinks/bottles/flasks by click-dragging them onto yourself while it's in your active hand.
+
+
Kyep updated:
+
+
The moonoutpost19 away mission should now be finishable, and more enjoyable to attempt.
+
+
uraniummeltdown updated:
+
+
Emagging a closed firelock does not permanently break it anymore, only opens it.
+
Emagged windoors should be able to be screwdriver+crowbar'd again.
+
Powered grilles now have a chance to zap you when you throw an object at them.
+
+
+
29 March 2017
+
Purpose2 updated:
+
+
'Roundstart malfunctioning' cameras now appropriately have their wires cut.
+
AI core camera can no longer be a 'roundstart malfunctioning' camera on both Box & Meta Stations.
+
+
+
28 March 2017
+
KasparoVy updated:
+
+
Skrell can now choose undergarments (undershirts, underpants, socks) at character creation and dressers.
+
Vox are now 20% less resilient to brute damage due to their light, porous and flexible skeletons.
+
+
uraniummeltdown updated:
+
+
Quick-replacing non-wooden tiles will only work with a crowbar in inactive hand instead of any item
+
+
+
27 March 2017
+
Crazylemon64 updated:
+
+
Away mission power works now.
+
+
Fox McCloud updated:
+
+
Fixes some stacks not wanting to stack with similar stacks (such as space cash)
+
+
KasparoVy updated:
+
+
Skrell have been greyscaled and darkened. You can now colour your Skrell characters as you please.
+
Kidan can now select from multiple different antennae head-accessory styles.
+
Kidan male/female bodies now have differences, namely mandible/torso structure.
+
Skrell flesh is now blue (like their blood), though you'll only ever see this under certain circumstances if they're dismembered.
+
+
Kyep updated:
+
+
The invisible floors in the engineering area of the UO45 away mission are no longer invisible. Previously, you had to crowbar up a seemingly invisible floor to make a wire appear.
+
Fixed several Terror Spider bugs. Including the notorious 'spiders can get stuck in vents' bug, the 'spiders ignore mechs' bug, and the 'prince is cheesable' bug.
+
Adjusted White & Empress spider abilities - webs spun by white spiders are now infectious.
+
+
Purpose2 updated:
+
+
Adds the Psychiatrist's bed/sofa for 5 metal.
+
Wooden chairs broken by animals no longer drop metal.
+
Abductors no longer have Syndicate ties.
+
Fixes material loss on some chair/bed/stool deconstruction types.
+
IPCs can no longer be DNA Scrambled.
+
Health analysers clunk again when upgraded
+
Resolves further grammatical/typo issues.
+
+
+
26 March 2017
+
FalseIncarnate updated:
+
+
Re-adds the telescopic scythe, the pinnacle of covert reaping technologies. Currently admin-spawn only, for use in the most dire of harvest times.
+
Scythes (normal and telescopic) should once again clear swathes through all but the hardiest of vines when in proper reaping configurations, and heavily damage those they don't outright destroy.
+
Ankle-high piles of dirt will no longer prevent you from stepping over them.
+
+
KasparoVy updated:
+
+
You can no longer climb through interdimensional rifts into cryopods.
+
Revenants can see properly in the dark again.
+
+
Kyep updated:
+
+
Adjusted Beach awaymission so it now includes deadly (but rewarding) pirate area.
+
Adjusted the centcom away mission to make it viable.
+
Deleted 'listening post' away mission.
+
+
Purpose2 updated:
+
+
QoL: Newly built APCs come unlocked.
+
QoL: Chief Engineer's locker has more building permits.
+
Assorted grammatical fixes.
+
+
Ty-Omaha updated:
+
+
Splints will display the proper sentence when applying them
+
+
uraniummeltdown updated:
+
+
Metastation: Fixed Gateway airlock access and Command Hallway vendor areas, virology smartfridge is correctly stocked, mass drivers now have tiny fans, Sec spacepod keys work on the Sec pod, Airlocks should have the correct icon, Firelocks/Windoors/Shutters should be layered correctly, Shutters should be facing the right direction
+
Drone fabricator consoles search for a fabricator in the same area instead of 3x3 range.
+
+
+
25 March 2017
+
Crazylemon64 updated:
+
+
All pens are now certified crayon-wax free!
+
+
Kyep updated:
+
+
Pipes in the Wizard Academy have been banished back under the carpet, where they belong.
+
+
+
24 March 2017
+
KasparoVy updated:
+
+
Red wire-cutters and red crowbars now appear correctly in-hands again. imgadd: The medical wrench and all the brass tools (screwdriver, crowbar, wrench, wire-cutters, welder) now have in-hand sprites of their own.
+
Adds TG's inhand icons for screwdrivers, crowbars, wrenches, wire-cutters and welders.
+
Slime People can wear underwear, undershirts and socks.
+
+
uraniummeltdown updated:
+
+
IV Drips are no longer dense objects, you can walk over them.
+
You can change gold and silver tiles into fancy versions by using them in hand.
+
+
+
23 March 2017
+
FalseIncarnate updated:
+
+
Fish breeding has been tweaked to support fish refusing to cross-breed and improved egg chances with same-species parents.
+
+
Fox McCloud updated:
+
+
Floors are now fully properly cleaned with mops and soap
+
Adds in emergency welding tool, fork, trays, drinking glasses, shot glasses, shakers, butcher cleavers, and riot darts to the autolathe
+
Adds all basic stock parts to the autolathe
+
re-arranges the autolathe menu to be more logical
+
light bulbs no longer require metal to produce
+
Incision management system can now cauterize
+
+
KasparoVy updated:
+
+
Unathi Security, Medical, Engineering and Syndicate side-facing hardsuit sprites have undergone weight reduction.
+
+
Kyep updated:
+
+
Chaplain's armor is no longer riot-grade. In addition, their nullrods do less damage.
+
+
MarsM0nd updated:
+
+
Conveyor switches can now set to left-only direction toggling.
+
+
Norgad updated:
+
+
Maintenance areas near arrivals, science, and the bar have been revamped.
+
+
uraniummeltdown updated:
+
+
Station lighting has less lighting power, this is not noticeable apart from maint and 1 bulb rooms being a bit darker.
+
Tweaked the potency scaling for glowshroom/glowberry light; high-potency plants no longer light up a huge area, but are slightly brighter.
+
Added Shadowshrooms as a glowshroom mutation. They do exactly what you'd expect.
+
+
+
22 March 2017
+
Crazylemon64 updated:
+
+
Rod form is now at half speed, and has a warning sound.
+
+
FlattestGuitar updated:
+
+
When a person's limb is dying, it will no longer notify the whole server of the ordeal
+
Welding tools no longer tell you about their span classes
+
+
KasparoVy updated:
+
+
Deconstructing beds now yields the same amount of metal as was used to make the bed.
+
The PA console will no longer appear as though it is fully constructed at the start of the round.
+
Ore Redemption Machines no longer eat IDs when deconstructed.
+
Ore Redemption Machines and Mining Equipment Vendors now spit out whatever IDs were in them when they lose power.
+
+
Krausus updated:
+
+
Personal crafting is now usable again for those with an Internet Explorer version below 11.
+
+
+
21 March 2017
+
Crazylemon64 updated:
+
+
Strange reagent now has a volume floor requirement to activate, induces clone damage, and may cause further trouble...
+
+
KasparoVy updated:
+
+
No-one escapes nuclear hellfire.
+
Secure fridges/freezers are now lead-lined and have thus become nuke resistant.
+
+
uraniummeltdown updated:
+
+
Baseball bats added to the game, are craftable from 5 wood planks.
+
Baseball burgers can be made with a baseball bat and a bun, either microwaved or table-crafted.
Fixes the exploit to produce infinite cable coil from airlocks.
+
+
Tayyyyyyy updated:
+
+
Added GPS devices to pod pilot and mechanic's offices
+
+
+
19 March 2017
+
Jovaniph updated:
+
+
Voxes can now wear soft caps.
+
+
Krausus updated:
+
+
Pest spray bottles are no longer invisible.
+
+
Kyep updated:
+
+
Wood doors in wild west map no longer constantly open/close
+
+
uraniummeltdown updated:
+
+
Shipping errors can sometimes cause the supply shuttle to receive an extra crate when ordering supplies.
+
Added dog beds! Can be made with 10 wood planks and deconstructed with a wrench. Ian's Bed added to Cyberiad and Metastation.
+
+
+
18 March 2017
+
Fox McCloud updated:
+
+
Fixes abductor surgeries
+
+
Jovaniph updated:
+
+
Unathi EVA suits
+
+
uraniummeltdown updated:
+
+
Shades now have directional sprites.
+
Attacking with glass shards now hurts your hand if not wearing gloves. Does not affect robotic hands though.
+
+
+
16 March 2017
+
FlattestGeetar updated:
+
+
Workboots are now in the loadout system.
+
Ports winter boots from /tg/
+
+
Jovaniph updated:
+
+
New sounds to Firelocks and Airlock External
+
Door closing sound to Airlocks - from yogstation
+
+
Markolie updated:
+
+
Fixed revenant night vision not working.
+
Fixed the "X attacked Y" message showing up when welding vents.
+
Fixed the follow button on the cell door timer radio message not working.
+
Fixed the Jaws of Life being unable to force unpowered doors.
+
Fixed a number of preference options being unavailable when modifying preferences while observing.
+
Fixed an issue where deleting security records wouldn't clear that player's wanted status properly.
+
Fixed the cult "first meal" sacrifice objective not counting properly. Also clarified what this objective actually entailed.
+
Fixed IPC's ocassionally being selected as a changeling "escape with X identity" target.
+
The character records and disabilities menus in the preferences menu no longer uses the plain white background, but uses the better looking blue layout instead.
+
+
+
15 March 2017
+
uraniummeltdown updated:
+
+
Plastic flaps can be deconstructed with tools and constructed using 5 sheets of plastic.
+
You can now damage grilles by throwing things at them.
+
You can rebuild broken grilles by using a metal rod on them.
+
Metal rods maximum amount reduced from 60 to 50.
+
+
+
14 March 2017
+
uraniummeltdown updated:
+
+
Strong supply talismans can now summon 5 sheets of runed metal.
+
+
+
13 March 2017
+
Kyep updated:
+
+
Syndicate mobs in the Wild West are no longer so stupid that they trip over, and die to, their own mines. This also means that they won't set their own buildings on fire anymore.
+
Phazons' phase ability now works again.
+
Phazons' toxin injector melee damage type (a weak melee attack) now works again.
+
+
uraniummeltdown updated:
+
+
Clicking on a tile with another tile and a crowbar or screwdriver in hand directly replaces the tile.
+
+
+
12 March 2017
+
Crazylemon64 updated:
+
+
Kudzu should now be less of (but still) a station-destroying force of nature.
+
Bluespace kudzu now only pierces a single layer of walls before losing its "charge".
+
Aggressive spread now does not bust rwalls, but does attack obstructing objects in its path.
+
Kudzu now only spreads on space turfs when it has specific mutations to do so.
+
Kudzu events should be more interesting on their own.
+
+
Jovaniph updated:
+
+
Adds Vulpkanin EVA suit sprite
+
+
Kyep updated:
+
+
Adjusted Wizard Academy to make it both more lethal, and more rewarding.
+
+
Markolie updated:
+
+
The system for picking ghosts to inhabit cultist slaughter demons now shows a confirmation prompt like most other role checks.
+
Fixed an issue where you could join as a cultist slaughter demon despite having antagHUD enabled.
+
Fixed an issue where it was possible to weld statues without any fuel.
+
It is no longer possible to spam the firelock force message.
+
+
Twinmold93 updated:
+
+
Employment record laptop to Head of Personnel's Office. Moves package wrap that was there to meeting room to be paired with the hand labeler there.
+
+
+
11 March 2017
+
Developed by XDTM, ported by davipatury updated:
+
+
Hallucinations have been modified to increase the creepiness factor and reduce the boring factor.
+
Added some new hallucinations.
+
Fixed a bug where the singularity hallucination was stunning for longer than intended and leaving the fake HUD crit icon permanently.
+
+
Flatty Patty updated:
+
+
all the tools have icons again
+
+
FlattyPatty updated:
+
+
Improved Nanotrasen click manufacturing procedures now allow the flashlights to make that classic clicking sound you know and love.
+
+
Fox McCloud updated:
+
+
Buckshot now does a max of 70 damage, down from 90
+
+
KasparoVy updated:
+
+
Fixes a bug with certain tail markings rendering when they shouldn't.
+
+
Markolie updated:
+
+
Firelocks forced by AI's, cyborgs at range or admin ghosts will now autoclose if there's still an atmospherics alarm present.
+
Regular (non-heavy) firelocks will now properly respond to explosions (100% chance of being destroyed at severity 1 explosions and 50% at severity 2). Heavy firelocks are still only destroyed in severity 1 explosions.
+
Added a visible message to forcing airlocks with the Jaws of Life.
+
+
davipatury updated:
+
+
Ported Modular Computers from /tg/.
+
Ported Rapid Cable Layer from /vg/.
+
+
uraniummeltdown updated:
+
+
EVA has 2 more EVA Suits
+
Removed Vox-only EVA suits (the grey ones in EVA)
+
Vox can now wear EVA suits
+
+
+
10 March 2017
+
Jovaniph updated:
+
+
Recitence no longer makes a sound when turning
+
+
Markolie updated:
+
+
The DNA Vault station goal will now be marked as completed properly.
+
Multi-tile airlocks will now change their direction properly.
+
The atmos skirt loadout item will now be equipped properly on round start.
+
Fixes the inhand disabler sprite pointing the wrong way in some directions.
+
The Janicart will no longer act as a jetpack.
+
You can now resist out of a borer's control again.
+
Fixes the general antag ban not working on certain conversion antagonists.
+
Fixes removing the trunk from underneath a chute/bin causing all sorts of issues.
+
Fixes alt titles not showing up on ID's.
+
Mineral doors no longer block atmos (like they're supposed to).
+
Fixes the cortical borer hivemind talk not working.
+
Fixes detomatix cartridges not working *from* PDA's with an uplink (it now no longer *on* a PDA with an uplink to prevent blowing up fellow traitors).
+
Fixes NODROP interaction with secure closets.
+
Fixes some stray fruit at the Syndicate base on Z2.
+
Fixes an incorrect camera network in the courtroom.
+
Fixes an issue where AI's would go blind upon travelling into space.
+
The cortical borer hivemind talk key is now "bo".
+
Attempting to blow up an undetonatable PDA (such as the captain's) will now show a warning message. It will also no longer use up a charge.
+
Animals can now open mineral doors and mineral doors will no longer be closable if there's a mob inside.
+
Matter grippers can now carry firelock electronics as well as bluespace crystals (for construction).
+
Removes the pipe fitting on the table from atmospherics as it was broken.
+
+
+
09 March 2017
+
Crazylemon64 updated:
+
+
Adds an "ethereal beacon", an admin-only structure usable to attract ghosts to an area.
+
Adds several transformer machines to streamline the ghost-to-PC process.
+
+
LordJike updated:
+
+
Space Fries are now made by deep-frying potato wedges instead of processing them.
+
Introducing carrots inside the food processor gives you carrot wedges now.
+
Now you can make carrot fries by deep-frying carrot wedges instead of formerly processing the whole carrots.
+
+
Markolie updated:
+
+
Tools now have a "usesound" and "toolspeed" variable which allows different tool (levels) to have different sounds and speeds.
+
Robots spawn with tools that are twice as fast as regular tools.
+
Abductor agents now spawn with a toolbelt with specialized abductor tools that are very fast.
+
Abductor surgery tools are now much faster.
+
Abductor (surgery) tools can now be constructed in R&D with a sufficiently high "abductor" research level.
+
The abductor multitool will now display what each wire does.
+
Admin ghosts can now interact with wires and see what each wire does.
+
Adds a set of unique tools for the Chief Engineer that he is given in a unique toolbelt at roundstart. These tools are faster and can be created in R&D with a sufficiently high R&D level.
+
The AI detector has been refactored to have much more robust AI tracking.
+
+
+
08 March 2017
+
Alffd updated:
+
+
Farting on a bible now puts you at the mercy of the gods.
+
Removed automatic biblefarting gibbing.
+
+
FlaaaaaattestGuitar updated:
+
+
Magistrate now starts their shift with a pair of white gloves as well as Bridge and Meeting Room access.
+
+
Fox McCloud updated:
+
+
money is now far easier to use, and distribute in amounts you would like
+
+
Kyep updated:
+
+
Changed event probabilities, aiming for a more fun late game. In general, events that do very little (e.g: meaty ores, rogue drones) are less likely. Events that will keep people on their toes (e.g: anomalies) are more likely. Events that might cause people to observe rather than joining the round (e.g: Xenos) are less likely.
+
+
uraniummeltdown updated:
+
+
Wizard Hardsuit helmet and suit now have inhand sprites
+
+
+
07 March 2017
+
Crazylemon64 updated:
+
+
IPCs now come with a power cord implant to use to recharge from APCs.
+
IPCs can now be genderless.
+
+
Kyep updated:
+
+
Deleted 'challenge' away mission.
+
+
MarsM0nd updated:
+
+
Cultists get shoes on usage of the armor talisman.
+
Cultists only get equipment if they have the slot for it free, weapons are always spawned.
+
The tome does a more fitting description of the talisman of armor.
+
+
+
05 March 2017
+
Kyep updated:
+
+
Added Poison Pen, a stealthy way of applying a contact-based poison to paper. Available to Syndicate HoPs, QMs, and Cargo Techs.
+
Antags whose objectives are manually announced by an admin, or altered automatically as a result of their target cryoing, will now hear a warning sound. The sound is the same as the 'crew transfer vote called' sound. Additionally, the text notice for changed objectives is more obvious.
+
+
MarsM0nd updated:
+
+
The grey satchel uses now the correct sprite instead of the leather one.
+
+
+
04 March 2017
+
Markolie updated:
+
+
Ghosts can now interact with ore dispensers, mining equipment vendors and laptop vendors.
+
Admins can now interact with crates, closets, false walls and conveyor switches if they have advanced interaction enabled.
+
+
davipatury updated:
+
+
Newscaster now uses Nano-UI.
+
Tank dispenser now uses Nano-UI.
+
Passive gate, pump and volume pump now uses Nano-UI.
+
Atmospherics filter and mixer now uses Nano-UI.
+
Wires now uses Nano-UI.
+
+
+
03 March 2017
+
FlauntestGuitar updated:
+
+
You will now be prompted on a karma purchase to confirm that you clicked what you wanted to click
+
+
uraniummeltdown updated:
+
+
You can now change the input/output directons for Ore Redemption Machines by using a multitool on them with the panel open.
+
Bluespace RPED beams have a new sprite
+
+
+
01 March 2017
+
Crazylemon64 updated:
+
+
Kudzu vines now can yield materials if carefully tended to
+
+
Fethas updated:
+
+
2 second cooldown on the rest verb. You are not Neo, knock it off.
+
StopResting and StartResting Procs are not on the rest verb.
+
Various metastation fixes.
+
+
KasparoVy updated:
+
+
Plasmaman multiverse sword copies are now properly equipped (suit, helmet, internals, etc.)
+
Vox multiverse sword copies are now peoperly equipped (internals).
+
+
Kyep updated:
+
+
Fixed several Terror Spider things that should not be possible, like recharging wireless guns, the 'evil-looking spiderlings' instant meta, and spiderlings spacing themselves.
+
Several Terror Spider balance and fun tweaks, such as giving the Prince of Terror a new webbing ability, and ensuring queens/mothers can break open vents, so they cannot be completely shut out late-round.
+
+
Purpose2 updated:
+
+
Enables Cargo to order Wood planks
+
+
+
28 February 2017
+
KasparoVy updated:
+
+
Plasmaman suits will now only auto-extinguish if you're actually on fire (and not just taking a shower).
+
+
+
27 February 2017
+
uraniummeltdown updated:
+
+
Mineral statues are here! Use 5 sheets of any mineral including sandstone to make one. Be careful around plasma and uranium statues!
+
The mime's office now comes with a statue too.
+
Updated plasma, uranium and diamond floor sprites to TG's newer ones.
+
+
+
26 February 2017
+
Crazylemon64 updated:
+
+
Immovable rod events now vanish after going through the station once
+
Firelocks can now be operated by AIs again
+
Barbers and captains get the right stuff now
+
It's now possible to have random floors or walls when mapping
+
+
KasparoVy updated:
+
+
Fixes a bug where you could get a part of a rigsuit stuck to your hand by deploying it twice.
+
Improves the readability of some rigsuit verbs.
+
+
Kyep updated:
+
+
players will no longer spawn with loadout items their job has no access to.
+
AI & Borg upload consoles now have to be on the station zlevel to work.
+
+
davipatury updated:
+
+
ATM now uses Nano-UI.
+
+
+
25 February 2017
+
Crazylemon64 updated:
+
+
Telecomms monitor is now infused with fastitude
+
+
FlattestGuitar updated:
+
+
Escape has been re-bushed.
+
+
KasparoVy updated:
+
+
Reagent plasma has a weak healing effect on Plasmamen when injected and will not poison them.
+
Reagent oxygen is as toxic to Vox as reagent plasma is to just about anyone.
+
Plasmamen now join the shift with 2 suit auto-extinguisher refill cartridges which, individually, will fully refill an empty Plasmaman suit's autoextinguisherl.
+
Plasmaman suits now auto-extinguish and will be able to do so 5 times before they can be refilled by a cartridge.
+
Plasmamen no longer burn in a vacuum or in plasma-pure environments.
+
+
davipatury updated:
+
+
Security Records now uses Nano-UI.
+
+
+
24 February 2017
+
FalseIncarnate updated:
+
+
Corn and bananas can be properly deepfried into their special results again.
+
Rice can be properly ground into a reagent again.
+
Hydroponics trays once again are equipped with Bee-proof lids to keep unwanted pollination to a minimum. This only works if you actually toggle the lid closed though!
+
Plants age slightly slower, so your space farming should no longer feel like it outpaces a meth'd up blue hedgehog in sneakers.
+
+
Kyep updated:
+
+
Fixes blob spawns prompting players twice.
+
+
Markolie updated:
+
+
Mining pod weapons are once again functional. Compared to regular kinetic accelerators, the weak projectile has one additional range (3 --> 4). The regular projectile's damage is increased (40 --> 50) and deals more damage in pressurized environments (50% instead of 25%). The enhanced projectile is able to fire its kinetic projectile AoE against turfs and mobs.
+
Fixed an issue where it was impossible to log out from fax machines.
+
It is no longer possible to steal ID cards from identification computers/fax machine using telekinesis at range.
+
The follow link on death alarms now works.
+
Fixes an exploit where players could use the ambulance trolley to teleport.
+
The chef now properly shows a chef hat on character preview.
+
The nuclear ops game mode will no longer always result in a major crew victory.
+
Players with their face covered will no longer show their flavor text upon examine.
+
Fax machines now have an "Eject ID card" verb so you can remove the inserted ID when it is depowered.
+
Firelocks are now more lethal.
+
Firelocks now crush players standing inside them when they finish closing.
+
Firelocks can no longer be instantly opened by hand: it requires thirty seconds and will autoclose in five seconds if there is still an atmospherics alert present in the area. They can no longer be closed by hand. Heavy firelocks can not be forced by hand.
+
Atmospherics technicians can once again remotely modify all settings on air alarms through the central atmospherics console.
+
+
Purpose2 updated:
+
+
Captain's crown is now part of the random hats crate, and no longer spawns in their locker.
+
+
Twinmold93 updated:
+
+
Ability to label bloodpacks with a pen, so you can now label a bloodpack from donations without a handlabeler.
+
Bloodpacks will now change name to say if they are empty or not.
+
+
davipatury updated:
+
+
EFTPOS now uses Nano-UI.
+
Medical Records now uses Nano-UI.
+
Employment Records now uses Nano-UI.
+
+
+
23 February 2017
+
Krausus updated:
+
+
Ghost candidate alert boxes ("Do you want to play as a thing?") will now have "No" as the leftmost, default option, which you will accidentally pick when it pops up while you're trying to type, but at least you won't be stuck as the thing when you didn't actually want to be that thing.
+
+
Markolie updated:
+
+
The meteor shield satellite station goal coverage goal has been increased tenfold.
+
+
+
22 February 2017
+
KasparoVy updated:
+
+
You can now toggle on/off the gladiator helmet's face-shield with an action button. This is totally cosmetic. imgadd: Adds a bunch of new helmet sprites for Vox.
+
Slightly adjusts the Vox knight armour sprites (not the Templar armour) to look nicer with the new helmets.
+
The Admin 'Select Equipment' debug verb now appropriately equips Armalis when the 'Vox' option is selected.
+
+
+
21 February 2017
+
Crazylemon64 updated:
+
+
Autolathes can be hacked again
+
+
KasparoVy updated:
+
+
Removes rogue super-bright pixel at top of Vulpkanin Adhara hairstyle north and south facing sprites.
+
+
Kyep updated:
+
+
Deleted clown planet away mission.
+
blobs now spawn with a player in control, instantly. There is no longer a 30 second period where they exist, but nobody is controlling them.
+
blobs now get extra time after spawn, before they are announced.
+
+
Markolie updated:
+
+
Megaphones can no longer be used by mute people.
+
Rechargers will no longer recharge stacks beyond their max amount or restack 0.5 sheets.
+
Ranged guardians now have a proper one second cooldown instead of 0.1 seconds.
+
Cult can no longer soul stone manifested ghosts.
+
+
davipatury updated:
+
+
Autolathe now uses Nano-UI.
+
+
uraniummeltdown updated:
+
+
Shuttle engines should now face the correct way
+
+
+
20 February 2017
+
Markolie updated:
+
+
The chaplain on the Cyberiad map now has a one-use soulstone.
+
The chaplain's soul stone on MetaStation can now only be used once.
+
+
davipatury updated:
+
+
Shuttle Console now uses Nano-UI.
+
+
tigercat2000 updated:
+
+
The AI has a button next to radio messages to open the door closest to the speaker. ;AI, Open this fucking door!
+
+
+
19 February 2017
+
Markolie updated:
+
+
Claw games no longer eat up all glass sheets in the stack when constructed.
+
+
18 February 2017
Alffd updated:
@@ -66,6 +983,10 @@
Mind transfer abilities work again
Centcomm is no longer obnoxiously pedantic, regarding BSA deployment
+
Krausus updated:
+
+
End-of-round sounds will now play just in time for them to end as the server reboots, rather than starting the moment it reboots.
+
Kyep updated:
Added a 'take' option to ahelps/mhelps, so admins/mentors can quickly let the asker know their question is being looked at.
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index 7e0cb591f66..4aec21eaa76 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -3764,6 +3764,9 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
influx of fax responses from Clown impersonators
- bugfix: Mind transfer abilities work again
- bugfix: Centcomm is no longer obnoxiously pedantic, regarding BSA deployment
+ Krausus:
+ - tweak: End-of-round sounds will now play just in time for them to end as the server
+ reboots, rather than starting the moment it reboots.
Kyep:
- rscadd: Added a 'take' option to ahelps/mhelps, so admins/mentors can quickly
let the asker know their question is being looked at.
@@ -3779,3 +3782,741 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
- bugfix: Slicing disposal pipes now shows a progress bar.
uraniummeltdown:
- rscadd: Shuttle engines have new sprites.
+2017-02-19:
+ Markolie:
+ - bugfix: Claw games no longer eat up all glass sheets in the stack when constructed.
+2017-02-20:
+ Markolie:
+ - rscadd: The chaplain on the Cyberiad map now has a one-use soulstone.
+ - tweak: The chaplain's soul stone on MetaStation can now only be used once.
+ davipatury:
+ - rscadd: Shuttle Console now uses Nano-UI.
+ tigercat2000:
+ - rscadd: The AI has a button next to radio messages to open the door closest to
+ the speaker. ;AI, Open this fucking door!
+2017-02-21:
+ Crazylemon64:
+ - bugfix: Autolathes can be hacked again
+ KasparoVy:
+ - tweak: Removes rogue super-bright pixel at top of Vulpkanin Adhara hairstyle north
+ and south facing sprites.
+ Kyep:
+ - rscdel: Deleted clown planet away mission.
+ - tweak: blobs now spawn with a player in control, instantly. There is no longer
+ a 30 second period where they exist, but nobody is controlling them.
+ - tweak: blobs now get extra time after spawn, before they are announced.
+ Markolie:
+ - bugfix: Megaphones can no longer be used by mute people.
+ - bugfix: Rechargers will no longer recharge stacks beyond their max amount or restack
+ 0.5 sheets.
+ - bugfix: Ranged guardians now have a proper one second cooldown instead of 0.1
+ seconds.
+ - bugfix: Cult can no longer soul stone manifested ghosts.
+ davipatury:
+ - rscadd: Autolathe now uses Nano-UI.
+ uraniummeltdown:
+ - bugfix: Shuttle engines should now face the correct way
+2017-02-22:
+ KasparoVy:
+ - rscadd: 'You can now toggle on/off the gladiator helmet''s face-shield with an
+ action button. This is totally cosmetic. imgadd: Adds a bunch of new helmet
+ sprites for Vox.'
+ - tweak: Slightly adjusts the Vox knight armour sprites (not the Templar armour)
+ to look nicer with the new helmets.
+ - bugfix: The Admin 'Select Equipment' debug verb now appropriately equips Armalis
+ when the 'Vox' option is selected.
+2017-02-23:
+ Krausus:
+ - tweak: Ghost candidate alert boxes ("Do you want to play as a thing?") will now
+ have "No" as the leftmost, default option, which you will accidentally pick
+ when it pops up while you're trying to type, but at least you won't be stuck
+ as the thing when you didn't actually want to be that thing.
+ Markolie:
+ - tweak: The meteor shield satellite station goal coverage goal has been increased
+ tenfold.
+2017-02-24:
+ FalseIncarnate:
+ - bugfix: Corn and bananas can be properly deepfried into their special results
+ again.
+ - bugfix: Rice can be properly ground into a reagent again.
+ - rscadd: Hydroponics trays once again are equipped with Bee-proof lids to keep
+ unwanted pollination to a minimum. This only works if you actually toggle the
+ lid closed though!
+ - tweak: Plants age slightly slower, so your space farming should no longer feel
+ like it outpaces a meth'd up blue hedgehog in sneakers.
+ Kyep:
+ - bugfix: Fixes blob spawns prompting players twice.
+ Markolie:
+ - bugfix: Mining pod weapons are once again functional. Compared to regular kinetic
+ accelerators, the weak projectile has one additional range (3 --> 4). The regular
+ projectile's damage is increased (40 --> 50) and deals more damage in pressurized
+ environments (50% instead of 25%). The enhanced projectile is able to fire its
+ kinetic projectile AoE against turfs and mobs.
+ - bugfix: Fixed an issue where it was impossible to log out from fax machines.
+ - bugfix: It is no longer possible to steal ID cards from identification computers/fax
+ machine using telekinesis at range.
+ - bugfix: The follow link on death alarms now works.
+ - bugfix: Fixes an exploit where players could use the ambulance trolley to teleport.
+ - bugfix: The chef now properly shows a chef hat on character preview.
+ - bugfix: The nuclear ops game mode will no longer always result in a major crew
+ victory.
+ - tweak: Players with their face covered will no longer show their flavor text upon
+ examine.
+ - rscadd: Fax machines now have an "Eject ID card" verb so you can remove the inserted
+ ID when it is depowered.
+ - tweak: Firelocks are now more lethal.
+ - rscadd: Firelocks now crush players standing inside them when they finish closing.
+ - rscadd: 'Firelocks can no longer be instantly opened by hand: it requires thirty
+ seconds and will autoclose in five seconds if there is still an atmospherics
+ alert present in the area. They can no longer be closed by hand. Heavy firelocks
+ can not be forced by hand.'
+ - bugfix: Atmospherics technicians can once again remotely modify all settings on
+ air alarms through the central atmospherics console.
+ Purpose2:
+ - tweak: Captain's crown is now part of the random hats crate, and no longer spawns
+ in their locker.
+ Twinmold93:
+ - rscadd: Ability to label bloodpacks with a pen, so you can now label a bloodpack
+ from donations without a handlabeler.
+ - rscadd: Bloodpacks will now change name to say if they are empty or not.
+ davipatury:
+ - rscadd: EFTPOS now uses Nano-UI.
+ - rscadd: Medical Records now uses Nano-UI.
+ - rscadd: Employment Records now uses Nano-UI.
+2017-02-25:
+ Crazylemon64:
+ - bugfix: Telecomms monitor is now infused with fastitude
+ FlattestGuitar:
+ - tweak: Escape has been re-bushed.
+ KasparoVy:
+ - rscadd: Reagent plasma has a weak healing effect on Plasmamen when injected and
+ will not poison them.
+ - rscadd: Reagent oxygen is as toxic to Vox as reagent plasma is to just about anyone.
+ - rscadd: Plasmamen now join the shift with 2 suit auto-extinguisher refill cartridges
+ which, individually, will fully refill an empty Plasmaman suit's autoextinguisherl.
+ - rscadd: Plasmaman suits now auto-extinguish and will be able to do so 5 times
+ before they can be refilled by a cartridge.
+ - tweak: Plasmamen no longer burn in a vacuum or in plasma-pure environments.
+ davipatury:
+ - rscadd: Security Records now uses Nano-UI.
+2017-02-26:
+ Crazylemon64:
+ - tweak: Immovable rod events now vanish after going through the station once
+ - bugfix: Firelocks can now be operated by AIs again
+ - bugfix: Barbers and captains get the right stuff now
+ - rscadd: It's now possible to have random floors or walls when mapping
+ KasparoVy:
+ - bugfix: Fixes a bug where you could get a part of a rigsuit stuck to your hand
+ by deploying it twice.
+ - tweak: Improves the readability of some rigsuit verbs.
+ Kyep:
+ - bugfix: players will no longer spawn with loadout items their job has no access
+ to.
+ - tweak: AI & Borg upload consoles now have to be on the station zlevel to work.
+ davipatury:
+ - rscadd: ATM now uses Nano-UI.
+2017-02-27:
+ uraniummeltdown:
+ - rscadd: Mineral statues are here! Use 5 sheets of any mineral including sandstone
+ to make one. Be careful around plasma and uranium statues!
+ - rscadd: The mime's office now comes with a statue too.
+ - tweak: Updated plasma, uranium and diamond floor sprites to TG's newer ones.
+2017-02-28:
+ KasparoVy:
+ - bugfix: Plasmaman suits will now only auto-extinguish if you're actually on fire
+ (and not just taking a shower).
+2017-03-01:
+ Crazylemon64:
+ - rscadd: Kudzu vines now can yield materials if carefully tended to
+ Fethas:
+ - tweak: 2 second cooldown on the rest verb. You are not Neo, knock it off.
+ - rscadd: StopResting and StartResting Procs are not on the rest verb.
+ - tweak: Various metastation fixes.
+ KasparoVy:
+ - bugfix: Plasmaman multiverse sword copies are now properly equipped (suit, helmet,
+ internals, etc.)
+ - bugfix: Vox multiverse sword copies are now peoperly equipped (internals).
+ Kyep:
+ - bugfix: Fixed several Terror Spider things that should not be possible, like recharging
+ wireless guns, the 'evil-looking spiderlings' instant meta, and spiderlings
+ spacing themselves.
+ - tweak: Several Terror Spider balance and fun tweaks, such as giving the Prince
+ of Terror a new webbing ability, and ensuring queens/mothers can break open
+ vents, so they cannot be completely shut out late-round.
+ Purpose2:
+ - rscadd: Enables Cargo to order Wood planks
+2017-03-03:
+ FlauntestGuitar:
+ - rscadd: You will now be prompted on a karma purchase to confirm that you clicked
+ what you wanted to click
+ uraniummeltdown:
+ - rscadd: You can now change the input/output directons for Ore Redemption Machines
+ by using a multitool on them with the panel open.
+ - rscadd: Bluespace RPED beams have a new sprite
+2017-03-04:
+ Markolie:
+ - rscadd: Ghosts can now interact with ore dispensers, mining equipment vendors
+ and laptop vendors.
+ - rscadd: Admins can now interact with crates, closets, false walls and conveyor
+ switches if they have advanced interaction enabled.
+ davipatury:
+ - rscadd: Newscaster now uses Nano-UI.
+ - rscadd: Tank dispenser now uses Nano-UI.
+ - rscadd: Passive gate, pump and volume pump now uses Nano-UI.
+ - rscadd: Atmospherics filter and mixer now uses Nano-UI.
+ - rscadd: Wires now uses Nano-UI.
+2017-03-05:
+ Kyep:
+ - rscadd: Added Poison Pen, a stealthy way of applying a contact-based poison to
+ paper. Available to Syndicate HoPs, QMs, and Cargo Techs.
+ - tweak: Antags whose objectives are manually announced by an admin, or altered
+ automatically as a result of their target cryoing, will now hear a warning sound.
+ The sound is the same as the 'crew transfer vote called' sound. Additionally,
+ the text notice for changed objectives is more obvious.
+ MarsM0nd:
+ - bugfix: The grey satchel uses now the correct sprite instead of the leather one.
+2017-03-07:
+ Crazylemon64:
+ - rscadd: IPCs now come with a power cord implant to use to recharge from APCs.
+ - tweak: IPCs can now be genderless.
+ Kyep:
+ - rscdel: Deleted 'challenge' away mission.
+ MarsM0nd:
+ - rscadd: Cultists get shoes on usage of the armor talisman.
+ - rscadd: Cultists only get equipment if they have the slot for it free, weapons
+ are always spawned.
+ - tweak: The tome does a more fitting description of the talisman of armor.
+2017-03-08:
+ Alffd:
+ - rscadd: Farting on a bible now puts you at the mercy of the gods.
+ - rscdel: Removed automatic biblefarting gibbing.
+ FlaaaaaattestGuitar:
+ - tweak: Magistrate now starts their shift with a pair of white gloves as well as
+ Bridge and Meeting Room access.
+ Fox McCloud:
+ - tweak: money is now far easier to use, and distribute in amounts you would like
+ Kyep:
+ - tweak: 'Changed event probabilities, aiming for a more fun late game. In general,
+ events that do very little (e.g: meaty ores, rogue drones) are less likely.
+ Events that will keep people on their toes (e.g: anomalies) are more likely.
+ Events that might cause people to observe rather than joining the round (e.g:
+ Xenos) are less likely.'
+ uraniummeltdown:
+ - rscadd: Wizard Hardsuit helmet and suit now have inhand sprites
+2017-03-09:
+ Crazylemon64:
+ - rscadd: Adds an "ethereal beacon", an admin-only structure usable to attract ghosts
+ to an area.
+ - rscadd: Adds several transformer machines to streamline the ghost-to-PC process.
+ LordJike:
+ - tweak: Space Fries are now made by deep-frying potato wedges instead of processing
+ them.
+ - rscadd: Introducing carrots inside the food processor gives you carrot wedges
+ now.
+ - tweak: Now you can make carrot fries by deep-frying carrot wedges instead of formerly
+ processing the whole carrots.
+ Markolie:
+ - tweak: Tools now have a "usesound" and "toolspeed" variable which allows different
+ tool (levels) to have different sounds and speeds.
+ - tweak: Robots spawn with tools that are twice as fast as regular tools.
+ - rscadd: Abductor agents now spawn with a toolbelt with specialized abductor tools
+ that are very fast.
+ - tweak: Abductor surgery tools are now much faster.
+ - rscadd: Abductor (surgery) tools can now be constructed in R&D with a sufficiently
+ high "abductor" research level.
+ - tweak: The abductor multitool will now display what each wire does.
+ - rscadd: Admin ghosts can now interact with wires and see what each wire does.
+ - rscadd: Adds a set of unique tools for the Chief Engineer that he is given in
+ a unique toolbelt at roundstart. These tools are faster and can be created in
+ R&D with a sufficiently high R&D level.
+ - tweak: The AI detector has been refactored to have much more robust AI tracking.
+2017-03-10:
+ Jovaniph:
+ - tweak: Recitence no longer makes a sound when turning
+ Markolie:
+ - bugfix: The DNA Vault station goal will now be marked as completed properly.
+ - bugfix: Multi-tile airlocks will now change their direction properly.
+ - bugfix: The atmos skirt loadout item will now be equipped properly on round start.
+ - bugfix: Fixes the inhand disabler sprite pointing the wrong way in some directions.
+ - bugfix: The Janicart will no longer act as a jetpack.
+ - bugfix: You can now resist out of a borer's control again.
+ - bugfix: Fixes the general antag ban not working on certain conversion antagonists.
+ - bugfix: Fixes removing the trunk from underneath a chute/bin causing all sorts
+ of issues.
+ - bugfix: Fixes alt titles not showing up on ID's.
+ - bugfix: Mineral doors no longer block atmos (like they're supposed to).
+ - bugfix: Fixes the cortical borer hivemind talk not working.
+ - bugfix: Fixes detomatix cartridges not working *from* PDA's with an uplink (it
+ now no longer *on* a PDA with an uplink to prevent blowing up fellow traitors).
+ - bugfix: Fixes NODROP interaction with secure closets.
+ - bugfix: Fixes some stray fruit at the Syndicate base on Z2.
+ - bugfix: Fixes an incorrect camera network in the courtroom.
+ - bugfix: Fixes an issue where AI's would go blind upon travelling into space.
+ - tweak: The cortical borer hivemind talk key is now "bo".
+ - tweak: Attempting to blow up an undetonatable PDA (such as the captain's) will
+ now show a warning message. It will also no longer use up a charge.
+ - tweak: Animals can now open mineral doors and mineral doors will no longer be
+ closable if there's a mob inside.
+ - tweak: Matter grippers can now carry firelock electronics as well as bluespace
+ crystals (for construction).
+ - rscdel: Removes the pipe fitting on the table from atmospherics as it was broken.
+2017-03-11:
+ Developed by XDTM, ported by davipatury:
+ - tweak: Hallucinations have been modified to increase the creepiness factor and
+ reduce the boring factor.
+ - rscadd: Added some new hallucinations.
+ - bugfix: Fixed a bug where the singularity hallucination was stunning for longer
+ than intended and leaving the fake HUD crit icon permanently.
+ Flatty Patty:
+ - bugfix: all the tools have icons again
+ FlattyPatty:
+ - tweak: Improved Nanotrasen click manufacturing procedures now allow the flashlights
+ to make that classic clicking sound you know and love.
+ Fox McCloud:
+ - tweak: Buckshot now does a max of 70 damage, down from 90
+ KasparoVy:
+ - bugfix: Fixes a bug with certain tail markings rendering when they shouldn't.
+ Markolie:
+ - tweak: Firelocks forced by AI's, cyborgs at range or admin ghosts will now autoclose
+ if there's still an atmospherics alarm present.
+ - tweak: Regular (non-heavy) firelocks will now properly respond to explosions (100%
+ chance of being destroyed at severity 1 explosions and 50% at severity 2). Heavy
+ firelocks are still only destroyed in severity 1 explosions.
+ - tweak: Added a visible message to forcing airlocks with the Jaws of Life.
+ davipatury:
+ - rscadd: Ported Modular Computers from /tg/.
+ - rscadd: Ported Rapid Cable Layer from /vg/.
+ uraniummeltdown:
+ - rscadd: EVA has 2 more EVA Suits
+ - rscdel: Removed Vox-only EVA suits (the grey ones in EVA)
+ - tweak: Vox can now wear EVA suits
+2017-03-12:
+ Crazylemon64:
+ - bugfix: Kudzu should now be less of (but still) a station-destroying force of
+ nature.
+ - tweak: Bluespace kudzu now only pierces a single layer of walls before losing
+ its "charge".
+ - tweak: Aggressive spread now does not bust rwalls, but does attack obstructing
+ objects in its path.
+ - tweak: Kudzu now only spreads on space turfs when it has specific mutations to
+ do so.
+ - tweak: Kudzu events should be more interesting on their own.
+ Jovaniph:
+ - rscadd: Adds Vulpkanin EVA suit sprite
+ Kyep:
+ - tweak: Adjusted Wizard Academy to make it both more lethal, and more rewarding.
+ Markolie:
+ - tweak: The system for picking ghosts to inhabit cultist slaughter demons now shows
+ a confirmation prompt like most other role checks.
+ - bugfix: Fixed an issue where you could join as a cultist slaughter demon despite
+ having antagHUD enabled.
+ - bugfix: Fixed an issue where it was possible to weld statues without any fuel.
+ - tweak: It is no longer possible to spam the firelock force message.
+ Twinmold93:
+ - rscadd: Employment record laptop to Head of Personnel's Office. Moves package
+ wrap that was there to meeting room to be paired with the hand labeler there.
+2017-03-13:
+ Kyep:
+ - bugfix: Syndicate mobs in the Wild West are no longer so stupid that they trip
+ over, and die to, their own mines. This also means that they won't set their
+ own buildings on fire anymore.
+ - bugfix: Phazons' phase ability now works again.
+ - bugfix: Phazons' toxin injector melee damage type (a weak melee attack) now works
+ again.
+ uraniummeltdown:
+ - rscadd: Clicking on a tile with another tile and a crowbar or screwdriver in hand
+ directly replaces the tile.
+2017-03-14:
+ uraniummeltdown:
+ - rscadd: Strong supply talismans can now summon 5 sheets of runed metal.
+2017-03-15:
+ uraniummeltdown:
+ - rscadd: Plastic flaps can be deconstructed with tools and constructed using 5
+ sheets of plastic.
+ - rscadd: You can now damage grilles by throwing things at them.
+ - rscadd: You can rebuild broken grilles by using a metal rod on them.
+ - tweak: Metal rods maximum amount reduced from 60 to 50.
+2017-03-16:
+ FlattestGeetar:
+ - tweak: Workboots are now in the loadout system.
+ - rscadd: Ports winter boots from /tg/
+ Jovaniph:
+ - rscadd: New sounds to Firelocks and Airlock External
+ - rscadd: Door closing sound to Airlocks - from yogstation
+ Markolie:
+ - bugfix: Fixed revenant night vision not working.
+ - bugfix: Fixed the "X attacked Y" message showing up when welding vents.
+ - bugfix: Fixed the follow button on the cell door timer radio message not working.
+ - bugfix: Fixed the Jaws of Life being unable to force unpowered doors.
+ - bugfix: Fixed a number of preference options being unavailable when modifying
+ preferences while observing.
+ - bugfix: Fixed an issue where deleting security records wouldn't clear that player's
+ wanted status properly.
+ - bugfix: Fixed the cult "first meal" sacrifice objective not counting properly.
+ Also clarified what this objective actually entailed.
+ - bugfix: Fixed IPC's ocassionally being selected as a changeling "escape with X
+ identity" target.
+ - tweak: The character records and disabilities menus in the preferences menu no
+ longer uses the plain white background, but uses the better looking blue layout
+ instead.
+2017-03-18:
+ Fox McCloud:
+ - bugfix: Fixes abductor surgeries
+ Jovaniph:
+ - rscadd: Unathi EVA suits
+ uraniummeltdown:
+ - rscadd: Shades now have directional sprites.
+ - rscadd: Attacking with glass shards now hurts your hand if not wearing gloves.
+ Does not affect robotic hands though.
+2017-03-19:
+ Jovaniph:
+ - tweak: Voxes can now wear soft caps.
+ Krausus:
+ - bugfix: Pest spray bottles are no longer invisible.
+ Kyep:
+ - bugfix: Wood doors in wild west map no longer constantly open/close
+ uraniummeltdown:
+ - rscadd: Shipping errors can sometimes cause the supply shuttle to receive an extra
+ crate when ordering supplies.
+ - rscadd: Added dog beds! Can be made with 10 wood planks and deconstructed with
+ a wrench. Ian's Bed added to Cyberiad and Metastation.
+2017-03-20:
+ Jovaniph:
+ - rscadd: Tajaran EVA Suit Sprites
+ KasparoVy:
+ - bugfix: Gloves can be snipped again.
+ Purpose2:
+ - bugfix: Fixes assorted wording / capitalisation / grammatical problems.
+ - bugfix: Fixes the exploit to produce infinite cable coil from airlocks.
+ Tayyyyyyy:
+ - rscadd: Added GPS devices to pod pilot and mechanic's offices
+2017-03-21:
+ Crazylemon64:
+ - experiment: Strange reagent now has a volume floor requirement to activate, induces
+ clone damage, and may cause further trouble...
+ KasparoVy:
+ - tweak: No-one escapes nuclear hellfire.
+ - rscadd: Secure fridges/freezers are now lead-lined and have thus become nuke resistant.
+ uraniummeltdown:
+ - rscadd: Baseball bats added to the game, are craftable from 5 wood planks.
+ - rscadd: Baseball burgers can be made with a baseball bat and a bun, either microwaved
+ or table-crafted.
+2017-03-22:
+ Crazylemon64:
+ - tweak: Rod form is now at half speed, and has a warning sound.
+ FlattestGuitar:
+ - bugfix: When a person's limb is dying, it will no longer notify the whole server
+ of the ordeal
+ - bugfix: Welding tools no longer tell you about their span classes
+ KasparoVy:
+ - bugfix: Deconstructing beds now yields the same amount of metal as was used to
+ make the bed.
+ - bugfix: The PA console will no longer appear as though it is fully constructed
+ at the start of the round.
+ - bugfix: Ore Redemption Machines no longer eat IDs when deconstructed.
+ - tweak: Ore Redemption Machines and Mining Equipment Vendors now spit out whatever
+ IDs were in them when they lose power.
+ Krausus:
+ - bugfix: Personal crafting is now usable again for those with an Internet Explorer
+ version below 11.
+2017-03-23:
+ FalseIncarnate:
+ - tweak: Fish breeding has been tweaked to support fish refusing to cross-breed
+ and improved egg chances with same-species parents.
+ Fox McCloud:
+ - bugfix: Floors are now fully properly cleaned with mops and soap
+ - rscadd: Adds in emergency welding tool, fork, trays, drinking glasses, shot glasses,
+ shakers, butcher cleavers, and riot darts to the autolathe
+ - rscadd: Adds all basic stock parts to the autolathe
+ - tweak: re-arranges the autolathe menu to be more logical
+ - tweak: light bulbs no longer require metal to produce
+ - tweak: Incision management system can now cauterize
+ KasparoVy:
+ - tweak: Unathi Security, Medical, Engineering and Syndicate side-facing hardsuit
+ sprites have undergone weight reduction.
+ Kyep:
+ - tweak: Chaplain's armor is no longer riot-grade. In addition, their nullrods do
+ less damage.
+ MarsM0nd:
+ - bugfix: Conveyor switches can now set to left-only direction toggling.
+ Norgad:
+ - tweak: Maintenance areas near arrivals, science, and the bar have been revamped.
+ uraniummeltdown:
+ - tweak: Station lighting has less lighting power, this is not noticeable apart
+ from maint and 1 bulb rooms being a bit darker.
+ - tweak: Tweaked the potency scaling for glowshroom/glowberry light; high-potency
+ plants no longer light up a huge area, but are slightly brighter.
+ - rscadd: Added Shadowshrooms as a glowshroom mutation. They do exactly what you'd
+ expect.
+2017-03-24:
+ KasparoVy:
+ - bugfix: 'Red wire-cutters and red crowbars now appear correctly in-hands again.
+ imgadd: The medical wrench and all the brass tools (screwdriver, crowbar, wrench,
+ wire-cutters, welder) now have in-hand sprites of their own.'
+ - tweak: Adds TG's inhand icons for screwdrivers, crowbars, wrenches, wire-cutters
+ and welders.
+ - bugfix: Slime People can wear underwear, undershirts and socks.
+ uraniummeltdown:
+ - tweak: IV Drips are no longer dense objects, you can walk over them.
+ - rscadd: You can change gold and silver tiles into fancy versions by using them
+ in hand.
+2017-03-25:
+ Crazylemon64:
+ - bugfix: All pens are now certified crayon-wax free!
+ Kyep:
+ - bugfix: Pipes in the Wizard Academy have been banished back under the carpet,
+ where they belong.
+2017-03-26:
+ FalseIncarnate:
+ - rscadd: Re-adds the telescopic scythe, the pinnacle of covert reaping technologies.
+ Currently admin-spawn only, for use in the most dire of harvest times.
+ - bugfix: Scythes (normal and telescopic) should once again clear swathes through
+ all but the hardiest of vines when in proper reaping configurations, and heavily
+ damage those they don't outright destroy.
+ - bugfix: Ankle-high piles of dirt will no longer prevent you from stepping over
+ them.
+ KasparoVy:
+ - bugfix: You can no longer climb through interdimensional rifts into cryopods.
+ - bugfix: Revenants can see properly in the dark again.
+ Kyep:
+ - tweak: Adjusted Beach awaymission so it now includes deadly (but rewarding) pirate
+ area.
+ - tweak: Adjusted the centcom away mission to make it viable.
+ - rscdel: Deleted 'listening post' away mission.
+ Purpose2:
+ - tweak: 'QoL: Newly built APCs come unlocked.'
+ - tweak: 'QoL: Chief Engineer''s locker has more building permits.'
+ - bugfix: Assorted grammatical fixes.
+ Ty-Omaha:
+ - bugfix: Splints will display the proper sentence when applying them
+ uraniummeltdown:
+ - bugfix: 'Metastation: Fixed Gateway airlock access and Command Hallway vendor
+ areas, virology smartfridge is correctly stocked, mass drivers now have tiny
+ fans, Sec spacepod keys work on the Sec pod, Airlocks should have the correct
+ icon, Firelocks/Windoors/Shutters should be layered correctly, Shutters should
+ be facing the right direction'
+ - tweak: Drone fabricator consoles search for a fabricator in the same area instead
+ of 3x3 range.
+2017-03-27:
+ Crazylemon64:
+ - bugfix: Away mission power works now.
+ Fox McCloud:
+ - bugfix: Fixes some stacks not wanting to stack with similar stacks (such as space
+ cash)
+ KasparoVy:
+ - rscadd: Skrell have been greyscaled and darkened. You can now colour your Skrell
+ characters as you please.
+ - rscadd: Kidan can now select from multiple different antennae head-accessory styles.
+ - tweak: Kidan male/female bodies now have differences, namely mandible/torso structure.
+ - tweak: Skrell flesh is now blue (like their blood), though you'll only ever see
+ this under certain circumstances if they're dismembered.
+ Kyep:
+ - bugfix: The invisible floors in the engineering area of the UO45 away mission
+ are no longer invisible. Previously, you had to crowbar up a seemingly invisible
+ floor to make a wire appear.
+ - bugfix: Fixed several Terror Spider bugs. Including the notorious 'spiders can
+ get stuck in vents' bug, the 'spiders ignore mechs' bug, and the 'prince is
+ cheesable' bug.
+ - tweak: Adjusted White & Empress spider abilities - webs spun by white spiders
+ are now infectious.
+ Purpose2:
+ - rscadd: Adds the Psychiatrist's bed/sofa for 5 metal.
+ - bugfix: Wooden chairs broken by animals no longer drop metal.
+ - bugfix: Abductors no longer have Syndicate ties.
+ - bugfix: Fixes material loss on some chair/bed/stool deconstruction types.
+ - bugfix: IPCs can no longer be DNA Scrambled.
+ - bugfix: Health analysers clunk again when upgraded
+ - bugfix: Resolves further grammatical/typo issues.
+2017-03-28:
+ KasparoVy:
+ - bugfix: Skrell can now choose undergarments (undershirts, underpants, socks) at
+ character creation and dressers.
+ - tweak: Vox are now 20% less resilient to brute damage due to their light, porous
+ and flexible skeletons.
+ uraniummeltdown:
+ - bugfix: Quick-replacing non-wooden tiles will only work with a crowbar in inactive
+ hand instead of any item
+2017-03-29:
+ Purpose2:
+ - bugfix: '''Roundstart malfunctioning'' cameras now appropriately have their wires
+ cut.'
+ - bugfix: AI core camera can no longer be a 'roundstart malfunctioning' camera on
+ both Box & Meta Stations.
+2017-03-30:
+ Crazylemon64:
+ - bugfix: Cult shifter should work now
+ FlattestGuitar:
+ - tweak: Strange Reagent only deals clone damage on a successful revival.
+ Fox McCloud:
+ - rscadd: Non-designated drinks now mix their colors from the reagents within them
+ - tweak: Autopsies can now be performed without needing to cut someone open
+ - rscadd: Adds modular receiver to the maintenance loot system
+ - rscadd: Receivers can now be produced in hacked autolathes; no longer available
+ in R&D protolathes.
+ - tweak: removes the random "scary" sounds that play when walking about
+ KasparoVy:
+ - rscadd: You can now slam drinks/bottles/flasks by click-dragging them onto yourself
+ while it's in your active hand.
+ Kyep:
+ - tweak: The moonoutpost19 away mission should now be finishable, and more enjoyable
+ to attempt.
+ uraniummeltdown:
+ - bugfix: Emagging a closed firelock does not permanently break it anymore, only
+ opens it.
+ - bugfix: Emagged windoors should be able to be screwdriver+crowbar'd again.
+ - rscadd: Powered grilles now have a chance to zap you when you throw an object
+ at them.
+2017-03-31:
+ Krausus:
+ - bugfix: Blobs are no longer nearly guaranteed to immediately tear themselves apart
+ upon spawning.
+ Kyep:
+ - rscadd: Access to jobs is now based solely on Playtime, NOT days since BYOND account
+ was registered.
+2017-04-02:
+ KasparoVy:
+ - bugfix: Nuclear Operatives/ERT Members/Abductors will no longer spawn in with
+ genetic quirks.
+ - bugfix: Thrown objects that cross a tile with non-full windows will no longer
+ hit the window even if it isn't visually obstructing the path.
+ - bugfix: Shooting guns (i.e. tasers) in the above circumstances means that the
+ taser shots won't be blocked by windows that aren't visually obstructing the
+ path.
+ Kyep:
+ - tweak: Adjusted Black Market Packers away mission. It now has some danger to it
+ (carp), some more interesting stuff to find (syndi lab) and a challenge (fix
+ the ship powergrid).
+ - tweak: Slight adjustment to word lists based on our rules.
+ - tweak: Removed thunderdome armor from centcom away mission.
+ - bugfix: Cultists now get a new sacrifice target when the current one cryos.
+2017-04-03:
+ Kyep:
+ - bugfix: Ghosts manifested by cultists are no longer invincible, and an exploit
+ allowing them to be made permanent has been fixed.
+2017-04-04:
+ FalseIncarnate:
+ - rscadd: Adds FullofSkittles's custom pAI sprites. Thanks FoS!
+ - tweak: Custom sprites for cyborgs, AI, AI holograms, and pAI units no longer are
+ restricted to a single name. Get your money's worth by using that borg sprite
+ regardless of your version number!
+2017-04-05:
+ KasparoVy:
+ - rscadd: Adds a Tajaran facial hair style.
+ - rscadd: Adds a few new frill styles for Unathi.
+ - rscadd: Adds some new horn styles for Unathi.
+ - rscadd: Adds a couple new facial hair styles for Vulpkanin.
+ - rscadd: Adds a few new hair styles for Vulpkanin.
+ - tweak: Updates Vulpkanin Adhara & Kajam hairstyles.
+ Purpose2:
+ - rscadd: Can now take photos of the Blueprints to count as a completed objective.
+ - rscadd: Cryostorage console now stores the Null Rod & all variations.
+ - bugfix: Mime mech is now 'Reticence' as it should be
+ - bugfix: Fixes missing cult's Berserker Robe sprite.
+ - tweak: Cryostorage console no longer stores hundreds of bomber jackets, and now
+ stores hardsuits
+ - tweak: Cryostorage console now catches and stores most unique objective items.
+ - tweak: Corrects some typos and grammar.
+ - rscadd: You can now light cigarettes with Wands of Fireball, at the cost of your
+ eyebrows.
+ Twinmold93:
+ - bugfix: Buying poison pen will actually give you the poison pen now.
+2017-04-06:
+ Fox McCloud:
+ - bugfix: Fixes autopsy report printing; print reports by clicking the device itself
+ davipatury:
+ - rscadd: Rapid Cable Layer now have an autolathe design.
+2017-04-09:
+ Fox McCloud:
+ - tweak: abductor glands now act as actual hearts; removing them induces heart failure
+ - tweak: plasma gland no longer gibs you, but makes you vomit plasma instead
+ - tweak: bodysnatcher gland no longer gibs you, but will deal brute damage instead
+ - tweak: bloody gland will now drain blood instead of dealing brute damage
+ - tweak: species change gland will now change your species until the gland is removed
+ - tweak: adjusted the origin tech on a few gland
+ - tweak: heart attacks will once again paralyse you and do slightly more brute damage
+ - bugfix: body snatch clones look more like their originator
+ - tweak: Abductors can no longer use guns (minus their own alien energy gun)
+ - tweak: Sending someone with an abductor teleport via the console will stun them
+ for 3 cycles (doesn't apply with the advanced camera console)
+ - rscadd: Abductors can now purchase additional abductor vests
+ - rscadd: Abductors can lock/unlock vests
+ - tweak: Purchasing supplies from the abductor console will no longer increase the
+ amount of experiments you must do
+ - tweak: Wonderprods will not induce sleep in those who are stunned OR sleeping
+ - tweak: altered the origin tech of abductor tools
+ - rscadd: Can make abductor surgery tables from regular tables by adding silver
+ sheets to an abductor table frame
+ - rscadd: Added a bunch more abductee objectives
+ - tweak: abductors no long scream like girls
+ - tweak: High capacity cells have 10,000 charge instead of 15,000
+ - tweak: Mech equipment power costs minorly adjusted
+ - tweak: APCs charge a bit faster
+ - tweak: EMPs less effective against pods and mechs
+ - bugfix: Fixes not being able to recharge modular laptops/tablets
+ Purpose2:
+ - bugfix: Welders must now been fueled and active to cut lattices.
+2017-04-11:
+ FalseIncarnate:
+ - tweak: Damage done to the shuttle engines by a shadowling's "Extend Shuttle" ability
+ now prevent the shuttle from being recalled to CentComm.
+2017-04-16:
+ FalseIncarnate:
+ - tweak: Potential collaborators for traitors now are informed they are potentially
+ a collaborator for a potential increase in them potentially helping the traitors
+ potentially do potentially bad things. Potentially.
+ - rscadd: Potential collaborators are given a single code word and response set
+ so they can discretely find out that their best friend is a filthy traitor.
+ KasparoVy:
+ - rscadd: Adds secondary (facial) hair colours to the genome (UI). There are 6 new
+ blocks.
+ - bugfix: Characters with secondary (facial) hair colours won't find they've turned
+ black after cloning anymore.
+ Kyep:
+ - rscdel: Plasma dust no longer creates plasma gas on objects or turfs during reactions.
+ Twinmold93:
+ - bugfix: Missing sprite for pod pilot Drask now added.
+ Xantholne:
+ - rscadd: Adds Medical Beret available via loadout menu
+ ZomgPonies:
+ - bugfix: Fixes Superhero ID cards
+ - bugfix: Fixes Griffin missing his Freedom Implant
+ - bugfix: Fixes ElectroNegmatic's Ability not working at all.
+ - tweak: Changes LightnIan's ability into a non-damaging stun lasting 2 ticks, with
+ the amount of people affected depending on how long you hold the power in for.
+ uraniummeltdown:
+ - rscadd: You can now create heat-proof glass airlocks by using a sheet of reinforced
+ glass on the assembly during construction. Regular glass airlocks just require
+ a sheet of glass.
+2017-04-17:
+ KasparoVy:
+ - bugfix: The God-emperor of Mankind diskette's UI works again.
+ - bugfix: DNA UI injectors will now immediately update a person's eye colour.
+ Krausus:
+ - bugfix: You can no longer squeeze non-match objects into matchboxes.
+2017-04-19:
+ IK3I:
+ - bugfix: Chaplain now spawns with his bible
+ Xantholne:
+ - bugfix: You now correctly spawn with the CMO Skirt if selected in loadout menu
+2017-04-21:
+ Anticept:
+ - tweak: Alternate Job Preference now defaults to "Return to Lobby if Preferences
+ Unavailable". Only affects new players.
+ Fox McCloud:
+ - tweak: Tesla can now damage blobs
+ - tweak: Tesla causes machinery to overload and explode when zapping it
+ - tweak: Tesla dissipates energy more slowly and is easier to charge up (making
+ it more deadly when released)
+ - tweak: Tesla will now dust mobs it bumps into
+ - rscadd: Tesla coils now have wires that can be pulsed to generate a tesla zap
+ Lady-Luck:
+ - tweak: Makes several balance adjustments to existing syndicate bundles, generally
+ making them more worthwhile.
+ - rscadd: Adds an Allies Cocktail object for the Bond bundle.
+ - rscadd: Adds the 'gadgets' syndicate bundle.
+ - rscdel: Removes the 'lordsingulo' and 'murder' syndicate bundles.
+ Spacemanspark:
+ - rscadd: Permits hoodies to carry flashlights.
+ Twinmold93:
+ - rscadd: Adds attack options for deep fryers, grills, and ovens. Those breaking
+ into the kitchen beware.
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index a7962c37ec1..e0bc6105f06 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/goonstation/objects/money.dmi b/icons/goonstation/objects/money.dmi
new file mode 100644
index 00000000000..c4f6508f025
Binary files /dev/null and b/icons/goonstation/objects/money.dmi differ
diff --git a/icons/mecha/mech_construct.dmi b/icons/mecha/mech_construct.dmi
index 8d97261c9bb..10a6d9b86fd 100644
Binary files a/icons/mecha/mech_construct.dmi and b/icons/mecha/mech_construct.dmi differ
diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi
index db8191aed53..e5a33e76de3 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 7764cd6d0c5..1c4472d5299 100644
Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ
diff --git a/icons/mob/belt.dmi b/icons/mob/belt.dmi
index b6089236f2a..93630adce9a 100644
Binary files a/icons/mob/belt.dmi and b/icons/mob/belt.dmi differ
diff --git a/icons/mob/body_accessory.dmi b/icons/mob/body_accessory.dmi
index 8d635c2c2df..5400c933c7f 100644
Binary files a/icons/mob/body_accessory.dmi and b/icons/mob/body_accessory.dmi differ
diff --git a/icons/mob/clothing/paranormal_hardsuit.dmi b/icons/mob/clothing/paranormal_hardsuit.dmi
deleted file mode 100644
index f06e81ab1e7..00000000000
Binary files a/icons/mob/clothing/paranormal_hardsuit.dmi and /dev/null differ
diff --git a/icons/mob/custom-synthetic.dmi b/icons/mob/custom-synthetic.dmi
deleted file mode 100644
index 709a6e2f0da..00000000000
Binary files a/icons/mob/custom-synthetic.dmi and /dev/null differ
diff --git a/icons/mob/custom_synthetic/custom-synthetic.dmi b/icons/mob/custom_synthetic/custom-synthetic.dmi
new file mode 100644
index 00000000000..29917049c85
Binary files /dev/null and b/icons/mob/custom_synthetic/custom-synthetic.dmi differ
diff --git a/icons/mob/custom-synthetic64.dmi b/icons/mob/custom_synthetic/custom-synthetic64.dmi
similarity index 100%
rename from icons/mob/custom-synthetic64.dmi
rename to icons/mob/custom_synthetic/custom-synthetic64.dmi
diff --git a/icons/mob/custom_synthetic/custom_head.dmi b/icons/mob/custom_synthetic/custom_head.dmi
new file mode 100644
index 00000000000..76ffcedcc82
Binary files /dev/null and b/icons/mob/custom_synthetic/custom_head.dmi differ
diff --git a/icons/mob/custom_synthetic/custom_lefthand.dmi b/icons/mob/custom_synthetic/custom_lefthand.dmi
new file mode 100644
index 00000000000..8d469195434
Binary files /dev/null and b/icons/mob/custom_synthetic/custom_lefthand.dmi differ
diff --git a/icons/mob/custom_synthetic/custom_righthand.dmi b/icons/mob/custom_synthetic/custom_righthand.dmi
new file mode 100644
index 00000000000..8d469195434
Binary files /dev/null and b/icons/mob/custom_synthetic/custom_righthand.dmi differ
diff --git a/icons/mob/eyes.dmi b/icons/mob/eyes.dmi
index 97966c61dac..fdf13394f20 100644
Binary files a/icons/mob/eyes.dmi and b/icons/mob/eyes.dmi differ
diff --git a/icons/mob/feet.dmi b/icons/mob/feet.dmi
index 1a4810c7fbc..659c3d2e9d2 100644
Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ
diff --git a/icons/mob/hands.dmi b/icons/mob/hands.dmi
index d4f0b3ac57a..a5a14094fd6 100644
Binary files a/icons/mob/hands.dmi and b/icons/mob/hands.dmi differ
diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi
index 93d81f6923e..acfaf83a92c 100644
Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ
diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi
index 25722400d84..4959f0ebb53 100644
Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ
diff --git a/icons/mob/human_races/cyberlimbs/shellguard/shellguard_alt1.dmi b/icons/mob/human_races/cyberlimbs/shellguard/shellguard_alt1.dmi
new file mode 100644
index 00000000000..1b52131cfde
Binary files /dev/null and b/icons/mob/human_races/cyberlimbs/shellguard/shellguard_alt1.dmi differ
diff --git a/icons/mob/human_races/cyberlimbs/shellguard/shellguard_main.dmi b/icons/mob/human_races/cyberlimbs/shellguard/shellguard_main.dmi
new file mode 100644
index 00000000000..d0db48eb310
Binary files /dev/null and b/icons/mob/human_races/cyberlimbs/shellguard/shellguard_main.dmi differ
diff --git a/icons/mob/human_races/cyberlimbs/shellguard/shellguard_monitor.dmi b/icons/mob/human_races/cyberlimbs/shellguard/shellguard_monitor.dmi
new file mode 100644
index 00000000000..6bd25bee030
Binary files /dev/null and b/icons/mob/human_races/cyberlimbs/shellguard/shellguard_monitor.dmi differ
diff --git a/icons/mob/human_races/r_def_kidan.dmi b/icons/mob/human_races/r_def_kidan.dmi
index 9cef8f9597c..0f84cde5dec 100644
Binary files a/icons/mob/human_races/r_def_kidan.dmi and b/icons/mob/human_races/r_def_kidan.dmi differ
diff --git a/icons/mob/human_races/r_def_skrell.dmi b/icons/mob/human_races/r_def_skrell.dmi
index 601534919eb..61ed4415ceb 100644
Binary files a/icons/mob/human_races/r_def_skrell.dmi and b/icons/mob/human_races/r_def_skrell.dmi differ
diff --git a/icons/mob/human_races/r_kidan.dmi b/icons/mob/human_races/r_kidan.dmi
index 9cef8f9597c..0f84cde5dec 100644
Binary files a/icons/mob/human_races/r_kidan.dmi and b/icons/mob/human_races/r_kidan.dmi differ
diff --git a/icons/mob/human_races/r_skrell.dmi b/icons/mob/human_races/r_skrell.dmi
index 586714c7da8..148c8d42d27 100644
Binary files a/icons/mob/human_races/r_skrell.dmi and b/icons/mob/human_races/r_skrell.dmi differ
diff --git a/icons/mob/inhands/clothing_lefthand.dmi b/icons/mob/inhands/clothing_lefthand.dmi
index 34e2a6ce696..29ebf19be94 100644
Binary files a/icons/mob/inhands/clothing_lefthand.dmi and b/icons/mob/inhands/clothing_lefthand.dmi differ
diff --git a/icons/mob/inhands/clothing_righthand.dmi b/icons/mob/inhands/clothing_righthand.dmi
index 2753f52dfee..0d43b6216f7 100644
Binary files a/icons/mob/inhands/clothing_righthand.dmi and b/icons/mob/inhands/clothing_righthand.dmi differ
diff --git a/icons/mob/inhands/fluff_lefthand.dmi b/icons/mob/inhands/fluff_lefthand.dmi
new file mode 100644
index 00000000000..84380f038ed
Binary files /dev/null and b/icons/mob/inhands/fluff_lefthand.dmi differ
diff --git a/icons/mob/inhands/fluff_righthand.dmi b/icons/mob/inhands/fluff_righthand.dmi
new file mode 100644
index 00000000000..d93ab0ffc68
Binary files /dev/null and b/icons/mob/inhands/fluff_righthand.dmi differ
diff --git a/icons/mob/inhands/guns_righthand.dmi b/icons/mob/inhands/guns_righthand.dmi
index 359045c25e0..d0c1b7bacda 100644
Binary files a/icons/mob/inhands/guns_righthand.dmi and b/icons/mob/inhands/guns_righthand.dmi differ
diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi
index 0c9090c5b81..6d0661c8911 100644
Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ
diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi
index 0f889055ad0..7dc7b163c54 100644
Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ
diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi
index fd305492464..636e78a7a43 100644
Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ
diff --git a/icons/mob/robots.dmi b/icons/mob/robots.dmi
index 062fb83e28b..2edbeefab9e 100644
Binary files a/icons/mob/robots.dmi and b/icons/mob/robots.dmi differ
diff --git a/icons/mob/species/armalis/suit.dmi b/icons/mob/species/armalis/suit.dmi
index cecf7e414b4..ceed59b7819 100644
Binary files a/icons/mob/species/armalis/suit.dmi and b/icons/mob/species/armalis/suit.dmi differ
diff --git a/icons/mob/species/drask/helmet.dmi b/icons/mob/species/drask/helmet.dmi
index 9c4ccd89c4b..b1ffbe8056f 100644
Binary files a/icons/mob/species/drask/helmet.dmi and b/icons/mob/species/drask/helmet.dmi differ
diff --git a/icons/mob/species/drask/suit.dmi b/icons/mob/species/drask/suit.dmi
index b7631041271..6e608313eda 100644
Binary files a/icons/mob/species/drask/suit.dmi and b/icons/mob/species/drask/suit.dmi differ
diff --git a/icons/mob/species/drask/uniform.dmi b/icons/mob/species/drask/uniform.dmi
index 6610948f641..9dd5a22618c 100644
Binary files a/icons/mob/species/drask/uniform.dmi and b/icons/mob/species/drask/uniform.dmi differ
diff --git a/icons/mob/species/plasmaman/helmet.dmi b/icons/mob/species/plasmaman/helmet.dmi
new file mode 100644
index 00000000000..f4771885c77
Binary files /dev/null and b/icons/mob/species/plasmaman/helmet.dmi differ
diff --git a/icons/mob/species/plasmaman/suit.dmi b/icons/mob/species/plasmaman/suit.dmi
new file mode 100644
index 00000000000..526211ef0ea
Binary files /dev/null and b/icons/mob/species/plasmaman/suit.dmi differ
diff --git a/icons/mob/species/skrell/helmet.dmi b/icons/mob/species/skrell/helmet.dmi
index 8e2965371c0..97f3c7626c4 100644
Binary files a/icons/mob/species/skrell/helmet.dmi and b/icons/mob/species/skrell/helmet.dmi differ
diff --git a/icons/mob/species/skrell/suit.dmi b/icons/mob/species/skrell/suit.dmi
index d0a12f2d0da..5e6d99b2ae8 100644
Binary files a/icons/mob/species/skrell/suit.dmi and b/icons/mob/species/skrell/suit.dmi differ
diff --git a/icons/mob/species/tajaran/helmet.dmi b/icons/mob/species/tajaran/helmet.dmi
index 49f209387bf..40474762635 100644
Binary files a/icons/mob/species/tajaran/helmet.dmi and b/icons/mob/species/tajaran/helmet.dmi differ
diff --git a/icons/mob/species/tajaran/suit.dmi b/icons/mob/species/tajaran/suit.dmi
index eedf3501cb1..98454026846 100644
Binary files a/icons/mob/species/tajaran/suit.dmi and b/icons/mob/species/tajaran/suit.dmi differ
diff --git a/icons/mob/species/unathi/feet.dmi b/icons/mob/species/unathi/feet.dmi
new file mode 100644
index 00000000000..2c5cc99db2e
Binary files /dev/null and b/icons/mob/species/unathi/feet.dmi differ
diff --git a/icons/mob/species/unathi/gloves.dmi b/icons/mob/species/unathi/gloves.dmi
new file mode 100644
index 00000000000..808736e4cfd
Binary files /dev/null and b/icons/mob/species/unathi/gloves.dmi differ
diff --git a/icons/mob/species/unathi/helmet.dmi b/icons/mob/species/unathi/helmet.dmi
index c84122e9571..f969705ec83 100644
Binary files a/icons/mob/species/unathi/helmet.dmi and b/icons/mob/species/unathi/helmet.dmi differ
diff --git a/icons/mob/species/unathi/suit.dmi b/icons/mob/species/unathi/suit.dmi
index f30cb9facef..ebbfa5f9c73 100644
Binary files a/icons/mob/species/unathi/suit.dmi and b/icons/mob/species/unathi/suit.dmi differ
diff --git a/icons/mob/species/vox/head.dmi b/icons/mob/species/vox/head.dmi
index bca96cddb8f..94355509bc0 100644
Binary files a/icons/mob/species/vox/head.dmi and b/icons/mob/species/vox/head.dmi differ
diff --git a/icons/mob/species/vox/helmet.dmi b/icons/mob/species/vox/helmet.dmi
index 869d98223cf..c9227ce2119 100644
Binary files a/icons/mob/species/vox/helmet.dmi and b/icons/mob/species/vox/helmet.dmi differ
diff --git a/icons/mob/species/vox/mask.dmi b/icons/mob/species/vox/mask.dmi
index 93dacb8f058..23ec9ba3c43 100644
Binary files a/icons/mob/species/vox/mask.dmi and b/icons/mob/species/vox/mask.dmi differ
diff --git a/icons/mob/species/vox/shoes.dmi b/icons/mob/species/vox/shoes.dmi
index f3cc54d72e0..83d6b9870ce 100644
Binary files a/icons/mob/species/vox/shoes.dmi and b/icons/mob/species/vox/shoes.dmi differ
diff --git a/icons/mob/species/vox/suit.dmi b/icons/mob/species/vox/suit.dmi
index 311bc31623a..4584f489ca6 100644
Binary files a/icons/mob/species/vox/suit.dmi and b/icons/mob/species/vox/suit.dmi differ
diff --git a/icons/mob/species/vulpkanin/helmet.dmi b/icons/mob/species/vulpkanin/helmet.dmi
index 9be69155ee3..ce0f9c0e548 100644
Binary files a/icons/mob/species/vulpkanin/helmet.dmi and b/icons/mob/species/vulpkanin/helmet.dmi differ
diff --git a/icons/mob/species/vulpkanin/suit.dmi b/icons/mob/species/vulpkanin/suit.dmi
index ad946a3805b..6245547df30 100644
Binary files a/icons/mob/species/vulpkanin/suit.dmi and b/icons/mob/species/vulpkanin/suit.dmi differ
diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi
index d915f6941a7..03c1180b1dc 100644
Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ
diff --git a/icons/mob/suit_fat.dmi b/icons/mob/suit_fat.dmi
index a5cb6b72066..79bed1d0538 100644
Binary files a/icons/mob/suit_fat.dmi and b/icons/mob/suit_fat.dmi differ
diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi
index f2c1c3a1311..7742bdcc755 100644
Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ
diff --git a/icons/obj/abductor.dmi b/icons/obj/abductor.dmi
index 9a171b97645..7bcd0607116 100644
Binary files a/icons/obj/abductor.dmi and b/icons/obj/abductor.dmi differ
diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi
index 902bb2452ef..40d52d003bc 100644
Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ
diff --git a/icons/obj/clothing/belts.dmi b/icons/obj/clothing/belts.dmi
index ae8fa296794..cfcfec6e283 100644
Binary files a/icons/obj/clothing/belts.dmi and b/icons/obj/clothing/belts.dmi differ
diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi
index fd2947d7d69..227ec28b742 100644
Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ
diff --git a/icons/obj/clothing/gloves.dmi b/icons/obj/clothing/gloves.dmi
index 48d253c16cb..82ce8437b28 100644
Binary files a/icons/obj/clothing/gloves.dmi and b/icons/obj/clothing/gloves.dmi differ
diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi
index f12fcf3d86c..0aece3ac8ac 100644
Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ
diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi
index 8faec500e7b..974efa8a088 100644
Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ
diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi
index 1fbcc049e6b..b92c02e7166 100644
Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ
diff --git a/icons/obj/clothing/species/plasmaman/hats.dmi b/icons/obj/clothing/species/plasmaman/hats.dmi
new file mode 100644
index 00000000000..19bb100595c
Binary files /dev/null and b/icons/obj/clothing/species/plasmaman/hats.dmi differ
diff --git a/icons/obj/clothing/species/plasmaman/suits.dmi b/icons/obj/clothing/species/plasmaman/suits.dmi
new file mode 100644
index 00000000000..b9695f0ff27
Binary files /dev/null and b/icons/obj/clothing/species/plasmaman/suits.dmi differ
diff --git a/icons/obj/clothing/species/skrell/hats.dmi b/icons/obj/clothing/species/skrell/hats.dmi
index f5a7f54df0d..c2d81d0d54f 100644
Binary files a/icons/obj/clothing/species/skrell/hats.dmi and b/icons/obj/clothing/species/skrell/hats.dmi differ
diff --git a/icons/obj/clothing/species/skrell/suits.dmi b/icons/obj/clothing/species/skrell/suits.dmi
index 64bee068fa8..0d67f1f9c71 100644
Binary files a/icons/obj/clothing/species/skrell/suits.dmi and b/icons/obj/clothing/species/skrell/suits.dmi differ
diff --git a/icons/obj/clothing/species/tajaran/hats.dmi b/icons/obj/clothing/species/tajaran/hats.dmi
index e83fc173fee..e41451f71f8 100644
Binary files a/icons/obj/clothing/species/tajaran/hats.dmi and b/icons/obj/clothing/species/tajaran/hats.dmi differ
diff --git a/icons/obj/clothing/species/tajaran/suits.dmi b/icons/obj/clothing/species/tajaran/suits.dmi
index c107c13e415..d60a0a6840f 100644
Binary files a/icons/obj/clothing/species/tajaran/suits.dmi and b/icons/obj/clothing/species/tajaran/suits.dmi differ
diff --git a/icons/obj/clothing/species/unathi/gloves.dmi b/icons/obj/clothing/species/unathi/gloves.dmi
new file mode 100644
index 00000000000..26ce9ca8ac5
Binary files /dev/null and b/icons/obj/clothing/species/unathi/gloves.dmi differ
diff --git a/icons/obj/clothing/species/unathi/hats.dmi b/icons/obj/clothing/species/unathi/hats.dmi
index f55259fadf4..be2fb4f62aa 100644
Binary files a/icons/obj/clothing/species/unathi/hats.dmi and b/icons/obj/clothing/species/unathi/hats.dmi differ
diff --git a/icons/obj/clothing/species/unathi/shoes.dmi b/icons/obj/clothing/species/unathi/shoes.dmi
new file mode 100644
index 00000000000..78f74765a76
Binary files /dev/null and b/icons/obj/clothing/species/unathi/shoes.dmi differ
diff --git a/icons/obj/clothing/species/unathi/suits.dmi b/icons/obj/clothing/species/unathi/suits.dmi
index f0be55a5291..34c3ea75105 100644
Binary files a/icons/obj/clothing/species/unathi/suits.dmi and b/icons/obj/clothing/species/unathi/suits.dmi differ
diff --git a/icons/obj/clothing/species/vox/gloves.dmi b/icons/obj/clothing/species/vox/gloves.dmi
new file mode 100644
index 00000000000..eeca4b63f30
Binary files /dev/null and b/icons/obj/clothing/species/vox/gloves.dmi differ
diff --git a/icons/obj/clothing/species/vox/hats.dmi b/icons/obj/clothing/species/vox/hats.dmi
index 2680137ff0a..922ede57f1a 100644
Binary files a/icons/obj/clothing/species/vox/hats.dmi and b/icons/obj/clothing/species/vox/hats.dmi differ
diff --git a/icons/obj/clothing/species/vox/shoes.dmi b/icons/obj/clothing/species/vox/shoes.dmi
new file mode 100644
index 00000000000..a1dde383ff7
Binary files /dev/null and b/icons/obj/clothing/species/vox/shoes.dmi differ
diff --git a/icons/obj/clothing/species/vox/suits.dmi b/icons/obj/clothing/species/vox/suits.dmi
index 3d23ba1e396..4dc0ade4fb8 100644
Binary files a/icons/obj/clothing/species/vox/suits.dmi and b/icons/obj/clothing/species/vox/suits.dmi differ
diff --git a/icons/obj/clothing/species/vox/uniforms.dmi b/icons/obj/clothing/species/vox/uniforms.dmi
new file mode 100644
index 00000000000..4bf1b92308d
Binary files /dev/null and b/icons/obj/clothing/species/vox/uniforms.dmi differ
diff --git a/icons/obj/clothing/species/vulpkanin/hats.dmi b/icons/obj/clothing/species/vulpkanin/hats.dmi
index ee64e02158f..3e97b07e15b 100644
Binary files a/icons/obj/clothing/species/vulpkanin/hats.dmi and b/icons/obj/clothing/species/vulpkanin/hats.dmi differ
diff --git a/icons/obj/clothing/species/vulpkanin/suits.dmi b/icons/obj/clothing/species/vulpkanin/suits.dmi
index 22617558677..30cb26b4c62 100644
Binary files a/icons/obj/clothing/species/vulpkanin/suits.dmi and b/icons/obj/clothing/species/vulpkanin/suits.dmi differ
diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi
index be68443c2bf..669e8dff821 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 40f4c4c2b07..1db72be54fa 100644
Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ
diff --git a/icons/obj/custom_items.dmi b/icons/obj/custom_items.dmi
index 27e4ffc2c61..9623f991e2f 100644
Binary files a/icons/obj/custom_items.dmi and b/icons/obj/custom_items.dmi differ
diff --git a/icons/obj/decorations.dmi b/icons/obj/decorations.dmi
index 02916e632f0..a3b7f9dcd20 100644
Binary files a/icons/obj/decorations.dmi and b/icons/obj/decorations.dmi differ
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index 6e749fc11ec..afa4f586504 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/icons/obj/doors/Doorfire.dmi b/icons/obj/doors/Doorfire.dmi
index 1f3999b774e..94ec8b967fb 100644
Binary files a/icons/obj/doors/Doorfire.dmi and b/icons/obj/doors/Doorfire.dmi differ
diff --git a/icons/obj/drinks.dmi b/icons/obj/drinks.dmi
index 730c5d5632c..52eb53ac436 100644
Binary files a/icons/obj/drinks.dmi and b/icons/obj/drinks.dmi differ
diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi
index 25edd2c325a..283684b9d46 100644
Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ
diff --git a/icons/obj/hydroponics/equipment.dmi b/icons/obj/hydroponics/equipment.dmi
index 189d1682194..3b1c4c07cfa 100644
Binary files a/icons/obj/hydroponics/equipment.dmi and b/icons/obj/hydroponics/equipment.dmi differ
diff --git a/icons/obj/hydroponics/growing_mushrooms.dmi b/icons/obj/hydroponics/growing_mushrooms.dmi
index eb4405bf8bf..7a0eedbdae7 100644
Binary files a/icons/obj/hydroponics/growing_mushrooms.dmi and b/icons/obj/hydroponics/growing_mushrooms.dmi differ
diff --git a/icons/obj/hydroponics/harvest.dmi b/icons/obj/hydroponics/harvest.dmi
index 0adedb879e9..d5bb7d48acb 100644
Binary files a/icons/obj/hydroponics/harvest.dmi and b/icons/obj/hydroponics/harvest.dmi differ
diff --git a/icons/obj/hydroponics/seeds.dmi b/icons/obj/hydroponics/seeds.dmi
index 5e28a475cf3..edc0ee4894f 100644
Binary files a/icons/obj/hydroponics/seeds.dmi and b/icons/obj/hydroponics/seeds.dmi differ
diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi
index 186e7d05232..2735d145ac8 100644
Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ
diff --git a/icons/obj/lighting.dmi b/icons/obj/lighting.dmi
index 06afc67979c..484417b9e83 100644
Binary files a/icons/obj/lighting.dmi and b/icons/obj/lighting.dmi differ
diff --git a/icons/obj/machines/particle_accelerator.dmi b/icons/obj/machines/particle_accelerator.dmi
index 905d1737ec8..f8455d80b49 100644
Binary files a/icons/obj/machines/particle_accelerator.dmi and b/icons/obj/machines/particle_accelerator.dmi differ
diff --git a/icons/obj/modular_console.dmi b/icons/obj/modular_console.dmi
new file mode 100644
index 00000000000..85d6026617f
Binary files /dev/null and b/icons/obj/modular_console.dmi differ
diff --git a/icons/obj/modular_laptop.dmi b/icons/obj/modular_laptop.dmi
new file mode 100644
index 00000000000..2daeee0c7a4
Binary files /dev/null and b/icons/obj/modular_laptop.dmi differ
diff --git a/icons/obj/modular_tablet.dmi b/icons/obj/modular_tablet.dmi
new file mode 100644
index 00000000000..2438f375f65
Binary files /dev/null and b/icons/obj/modular_tablet.dmi differ
diff --git a/icons/obj/money.dmi b/icons/obj/money.dmi
deleted file mode 100644
index 5a053c07e05..00000000000
Binary files a/icons/obj/money.dmi and /dev/null differ
diff --git a/icons/obj/objects.dmi b/icons/obj/objects.dmi
index c02603ecd25..e95b9ce041f 100644
Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ
diff --git a/icons/obj/power.dmi b/icons/obj/power.dmi
index 5977cd3cb66..e9de23533ed 100644
Binary files a/icons/obj/power.dmi and b/icons/obj/power.dmi differ
diff --git a/icons/obj/stationobjs.dmi b/icons/obj/stationobjs.dmi
index 72084b5675b..fd89b23d19d 100755
Binary files a/icons/obj/stationobjs.dmi and b/icons/obj/stationobjs.dmi differ
diff --git a/icons/obj/statue.dmi b/icons/obj/statue.dmi
index 74febfe53bc..e5deb9a0ec4 100644
Binary files a/icons/obj/statue.dmi and b/icons/obj/statue.dmi differ
diff --git a/icons/obj/statuelarge.dmi b/icons/obj/statuelarge.dmi
new file mode 100644
index 00000000000..e45afb8db8a
Binary files /dev/null and b/icons/obj/statuelarge.dmi differ
diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi
index 6c3fdcf2bee..ba4485bdbf8 100644
Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ
diff --git a/icons/obj/tesla_engine/tesla_coil.dmi b/icons/obj/tesla_engine/tesla_coil.dmi
index 5c3646dde80..96a6c636d83 100644
Binary files a/icons/obj/tesla_engine/tesla_coil.dmi and b/icons/obj/tesla_engine/tesla_coil.dmi differ
diff --git a/icons/obj/tiles.dmi b/icons/obj/tiles.dmi
index 3de478d728d..e4fedae838b 100644
Binary files a/icons/obj/tiles.dmi and b/icons/obj/tiles.dmi differ
diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi
index 332afbbdb71..a78a0babdc4 100644
Binary files a/icons/obj/tools.dmi and b/icons/obj/tools.dmi differ
diff --git a/icons/program_icons/alarm_green.gif b/icons/program_icons/alarm_green.gif
new file mode 100644
index 00000000000..7c2570c8ce3
Binary files /dev/null and b/icons/program_icons/alarm_green.gif differ
diff --git a/icons/program_icons/alarm_red.gif b/icons/program_icons/alarm_red.gif
new file mode 100644
index 00000000000..327d58e4db8
Binary files /dev/null and b/icons/program_icons/alarm_red.gif differ
diff --git a/icons/program_icons/batt_100.gif b/icons/program_icons/batt_100.gif
new file mode 100644
index 00000000000..ccdbd4333e9
Binary files /dev/null and b/icons/program_icons/batt_100.gif differ
diff --git a/icons/program_icons/batt_20.gif b/icons/program_icons/batt_20.gif
new file mode 100644
index 00000000000..1d5e38fc888
Binary files /dev/null and b/icons/program_icons/batt_20.gif differ
diff --git a/icons/program_icons/batt_40.gif b/icons/program_icons/batt_40.gif
new file mode 100644
index 00000000000..d5cedb99675
Binary files /dev/null and b/icons/program_icons/batt_40.gif differ
diff --git a/icons/program_icons/batt_5.gif b/icons/program_icons/batt_5.gif
new file mode 100644
index 00000000000..ceac8f3a945
Binary files /dev/null and b/icons/program_icons/batt_5.gif differ
diff --git a/icons/program_icons/batt_60.gif b/icons/program_icons/batt_60.gif
new file mode 100644
index 00000000000..d39534c8cb0
Binary files /dev/null and b/icons/program_icons/batt_60.gif differ
diff --git a/icons/program_icons/batt_80.gif b/icons/program_icons/batt_80.gif
new file mode 100644
index 00000000000..9c299773f01
Binary files /dev/null and b/icons/program_icons/batt_80.gif differ
diff --git a/icons/program_icons/charging.gif b/icons/program_icons/charging.gif
new file mode 100644
index 00000000000..cf19ca72876
Binary files /dev/null and b/icons/program_icons/charging.gif differ
diff --git a/icons/program_icons/downloader_finished.gif b/icons/program_icons/downloader_finished.gif
new file mode 100644
index 00000000000..f01b7c42af8
Binary files /dev/null and b/icons/program_icons/downloader_finished.gif differ
diff --git a/icons/program_icons/downloader_running.gif b/icons/program_icons/downloader_running.gif
new file mode 100644
index 00000000000..68fb977c86d
Binary files /dev/null and b/icons/program_icons/downloader_running.gif differ
diff --git a/icons/program_icons/ntnrc_idle.gif b/icons/program_icons/ntnrc_idle.gif
new file mode 100644
index 00000000000..d47c01d5800
Binary files /dev/null and b/icons/program_icons/ntnrc_idle.gif differ
diff --git a/icons/program_icons/ntnrc_new.gif b/icons/program_icons/ntnrc_new.gif
new file mode 100644
index 00000000000..af72a8b332f
Binary files /dev/null and b/icons/program_icons/ntnrc_new.gif differ
diff --git a/icons/program_icons/power_norm.gif b/icons/program_icons/power_norm.gif
new file mode 100644
index 00000000000..2b8d60edfa5
Binary files /dev/null and b/icons/program_icons/power_norm.gif differ
diff --git a/icons/program_icons/power_warn.gif b/icons/program_icons/power_warn.gif
new file mode 100644
index 00000000000..0c85b3a85a1
Binary files /dev/null and b/icons/program_icons/power_warn.gif differ
diff --git a/icons/program_icons/sig_high.gif b/icons/program_icons/sig_high.gif
new file mode 100644
index 00000000000..efb20f67306
Binary files /dev/null and b/icons/program_icons/sig_high.gif differ
diff --git a/icons/program_icons/sig_lan.gif b/icons/program_icons/sig_lan.gif
new file mode 100644
index 00000000000..07ba929f7f3
Binary files /dev/null and b/icons/program_icons/sig_lan.gif differ
diff --git a/icons/program_icons/sig_low.gif b/icons/program_icons/sig_low.gif
new file mode 100644
index 00000000000..08f98baea8e
Binary files /dev/null and b/icons/program_icons/sig_low.gif differ
diff --git a/icons/program_icons/sig_none.gif b/icons/program_icons/sig_none.gif
new file mode 100644
index 00000000000..79840d8a2bd
Binary files /dev/null and b/icons/program_icons/sig_none.gif differ
diff --git a/icons/turf/areas.dmi b/icons/turf/areas.dmi
index baf07678ed8..cd8a26cea98 100755
Binary files a/icons/turf/areas.dmi and b/icons/turf/areas.dmi differ
diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi
index 66bd1893196..62ba9c4e66c 100644
Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ
diff --git a/icons/turf/shuttle.dmi b/icons/turf/shuttle.dmi
index 659ec0bcf2d..a122cdf1def 100644
Binary files a/icons/turf/shuttle.dmi and b/icons/turf/shuttle.dmi differ
diff --git a/icons/vehicles/motorcycle.dmi b/icons/vehicles/motorcycle.dmi
index 2f3c2d5517f..5b1a910b7b0 100644
Binary files a/icons/vehicles/motorcycle.dmi and b/icons/vehicles/motorcycle.dmi differ
diff --git a/nano/assets/nanoui.css b/nano/assets/nanoui.css
index d91a6ece4ae..9bba91a1376 100644
--- a/nano/assets/nanoui.css
+++ b/nano/assets/nanoui.css
@@ -1,2 +1,2 @@
-@font-face{font-family:FontAwesome;src:url(fontawesome-webfont.eot?v=4.5.0);src:url(fontawesome-webfont.eot?#iefix&v=4.5.0) format('embedded-opentype'),url(fontawesome-webfont.woff2?v=4.5.0) format('woff2'),url(fontawesome-webfont.woff?v=4.5.0) format('woff'),url(fontawesome-webfont.ttf?v=4.5.0) format('truetype'),url(fontawesome-webfont.svg?v=4.5.0#fontawesomeregular) format('svg');font-weight:400;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:a 2s infinite linear;animation:a 2s infinite linear}.fa-pulse{-webkit-animation:a 1s infinite steps(8);animation:a 1s infinite steps(8)}@-webkit-keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0,mirror=1);-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2,mirror=1);-webkit-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-close:before,.fa-remove:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-cog:before,.fa-gear:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-repeat:before,.fa-rotate-right:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-exclamation-triangle:before,.fa-warning:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-cogs:before,.fa-gears:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-floppy-o:before,.fa-save:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-sort:before,.fa-unsorted:before{content:"\f0dc"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-sort-asc:before,.fa-sort-up:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-gavel:before,.fa-legal:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-bolt:before,.fa-flash:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-chain-broken:before,.fa-unlink:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:"\f150"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:"\f151"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:"\f152"}.fa-eur:before,.fa-euro:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-inr:before,.fa-rupee:before{content:"\f156"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:"\f157"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:"\f158"}.fa-krw:before,.fa-won:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-try:before,.fa-turkish-lira:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:"\f19c"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:"\f1c5"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:"\f1c6"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-empire:before,.fa-ge:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-paper-plane:before,.fa-send:before{content:"\f1d8"}.fa-paper-plane-o:before,.fa-send-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-bed:before,.fa-hotel:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-y-combinator:before,.fa-yc:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-television:before,.fa-tv:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}
-.displayBar{position:relative;width:236px;height:16px;border:1px solid #666;float:left;margin:0 5px 0 0;overflow:hidden;background:#000}.displayBarText{position:absolute;top:-2px;left:5px;width:100%;height:100%;color:#fff;font-weight:400}.displayBarFill{width:0;height:100%;background:#40628a;overflow:hidden;float:left}.displayBarFill.alignRight{float:right}.displayBarText.average,.displayBarText.bad,.displayBarText.good,.displayBarText.notgood{color:#fff}.displayBarText.highlight{color:#000}.displayBarFill.good{color:#fff;background:#4f7529}.displayBarFill.notgood{color:#fff;background:#ffb400}.displayBarFill.average{color:#fff;background:#cd6500}.displayBarFill.bad{color:#fff;background:#e00}.displayBarFill.highlight{color:#fff;background:#8ba5c4}.disabled,.link,.linkOff,.linkOn,.redButton,.selected,.yellowButton{float:left;min-width:15px;height:16px;text-align:center;color:#fff;text-decoration:none;background:#40628a;border:1px solid #161616;padding:0 4px 4px;margin:0 2px 2px 0;cursor:default;white-space:nowrap}.hasIcon{padding:0 4px 4px 0}.linkActive.hover,.zoomLink.hover,a.hover{background:#507aac}@keyframes a{to{color:#fff;background:#507aac}}.linkPending,.linkPending.hover{animation-name:a;animation-duration:.25s}a.white,a.white:active,a.white:link,a.white:visited{color:#40628a;text-decoration:none;background:#fff;border:1px solid #161616;padding:1px 4px;margin:0 2px 0 0;cursor:default}a.white.hover{color:#fff;background:#40628a}.linkOn,.selected,a.linkOn.hover,a.linkOn:active,a.linkOn:link,a.linkOn:visited,a.selected.hover,a.selected:active,a.selected:link,a.selected:visited{color:#fff;background:#2f943c}.disabled,.linkOff,a.disabled.hover,a.disabled:active,a.disabled:link,a.disabled:visited,a.linkOff.hover,a.linkOff:active,a.linkOff:link,a.linkOff:visited{color:#fff;background:#999;border-color:#666}.disabled.icon,.linkOff.icon,.linkOn.icon,.selected.icon,a.icon{position:relative;padding:1px 4px 2px 20px}.disabled.icon img,.linkOff.icon img,.linkOn.icon img,.selected.icon img,a.icon img{position:absolute;top:0;left:0;width:18px;height:18px}.linkDanger,a.linkDanger:active,a.linkDanger:link,a.linkDanger:visited{color:#fff;background-color:red;border-color:#a00}.linkDanger.hover{background-color:#f66}.inactive,a.inactive.hover,a.inactive:active,a.inactive:link,a.inactive:visited{color:#fff;background:#999;border-color:#666}.white{color:#fff}.good,.white{font-weight:700}.good{color:#4f7529}.average{color:#cd6500}.average,.bad{font-weight:700}.bad{color:#e00}.idle{color:#272727;font-weight:700}.redButton{background:#ea0000}.yellowButton{background:#cacc00}.highlight{color:#8ba5c4}.dark{color:#272727}.burn{color:orange}.brute{color:red}.toxin{color:green}.toxin_light{color:#3adf00}.oxyloss{color:blue}.oxyloss_light{color:#6698ff}.Red{color:red}.Blue{color:#00f}.Green{color:#0f0}.Marigold{color:#fda505}.Fuschia{color:#ff0080}.Black{color:#000}.Pearl{color:#c6cacb}.cold1{color:#94b8ff}.cold2{color:#69f}.cold3{color:#293d66}.hot1{color:#f96}.hot2{color:#993d00}.hot3{color:#f60}.itemGroup{border:1px solid #e9c183;background:#2c2c2c;padding:4px;clear:both}.item{width:100%;margin:4px 0 0;clear:both;overflow:auto}.itemContent,.itemContentNarrow{float:left}.itemContentNarrow{width:30%}.itemContent{width:69%}.itemLabel,.itemLabelNarrow,.itemLabelWide,.itemLabelWider,.itemLabelWidest{float:left;color:#e9c183}.itemLabelNarrow{width:20%}.itemLabel{width:30%}.itemLabelWide{width:45%}.itemLabelWider{width:69%}.itemLabelWidest{width:100%}.itemContentWide{float:left;width:79%}.itemContentSmall{float:left;width:33%}.itemContentMedium{float:left;width:55%}.block{padding:8px;margin:10px 4px 4px;border:1px solid #40628a;background-color:#202020}.block h3{padding:0}.clearBoth{clear:both}.clearLeft{clear:left}.clearRight{clear:right}.line{width:100%;clear:both}.fixedLeft{width:110px;float:left}.fixedLeftWide{width:165px;float:left}.fixedLeftWider{width:220px;float:left}.fixedLeftWidest{width:250px;float:left}.floatRight{float:right}.floatLeft{float:left}.hidden{display:none}.statusDisplay{overflow:hidden}.statusDisplay,.statusDisplayRecords{background:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background:rgba(0,0,0,.5);color:#fff;border:1px solid #40628a;padding:4px;margin:3px 0}.statusDisplayRecords{overflow-x:hidden;overflow-y:auto}.statusLabel{width:138px;float:left;overflow:hidden;color:#98b0c3}.statusValue{float:left}.fancy{display:none}.minimize{color:#e9c183;position:absolute;top:6px;right:46px}.minimize.hover{color:#b8c9d6}.close{color:#e9c183;position:absolute;top:4px;right:12px}.close.hover{color:#b8c9d6}div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 30px 30px;border-color:transparent transparent #363636;transform:rotate(1turn)}.uiLinkPendingIcon{display:none;float:left;width:16px;height:16px;margin:2px 2px 0;background-image:url(uiLinkPendingIcon.gif)}.linkPending .fa{display:none}.linkPending .uiLinkPendingIcon{display:block}.mapIcon16{position:absolute;width:16px;height:16px;background-image:url(uiIcons16Green.png);background-position:-144px -96px;background-repeat:no-repeat;zoom:.125;margin-left:-1px}.mapIcon16.bad,.mapIcon16.dead{background-image:url(uiIcons16Red.png)}.mapIcon16.average{background-image:url(uiIcons16Orange.png)}.mapIcon16.good{background-image:url(uiIcons16Green.png)}.mapIcon16.icon-airalarm{background-position:0 -144px}.mapIcon16.rank-captain{background-position:-224px -112px}.mapIcon16.rank-headofpersonnel{background-position:-112px -96px}.mapIcon16.rank-headofsecurity{background-position:-112px -128px}.mapIcon16.rank-chiefengineer{background-position:-176px -112px}.mapIcon16.rank-researchdirector{background-position:-128px -128px}.mapIcon16.rank-chiefmedicalofficer{background-position:-32px -128px}.mapIcon16.rank-atmospherictechnician,.mapIcon16.rank-stationengineer{background-position:-176px -112px}.mapIcon16.rank-chemist,.mapIcon16.rank-geneticist,.mapIcon16.rank-medicaldoctor,.mapIcon16.rank-psychiatrist{background-position:-32px -128px}.mapIcon16.rank-geneticist,.mapIcon16.rank-roboticist,.mapIcon16.rank-scientist,.mapIcon16.rank-xenobiologist{background-position:-128px -128px}.mapIcon16.rank-detective,.mapIcon16.rank-securityofficer,.mapIcon16.rank-warden{background-position:-112px -128px}ul{padding:4px 0 0 10px;margin:0;list-style-type:none}li{padding:0 0 2px}table.fixed{table-layout:fixed}table.fixed td{overflow:hidden}table.pmon{border:2px solid #4169e1}table.pmon td,table.pmon th{border-bottom:1px dotted #000;padding:0 5px}th.command{background:#33f}th.command,th.sec{font-weight:700;color:#fff}th.sec{background:#8e0000}th.med{background:#060}th.eng,th.med{font-weight:700;color:#fff}th.eng{background:#b27300}th.sci{background:#a65ba6}th.sci,th.ser{font-weight:700;color:#fff}th.ser{background:#7100aa}th.sup{background:#666621}th.civ,th.sup{font-weight:700;color:#fff}th.civ{background:#a32800}th.misc{background:#666;font-weight:700;color:#fff}span.qm-job{color:#b77a41;font-weight:700}.striped:not(table)>:nth-child(even),.striped tr:nth-child(even){background-color:#404040}#uiNoScript{position:fixed;top:50%;left:50%;margin:-60px 0 0 -150px;width:280px;height:120px;background:#fff;border:2px solid red;color:#000;font-size:10px;font-weight:700;z-index:1;padding:0 10px;text-align:center}.notice{background:url(uiNoticeBackground.jpg) 50% 50%;color:#000}.notice,.noticePlaceholder{position:relative;font-size:12px;font-style:italic;font-weight:700;padding:3px 4px;margin:4px 0}.notice.icon{padding:2px 4px 0 20px}.notice img{position:absolute;top:0;left:0;width:16px;height:16px}div.notice{clear:both}.wholeScreen{position:absolute;color:#517087;font-size:16px;font-weight:700;text-align:center}.pdalink{float:left;white-space:nowrap;cursor:default!important}.pdalink.disabled{background:none;border:none;color:#999;text-align:left}.pdanote{color:#cd6500;font-weight:700}.item.mainmenu{padding-bottom:.5em}div.clock{color:#fff;font-weight:700;float:right;padding-right:2em}#pdaFooter{position:fixed;left:0;bottom:0;width:100%;background:#272727}.pdaFooterButton{width:33%;padding:.5em 0;font-size:200%;border:none;background:none;color:#fff}.pdaFooterButton.hover{background:#507aac}.pdaFooterButton.disabled{background:none!important;color:#555!important}.pdaFooterButton .uiLinkPendingIcon{position:absolute;width:33%;background-repeat:no-repeat;background-position:50%}.dnaBlock{float:left;width:90px;padding:0 0 5px}.dnaBlockNumber{color:#fff;background:#363636;min-width:20px}.dnaBlockNumber,.dnaSubBlock{font-family:Fixed,monospace;float:left;height:20px;padding:0;text-align:center}.dnaSubBlock{min-width:16px}.mask{position:fixed;left:0;top:0;width:100%;height:100%;background:url(uiMaskBackground.png)}.maskContent{width:100%;height:200px;margin:200px 0;text-align:center}body{background:#272727;color:#fff;font-family:Verdana,Geneva,sans-serif;font-size:12px;line-height:170%;margin:0;padding:0}hr{background-color:#40628a;height:1px;border:none}a img,img{border-style:none}h1,h2,h3,h4,h5,h6{margin:0;padding:12px 0 6px;color:#fff;clear:both}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1' viewBox='0 0 425 200' opacity='.25'%3E%3Cpath d='M178.004.039H106.8a6.761 6.026 0 0 0-6.761 6.025v187.872a6.761 6.026 0 0 0 6.761 6.025h53.107a6.761 6.026 0 0 0 6.762-6.025V92.392l72.216 104.7a6.761 6.026 0 0 0 5.76 2.87H318.2a6.761 6.026 0 0 0 6.761-6.026V6.064A6.761 6.026 0 0 0 318.2.04h-54.717a6.761 6.026 0 0 0-6.76 6.025v102.62L183.763 2.909a6.761 6.026 0 0 0-5.76-2.87zM4.845 22.109A13.412 12.502 0 0 1 13.478.039h66.118A5.365 5 0 0 1 84.96 5.04v79.88zM420.155 177.891a13.412 12.502 0 0 1-8.633 22.07h-66.118a5.365 5 0 0 1-5.365-5.001v-79.88z'/%3E%3C/svg%3E") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020) no-repeat fixed 50%/100% 100%;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2a2a2a',endColorstr='#ff202020',GradientType=0)}#uiWrapper{width:100%;height:100%;-ms-user-select:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}#uiTitleWrapper{position:relative;height:30px}#uiTitleText{position:absolute;top:6px;left:44px;width:66%;overflow:hidden;color:#e9c183;font-size:16px}#uiTitle.icon{padding:6px 8px 6px 42px;background-position:2px 50%;background-repeat:no-repeat}#uiTitleFluff{position:absolute;top:4px;right:12px;width:42px;height:24px;background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1' viewBox='0 0 425 200' opacity='.25'%3E%3Cpath d='M178.004.039H106.8a6.761 6.026 0 0 0-6.761 6.025v187.872a6.761 6.026 0 0 0 6.761 6.025h53.107a6.761 6.026 0 0 0 6.762-6.025V92.392l72.216 104.7a6.761 6.026 0 0 0 5.76 2.87H318.2a6.761 6.026 0 0 0 6.761-6.026V6.064A6.761 6.026 0 0 0 318.2.04h-54.717a6.761 6.026 0 0 0-6.76 6.025v102.62L183.763 2.909a6.761 6.026 0 0 0-5.76-2.87zM4.845 22.109A13.412 12.502 0 0 1 13.478.039h66.118A5.365 5 0 0 1 84.96 5.04v79.88zM420.155 177.891a13.412 12.502 0 0 1-8.633 22.07h-66.118a5.365 5 0 0 1-5.365-5.001v-79.88z'/%3E%3C/svg%3E") 50% 50% no-repeat}.statusicon{position:absolute;top:4px;left:12px}#uiMapWrapper{clear:both;padding:8px}#uiMapHeader{position:relative;clear:both}#uiMapContainer{position:relative;width:100%;height:600px;overflow:hidden;border:1px solid #40628a;background:url(nanomapBackground.png)}#uiMap{top:50%;left:50%;margin:-512px 0 0 -512px;overflow:hidden;zoom:4}#uiMap,#uiMapImage{position:absolute;width:256px;height:256px}#uiMapImage{bottom:1px;left:1px}#uiMapContent{position:absolute;bottom:-13.5px;left:0;width:256px;height:256px}#uiMapFooter{position:relative;clear:both}#uiContent{clear:both;padding:8px}#uiMapTooltip{position:absolute;right:10px;top:10px;border:1px solid #40628a;background-color:#272727;padding:8px;display:none;z-index:1}#uiLoadingNotice{position:relative;background:url(uiNoticeBackground.jpg) 50% 50%;color:#000;font-size:14px;font-style:italic;font-weight:700;padding:3px 4px;margin:4px 0}
\ No newline at end of file
+@font-face{font-family:FontAwesome;src:url(fontawesome-webfont.eot?v=4.5.0);src:url(fontawesome-webfont.eot?#iefix&v=4.5.0) format("embedded-opentype"),url(fontawesome-webfont.woff2?v=4.5.0) format("woff2"),url(fontawesome-webfont.woff?v=4.5.0) format("woff"),url(fontawesome-webfont.ttf?v=4.5.0) format("truetype"),url(fontawesome-webfont.svg?v=4.5.0#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:a 2s infinite linear;animation:a 2s infinite linear}.fa-pulse{-webkit-animation:a 1s infinite steps(8);animation:a 1s infinite steps(8)}@-webkit-keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0,mirror=1);-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2,mirror=1);-webkit-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-close:before,.fa-remove:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-cog:before,.fa-gear:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-repeat:before,.fa-rotate-right:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-exclamation-triangle:before,.fa-warning:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-cogs:before,.fa-gears:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-floppy-o:before,.fa-save:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-sort:before,.fa-unsorted:before{content:"\f0dc"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-sort-asc:before,.fa-sort-up:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-gavel:before,.fa-legal:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-bolt:before,.fa-flash:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-chain-broken:before,.fa-unlink:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:"\f150"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:"\f151"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:"\f152"}.fa-eur:before,.fa-euro:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-inr:before,.fa-rupee:before{content:"\f156"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:"\f157"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:"\f158"}.fa-krw:before,.fa-won:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-try:before,.fa-turkish-lira:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:"\f19c"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:"\f1c5"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:"\f1c6"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-empire:before,.fa-ge:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-paper-plane:before,.fa-send:before{content:"\f1d8"}.fa-paper-plane-o:before,.fa-send-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-bed:before,.fa-hotel:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-y-combinator:before,.fa-yc:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-television:before,.fa-tv:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}
+.displayBar{position:relative;width:236px;height:16px;border:1px solid #666;float:left;margin:0 5px 0 0;overflow:hidden;background:#000}.displayBarText{position:absolute;top:-2px;left:5px;width:100%;height:100%;color:#fff;font-weight:400}.displayBarFill{width:0;height:100%;background:#40628a;overflow:hidden;float:left}.displayBarFill.alignRight{float:right}.displayBarText.average,.displayBarText.bad,.displayBarText.good,.displayBarText.notgood{color:#fff}.displayBarText.highlight{color:#000}.displayBarFill.good{color:#fff;background:#4f7529}.displayBarFill.notgood{color:#fff;background:#ffb400}.displayBarFill.average{color:#fff;background:#cd6500}.displayBarFill.bad{color:#fff;background:#e00}.displayBarFill.highlight{color:#fff;background:#8ba5c4}.disabled,.link,.linkOff,.linkOn,.redButton,.selected,.yellowButton{float:left;min-width:15px;height:16px;text-align:center;color:#fff;text-decoration:none;background:#40628a;border:1px solid #161616;padding:0 4px 4px;margin:0 2px 2px 0;cursor:default;white-space:nowrap}.hasIcon{padding:0 4px 4px 0}.linkActive.hover,.zoomLink.hover,a.hover{background:#507aac}@keyframes a{to{color:#fff;background:#507aac}}.linkPending,.linkPending.hover{animation-name:a;animation-duration:.25s}a.white,a.white:active,a.white:link,a.white:visited{color:#40628a;text-decoration:none;background:#fff;border:1px solid #161616;padding:1px 4px;margin:0 2px 0 0;cursor:default}a.white.hover{color:#fff;background:#40628a}.linkOn,.selected,a.linkOn.hover,a.linkOn:active,a.linkOn:link,a.linkOn:visited,a.selected.hover,a.selected:active,a.selected:link,a.selected:visited{color:#fff;background:#2f943c}.disabled,.linkOff,a.disabled.hover,a.disabled:active,a.disabled:link,a.disabled:visited,a.linkOff.hover,a.linkOff:active,a.linkOff:link,a.linkOff:visited{color:#fff;background:#999;border-color:#666}.disabled.icon,.linkOff.icon,.linkOn.icon,.selected.icon,a.icon{position:relative;padding:1px 4px 2px 20px}.disabled.icon img,.linkOff.icon img,.linkOn.icon img,.selected.icon img,a.icon img{position:absolute;top:0;left:0;width:18px;height:18px}.linkDanger,a.linkDanger:active,a.linkDanger:link,a.linkDanger:visited{color:#fff;background-color:red;border-color:#a00}.linkDanger.hover{background-color:#f66}.inactive,a.inactive.hover,a.inactive:active,a.inactive:link,a.inactive:visited{color:#fff;background:#999;border-color:#666}.white{color:#fff}.good,.white{font-weight:700}.good{color:#4f7529}.average{color:#cd6500}.average,.bad{font-weight:700}.bad{color:#e00}.idle{color:#272727;font-weight:700}.redButton{background:#ea0000}.yellowButton{background:#cacc00}.highlight{color:#8ba5c4}.dark{color:#272727}.burn{color:orange}.brute{color:red}.toxin{color:green}.toxin_light{color:#3adf00}.oxyloss{color:blue}.oxyloss_light{color:#6698ff}.Red{color:red}.Blue{color:#00f}.Green{color:#0f0}.Marigold{color:#fda505}.Fuschia{color:#ff0080}.Black{color:#000}.Pearl{color:#c6cacb}.cold1{color:#94b8ff}.cold2{color:#69f}.cold3{color:#293d66}.hot1{color:#f96}.hot2{color:#993d00}.hot3{color:#f60}div.display{padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}div.display header{display:block;position:relative;width:98.5%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}div.display header .buttonRight{position:absolute;bottom:6px;right:4px}div.display article{display:table;width:100%;border-collapse:collapse}.itemGroup{border:1px solid #e9c183;background:#2c2c2c;padding:4px;clear:both}.item{width:100%;margin:4px 0 0;clear:both;overflow:auto}.itemContent,.itemContentNarrow{float:left}.itemContentNarrow{width:30%}.itemContent{width:69%}.itemLabel,.itemLabelNarrow,.itemLabelWide,.itemLabelWider,.itemLabelWidest{float:left;color:#e9c183}.itemLabelNarrow{width:20%}.itemLabel{width:30%}.itemLabelWide{width:45%}.itemLabelWider{width:69%}.itemLabelWidest{width:100%}.itemContentWide{float:left;width:79%}.itemContentSmall{float:left;width:33%}.itemContentMedium{float:left;width:55%}.block{padding:8px;margin:10px 4px 4px;border:1px solid #40628a;background-color:#202020}.block h3{padding:0}.clearBoth{clear:both}.clearLeft{clear:left}.clearRight{clear:right}.line{width:100%;clear:both}.fixedLeft{width:110px;float:left}.fixedLeftWide{width:165px;float:left}.fixedLeftWider{width:220px;float:left}.fixedLeftWidest{width:250px;float:left}.floatRight{float:right}.floatLeft{float:left}.hidden{display:none}.statusDisplay{overflow:hidden}.statusDisplay,.statusDisplayRecords{background:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background:rgba(0,0,0,.5);color:#fff;border:1px solid #40628a;padding:4px;margin:3px 0}.statusDisplayRecords{overflow-x:hidden;overflow-y:auto}.statusLabel{width:138px;float:left;overflow:hidden;color:#98b0c3}.statusValue{float:left}.fancy{display:none}.minimize{color:#e9c183;position:absolute;top:6px;right:46px}.minimize.hover{color:#b8c9d6}.close{color:#e9c183;position:absolute;top:4px;right:12px}.close.hover{color:#b8c9d6}div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 30px 30px;border-color:transparent transparent #363636;transform:rotate(1turn)}.uiLinkPendingIcon{display:none;float:left;width:16px;height:16px;margin:2px 2px 0;background-image:url(uiLinkPendingIcon.gif)}.linkPending .fa{display:none}.linkPending .uiLinkPendingIcon{display:block}.mapIcon16{position:absolute;width:16px;height:16px;background-image:url(uiIcons16Green.png);background-position:-144px -96px;background-repeat:no-repeat;zoom:.125;margin-left:-1px}.mapIcon16.bad,.mapIcon16.dead{background-image:url(uiIcons16Red.png)}.mapIcon16.average{background-image:url(uiIcons16Orange.png)}.mapIcon16.good{background-image:url(uiIcons16Green.png)}.mapIcon16.icon-airalarm{background-position:0 -144px}.mapIcon16.rank-captain{background-position:-224px -112px}.mapIcon16.rank-headofpersonnel{background-position:-112px -96px}.mapIcon16.rank-headofsecurity{background-position:-112px -128px}.mapIcon16.rank-chiefengineer{background-position:-176px -112px}.mapIcon16.rank-researchdirector{background-position:-128px -128px}.mapIcon16.rank-chiefmedicalofficer{background-position:-32px -128px}.mapIcon16.rank-atmospherictechnician,.mapIcon16.rank-stationengineer{background-position:-176px -112px}.mapIcon16.rank-chemist,.mapIcon16.rank-geneticist,.mapIcon16.rank-medicaldoctor,.mapIcon16.rank-psychiatrist{background-position:-32px -128px}.mapIcon16.rank-geneticist,.mapIcon16.rank-roboticist,.mapIcon16.rank-scientist,.mapIcon16.rank-xenobiologist{background-position:-128px -128px}.mapIcon16.rank-detective,.mapIcon16.rank-securityofficer,.mapIcon16.rank-warden{background-position:-112px -128px}ul{padding:4px 0 0 10px;margin:0;list-style-type:none}li{padding:0 0 2px}table.fixed{table-layout:fixed}table.fixed td{overflow:hidden}table.pmon{border:2px solid #4169e1}table.pmon td,table.pmon th{border-bottom:1px dotted #000;padding:0 5px}th.command{background:#33f}th.command,th.sec{font-weight:700;color:#fff}th.sec{background:#8e0000}th.med{background:#060}th.eng,th.med{font-weight:700;color:#fff}th.eng{background:#b27300}th.sci{background:#a65ba6}th.sci,th.ser{font-weight:700;color:#fff}th.ser{background:#7100aa}th.sup{background:#666621}th.civ,th.sup{font-weight:700;color:#fff}th.civ{background:#a32800}th.misc{background:#666;font-weight:700;color:#fff}span.qm-job{color:#b77a41;font-weight:700}.striped:not(table)>:nth-child(2n),.striped tr:nth-child(2n){background-color:#404040}#uiNoScript{position:fixed;top:50%;left:50%;margin:-60px 0 0 -150px;width:280px;height:120px;background:#fff;border:2px solid red;color:#000;font-size:10px;font-weight:700;z-index:2;padding:0 10px;text-align:center}.notice{background:url(uiNoticeBackground.jpg) 50% 50%;color:#000}.notice,.noticePlaceholder{position:relative;font-size:12px;font-style:italic;font-weight:700;padding:3px 4px;margin:4px 0}.notice.icon{padding:2px 4px 0 20px}.notice img{position:absolute;top:0;left:0;width:16px;height:16px}div.notice{clear:both}.wholeScreen{position:absolute;color:#517087;font-size:16px;font-weight:700;text-align:center}.pdalink{float:left;white-space:nowrap;cursor:default!important}.pdalink.disabled{background:none;border:none;color:#999;text-align:left}.pdanote{color:#cd6500;font-weight:700}.item.mainmenu{padding-bottom:.5em}div.clock{color:#fff;font-weight:700;float:right;padding-right:2em}#pdaFooter{position:fixed;left:0;bottom:0;width:100%;background:#272727}.pdaFooterButton{width:33%;padding:.5em 0;font-size:200%;border:none;background:none;color:#fff}.pdaFooterButton.hover{background:#507aac}.pdaFooterButton.disabled{background:none!important;color:#555!important}.pdaFooterButton .uiLinkPendingIcon{position:absolute;width:33%;background-repeat:no-repeat;background-position:50%}.dnaBlock{float:left;width:90px;padding:0 0 5px}.dnaBlockNumber{color:#fff;background:#363636;min-width:20px}.dnaBlockNumber,.dnaSubBlock{font-family:Fixed,monospace;float:left;height:20px;padding:0;text-align:center}.dnaSubBlock{min-width:16px}.mask{position:fixed;left:0;top:0;width:100%;height:100%;background:url(uiMaskBackground.png)}.maskContent{width:100%;height:200px;margin:200px 0;text-align:center}body{background:#272727;color:#fff;font-family:Verdana,Geneva,sans-serif;font-size:12px;line-height:170%;margin:0;padding:0}hr{background-color:#40628a;height:1px;border:none}a img,img{border-style:none}h1,h2,h3,h4,h5,h6{margin:0;padding:12px 0 6px;color:#fff;clear:both}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}[data-tooltip]{position:relative}[data-tooltip]:after{position:absolute;display:block;z-index:1;width:250px;padding:10px;transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #999;background-color:#363636}[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}[data-tooltip].tooltipTop:after{bottom:100%;left:50%;transform:translateX(-50%) translateY(8px)}[data-tooltip].tooltipBottom:after,[data-tooltip].tooltipTop:hover:after{transform:translateX(-50%) translateY(-8px)}[data-tooltip].tooltipBottom:after{top:100%;left:50%}[data-tooltip].tooltipBottom:hover:after{transform:translateX(-50%) translateY(8px)}[data-tooltip].tooltipLeft:after{top:50%;right:100%;transform:translateX(8px) translateY(-50%)}[data-tooltip].tooltipLeft:hover:after,[data-tooltip].tooltipRight:after{transform:translateX(-8px) translateY(-50%)}[data-tooltip].tooltipRight:after{top:50%;left:100%}[data-tooltip].tooltipRight:hover:after{transform:translateX(8px) translateY(-50%)}body{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1' viewBox='0 0 425 200' opacity='.25'%3E%3Cpath d='M178.004.039H106.8a6.761 6.026 0 0 0-6.761 6.025v187.872a6.761 6.026 0 0 0 6.761 6.025h53.107a6.761 6.026 0 0 0 6.762-6.025V92.392l72.216 104.7a6.761 6.026 0 0 0 5.76 2.87H318.2a6.761 6.026 0 0 0 6.761-6.026V6.064A6.761 6.026 0 0 0 318.2.04h-54.717a6.761 6.026 0 0 0-6.76 6.025v102.62L183.763 2.909a6.761 6.026 0 0 0-5.76-2.87zM4.845 22.109A13.412 12.502 0 0 1 13.478.039h66.118A5.365 5 0 0 1 84.96 5.04v79.88zM420.155 177.891a13.412 12.502 0 0 1-8.633 22.07h-66.118a5.365 5 0 0 1-5.365-5.001v-79.88z'/%3E%3C/svg%3E") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020) no-repeat fixed 50%/100% 100%;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}#uiWrapper{width:100%;height:100%;-ms-user-select:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}#uiTitleWrapper{position:relative;height:30px}#uiTitleText{position:absolute;top:6px;left:44px;width:66%;overflow:hidden;color:#e9c183;font-size:16px}#uiTitle.icon{padding:6px 8px 6px 42px;background-position:2px 50%;background-repeat:no-repeat}#uiTitleFluff{position:absolute;top:4px;right:12px;width:42px;height:24px;background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1' viewBox='0 0 425 200' opacity='.25'%3E%3Cpath d='M178.004.039H106.8a6.761 6.026 0 0 0-6.761 6.025v187.872a6.761 6.026 0 0 0 6.761 6.025h53.107a6.761 6.026 0 0 0 6.762-6.025V92.392l72.216 104.7a6.761 6.026 0 0 0 5.76 2.87H318.2a6.761 6.026 0 0 0 6.761-6.026V6.064A6.761 6.026 0 0 0 318.2.04h-54.717a6.761 6.026 0 0 0-6.76 6.025v102.62L183.763 2.909a6.761 6.026 0 0 0-5.76-2.87zM4.845 22.109A13.412 12.502 0 0 1 13.478.039h66.118A5.365 5 0 0 1 84.96 5.04v79.88zM420.155 177.891a13.412 12.502 0 0 1-8.633 22.07h-66.118a5.365 5 0 0 1-5.365-5.001v-79.88z'/%3E%3C/svg%3E") 50% 50% no-repeat}.statusicon{position:absolute;top:4px;left:12px}#uiMapWrapper{clear:both;padding:8px}#uiMapHeader{position:relative;clear:both}#uiMapContainer{position:relative;width:100%;height:600px;overflow:hidden;border:1px solid #40628a;background:url(nanomapBackground.png)}#uiMap{top:50%;left:50%;margin:-512px 0 0 -512px;overflow:hidden;zoom:4}#uiMap,#uiMapImage{position:absolute;width:256px;height:256px}#uiMapImage{bottom:1px;left:1px}#uiMapContent{position:absolute;bottom:-13.5px;left:0;width:256px;height:256px}#uiMapFooter{position:relative;clear:both}#uiContent{clear:both;padding:8px}#uiMapTooltip{position:absolute;right:10px;top:10px;border:1px solid #40628a;background-color:#272727;padding:8px;display:none;z-index:2}#uiLoadingNotice{position:relative;background:url(uiNoticeBackground.jpg) 50% 50%;color:#000;font-size:14px;font-style:italic;font-weight:700;padding:3px 4px;margin:4px 0}
\ No newline at end of file
diff --git a/nano/layouts/layout_program.tmpl b/nano/layouts/layout_program.tmpl
new file mode 100644
index 00000000000..66d1605c7c0
--- /dev/null
+++ b/nano/layouts/layout_program.tmpl
@@ -0,0 +1,75 @@
+
+
+{{if data.ticks_left_locked_down > 0}}
+ Maximum number of pin attempts exceeded! Access to this ATM has been temporarily disabled.
+{{else data.authenticated_account}}
+ {{if data.view_screen == 1}}
+
Either the account number or card is required to access this account. EFTPOS transactions will require a card and ask for a pin, but not verify the pin is correct.
+ {{/if}}
+{{else data.linked_db}}
+
+{{else}}
+ Unable to connect to accounts database, please retry and if the issue persists contact Nanotrasen IT support.
+{{/if}}
\ No newline at end of file
diff --git a/nano/templates/atmos_filter.tmpl b/nano/templates/atmos_filter.tmpl
new file mode 100644
index 00000000000..e0715e243c5
--- /dev/null
+++ b/nano/templates/atmos_filter.tmpl
@@ -0,0 +1,24 @@
+
\ No newline at end of file
diff --git a/nano/templates/atmos_pump.tmpl b/nano/templates/atmos_pump.tmpl
new file mode 100644
index 00000000000..a27e5b710dd
--- /dev/null
+++ b/nano/templates/atmos_pump.tmpl
@@ -0,0 +1,24 @@
+
\ No newline at end of file
diff --git a/nano/templates/card_prog.tmpl b/nano/templates/card_prog.tmpl
new file mode 100644
index 00000000000..56c913a9de9
--- /dev/null
+++ b/nano/templates/card_prog.tmpl
@@ -0,0 +1,277 @@
+{{if data.printing}}
+
+
+
+ Battery allows your device to operate without external utility power source. Advanced batteries increase battery life.
+ Hard Drive stores file on your device. Advanced drives can store more files, but use more power, shortening battery life.
+ Network Card allows your device to wirelessly connect to stationwide NTNet network. Basic cards are limited to on-station use, while advanced cards can operate anywhere near the station, which includes the asteroid outposts.
+ Processor Unit is critical for your device's functionality. It allows you to run programs from your hard drive. Advanced CPUs use more power, but allow you to run more programs on background at once.
+ Tesla Relay is an advanced wireless power relay that allows your device to connect to nearby area power controller to provide alternative power source. This component is currently unavailable on tablet computers due to size restrictions.
+ Nano Printer is device that allows for various paperwork manipulations, such as, scanning of documents or printing new ones. This device was certified EcoFriendlyPlus and is capable of recycling existing paper for printing purposes.
+ Card Reader adds a slot that allows you to manipulate RFID cards. Please note that this is not necessary to allow the device to read your identification, it is just necessary to manipulate other cards.
+
+{{else data.state == 2}}
+
Step 3: Payment
+ Your device is now ready for fabrication..
+ Please swipe your identification card to finish purchase.
+ Total price: {{:data.totalprice}}C
+{{else data.state == 3}}
+
Step 4: Thank you for your purchase
+ Should you experience any issues with your new device, contact technical support at support@computerservice.nt
+{{/if}}
\ No newline at end of file
diff --git a/nano/templates/computer_main.tmpl b/nano/templates/computer_main.tmpl
new file mode 100644
index 00000000000..9aad3d58609
--- /dev/null
+++ b/nano/templates/computer_main.tmpl
@@ -0,0 +1,9 @@
+No program loaded. Please select program from list below.
+
\ No newline at end of file
diff --git a/nano/templates/eftpos.tmpl b/nano/templates/eftpos.tmpl
new file mode 100644
index 00000000000..663f665d7f9
--- /dev/null
+++ b/nano/templates/eftpos.tmpl
@@ -0,0 +1,55 @@
+
+
+
{{:data.eftpos_name}}
+This terminal is {{:data.machine_id}}. Report this code when contacting Nanotrasen IT Support
+{{if data.transaction_locked == 1}}
+
+
+ {{if data.transaction_paid}}
+ This transaction has been processed successfully.
+ {{else}}
+ Swipe your card below the line to finish this transaction.
+
{{:helper.link('Scan card to reset acess code', 'refresh', {'choice' : 'reset'})}}
+
+{{/if}}
\ No newline at end of file
diff --git a/nano/templates/file_manager.tmpl b/nano/templates/file_manager.tmpl
new file mode 100644
index 00000000000..1bdb0cd95c4
--- /dev/null
+++ b/nano/templates/file_manager.tmpl
@@ -0,0 +1,71 @@
+{{if data.error}}
+
An error has occurred and this program can not continue.
+ Additional information: {{:data.error}}
+ Please try again. If the problem persists contact your system administrator for assistance.
+ {{:helper.link('Restart program', null, {'action' : 'PRG_closefile'})}}
+{{else}}
+ {{if data.filename}}
+
+ {{/if}}
+ {{:helper.link('NEW DATA FILE', 'file-text', {'action' : 'PRG_newtextfile'})}}
+ {{/if}}
+{{/if}}
\ No newline at end of file
diff --git a/nano/templates/laptop_configuration.tmpl b/nano/templates/laptop_configuration.tmpl
new file mode 100644
index 00000000000..95dd315b90e
--- /dev/null
+++ b/nano/templates/laptop_configuration.tmpl
@@ -0,0 +1,71 @@
+Welcome to computer configuration utility. Please consult your system administrator if you have any questions about your device.
+
\ No newline at end of file
diff --git a/nano/templates/med_data.tmpl b/nano/templates/med_data.tmpl
new file mode 100644
index 00000000000..f47e13c6885
--- /dev/null
+++ b/nano/templates/med_data.tmpl
@@ -0,0 +1,171 @@
+
+
+
+
+
+ {{else data.screen == 4}}
+ Network currently serves a total of {{:data.total_num}} feed channels, {{:data.active_num}} of which are active, and a total of {{:data.message_num}} feed stories.
+
+ ATTENTION: This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.
+ No further feed story additions are allowed while the D-Notice is in effect.
+
+ {{else data.screen == 6}}
+ Nanotrasen Feed Censorship Tool
+ NOTE: Due to the nature of news Feeds, total deletion of a Feed Story is not possible.
+ Keep in mind that users attempting to view a censored feed will instead see the [REDACTED] tag above it.
+
+ Select feed channel to get stories from:
+
+ {{else data.screen == 7}}
+ Nanotrasen D-Notice Handler
+ A D-Notice is to be bestowed upon the channel if the handling Authority deems it as harmful for the station<>s morale, integrity or disciplinary behaviour.
+ A D-Notice will render a channel unable to be updated by anyone, without deleting any feedstories it might contain at the time.
+ You can lift a D-Notice if you have the required access at any time.
+
+
+ {{else data.screen == 9}}
+ {{:data.channel_name}}[created by: {{:data.author}}]
+ Channel messages listed below. If you deem them dangerous to the station, you can
{{:helper.link('Bestow a D-Notice upon the channel', null, {'toggle_d_notice' : data.ref})}}
+ {{if data.censored}}
+
+ ATTENTION: This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.
+ No further feed story additions are allowed while the D-Notice is in effect.
+
+ {{else data.screen == 10}}
+ Wanted Issue handler:
+ {{if data.wanted_already}}
+ A wanted issue is already in Feed Circulation. You can edit or cancel it below.
+ {{/if}}
+
+{{/if}}
\ No newline at end of file
diff --git a/nano/templates/ntnet_downloader.tmpl b/nano/templates/ntnet_downloader.tmpl
new file mode 100644
index 00000000000..a64ae3452b2
--- /dev/null
+++ b/nano/templates/ntnet_downloader.tmpl
@@ -0,0 +1,102 @@
+Welcome to software download utility. Please select which software you wish to download.
+{{if data.error}}
+
\ No newline at end of file
diff --git a/nano/templates/ntnet_relay.tmpl b/nano/templates/ntnet_relay.tmpl
new file mode 100644
index 00000000000..8625f94dd14
--- /dev/null
+++ b/nano/templates/ntnet_relay.tmpl
@@ -0,0 +1,19 @@
+
Relay
+{{if data.dos_crashed}}
+
NETWORK BUFFERS OVERLOADED
+
Overload Recovery Mode
+ This system is suffering temporary outage due to overflow of traffic buffers. Until buffered traffic is processed, all further requests will be dropped. Frequent occurences of this error may indicate insufficient hardware capacity of your network. Please contact your network planning department for instructions on how to resolve this issue.
+
ADMINISTRATIVE OVERRIDE
+ CAUTION - Data loss may occur
+ {{:helper.link('Purge buffered traffic', 'signal', {'action' : 'restart'})}}
+{{else}}
+
+{{/if}}
\ No newline at end of file
diff --git a/nano/templates/ntnet_transfer.tmpl b/nano/templates/ntnet_transfer.tmpl
new file mode 100644
index 00000000000..660838b94dc
--- /dev/null
+++ b/nano/templates/ntnet_transfer.tmpl
@@ -0,0 +1,77 @@
+{{if data.error}}
+
+{{/if}}
\ No newline at end of file
diff --git a/nano/templates/shuttle_console.tmpl b/nano/templates/shuttle_console.tmpl
new file mode 100644
index 00000000000..d16f39a8b20
--- /dev/null
+++ b/nano/templates/shuttle_console.tmpl
@@ -0,0 +1,37 @@
+
+
+
+{{/if}}
\ No newline at end of file
diff --git a/nano/templates/tank_dispenser.tmpl b/nano/templates/tank_dispenser.tmpl
new file mode 100644
index 00000000000..a634a2dde8e
--- /dev/null
+++ b/nano/templates/tank_dispenser.tmpl
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/nano/templates/wires.tmpl b/nano/templates/wires.tmpl
new file mode 100644
index 00000000000..a661fa3e851
--- /dev/null
+++ b/nano/templates/wires.tmpl
@@ -0,0 +1,24 @@
+