diff --git a/_maps/map_files/Delta/delta.dmm b/_maps/map_files/Delta/delta.dmm index 892a6d08422..0947c97f5d1 100644 --- a/_maps/map_files/Delta/delta.dmm +++ b/_maps/map_files/Delta/delta.dmm @@ -622,7 +622,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 4 }, -/turf/simulated/floor/plasteel, +/turf/simulated/floor/plating, /area/maintenance/auxsolarstarboard) "afm" = ( /obj/structure/cable{ @@ -650,7 +650,7 @@ pixel_y = 32 }, /obj/effect/decal/warning_stripes/yellow, -/turf/simulated/floor/plasteel, +/turf/simulated/floor/plating, /area/maintenance/auxsolarstarboard) "afn" = ( /obj/structure/cable{ @@ -664,7 +664,7 @@ name = "Engineering External Access"; req_access_txt = "10;13" }, -/turf/simulated/floor/plasteel, +/turf/simulated/floor/plating, /area/maintenance/auxsolarstarboard) "afw" = ( /obj/docking_port/stationary{ @@ -728,11 +728,12 @@ /area/maintenance/auxsolarstarboard) "afC" = ( /obj/structure/cable, +/obj/effect/decal/warning_stripes/southeast, /obj/machinery/power/solar_control{ + dir = 8; id = "auxsolareast"; name = "Fore Starboard Solar Control" }, -/obj/effect/decal/warning_stripes/southeast, /turf/simulated/floor/plating, /area/maintenance/auxsolarstarboard) "afJ" = ( @@ -1403,9 +1404,6 @@ }, /area/security/podbay) "aib" = ( -/obj/machinery/computer/security{ - network = list("SS13","Research Outpost","Mining Outpost") - }, /obj/machinery/firealarm{ dir = 4; pixel_x = 28 @@ -1413,6 +1411,10 @@ /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 1 }, +/obj/machinery/computer/security{ + dir = 8; + network = list("SS13","Research Outpost","Mining Outpost") + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -2080,10 +2082,12 @@ /turf/simulated/wall, /area/engine/mechanic_workshop) "akC" = ( -/obj/machinery/computer/podtracker, /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 1 }, +/obj/machinery/computer/podtracker{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -2255,7 +2259,9 @@ name = "south bump"; pixel_y = -24 }, -/obj/machinery/computer/rdconsole/mechanics, +/obj/machinery/computer/rdconsole/mechanics{ + dir = 1 + }, /turf/simulated/floor/engine, /area/engine/mechanic_workshop/hanger) "alk" = ( @@ -3135,7 +3141,7 @@ /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 + pixel_y = 25 }, /turf/simulated/floor/plasteel{ icon_state = "red" @@ -3154,7 +3160,7 @@ /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 + pixel_y = 25 }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel{ @@ -4173,7 +4179,9 @@ /obj/machinery/ai_status_display{ pixel_x = -32 }, -/obj/machinery/computer/crew, +/obj/machinery/computer/crew{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 10; icon_state = "blue" @@ -4272,7 +4280,9 @@ /obj/machinery/status_display{ pixel_x = 32 }, -/obj/machinery/computer/prisoner, +/obj/machinery/computer/prisoner{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 6; icon_state = "red" @@ -4290,7 +4300,9 @@ /area/maintenance/fore2) "arf" = ( /obj/effect/decal/cleanable/cobweb, -/obj/machinery/computer/arcade, +/obj/machinery/computer/arcade{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/fore2) "arg" = ( @@ -4533,7 +4545,9 @@ /obj/item/radio/intercom{ pixel_x = -28 }, -/obj/machinery/computer/card, +/obj/machinery/computer/card{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "bluefull" }, @@ -4692,7 +4706,9 @@ dir = 1; pixel_x = 28 }, -/obj/machinery/computer/security, +/obj/machinery/computer/security{ + dir = 8 + }, /turf/simulated/floor/plasteel{ icon_state = "redfull" }, @@ -4724,8 +4740,8 @@ }, /area/maintenance/fore2) "arX" = ( -/obj/machinery/computer/arcade, /obj/effect/decal/cleanable/dirt, +/obj/machinery/computer/arcade, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "dark" @@ -4896,7 +4912,9 @@ /obj/machinery/status_display{ pixel_x = -32 }, -/obj/machinery/computer/med_data, +/obj/machinery/computer/med_data{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 9; icon_state = "blue" @@ -4991,7 +5009,9 @@ /obj/machinery/ai_status_display{ pixel_x = 32 }, -/obj/machinery/computer/secure_data, +/obj/machinery/computer/secure_data{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "red" @@ -6239,7 +6259,9 @@ /turf/simulated/floor/plating, /area/maintenance/fore2) "avn" = ( -/obj/machinery/computer/arcade, +/obj/machinery/computer/arcade{ + dir = 1 + }, /turf/simulated/floor/plating, /area/maintenance/fore2) "avo" = ( @@ -8019,7 +8041,7 @@ /turf/simulated/floor/plating, /area/engine/controlroom) "ayV" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 2; d2 = 4; icon_state = "2-4" @@ -8174,8 +8196,7 @@ }, /obj/structure/sink{ dir = 8; - pixel_x = -12; - pixel_y = 2 + pixel_x = -12 }, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/warning_stripes/yellow/hollow, @@ -8449,7 +8470,7 @@ /turf/simulated/floor/plating, /area/maintenance/disposal) "azT" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 4; d2 = 8; icon_state = "4-8" @@ -8470,7 +8491,7 @@ }, /area/engine/controlroom) "azV" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 2; d2 = 8; icon_state = "2-8" @@ -8494,7 +8515,7 @@ dir = 4 }, /obj/machinery/power/rad_collector, -/obj/structure/cable{ +/obj/structure/cable/yellow{ d2 = 8; icon_state = "0-8" }, @@ -8523,14 +8544,14 @@ dir = 8 }, /obj/machinery/power/rad_collector, -/obj/structure/cable{ +/obj/structure/cable/yellow{ d2 = 4; icon_state = "0-4" }, /turf/simulated/floor/engine, /area/engine/supermatter) "aAd" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 4; d2 = 8; icon_state = "4-8" @@ -9007,7 +9028,7 @@ /turf/simulated/floor/plating, /area/maintenance/fore) "aBf" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 4; d2 = 8; icon_state = "4-8" @@ -9038,7 +9059,7 @@ dir = 4 }, /obj/machinery/power/rad_collector, -/obj/structure/cable{ +/obj/structure/cable/yellow{ d2 = 8; icon_state = "0-8" }, @@ -9066,7 +9087,7 @@ dir = 8 }, /obj/machinery/power/rad_collector, -/obj/structure/cable{ +/obj/structure/cable/yellow{ d2 = 4; icon_state = "0-4" }, @@ -9180,8 +9201,7 @@ }, /obj/structure/sink{ dir = 8; - pixel_x = -12; - pixel_y = 2 + pixel_x = -12 }, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/warning_stripes/yellow/hollow, @@ -9210,10 +9230,12 @@ }, /obj/structure/sink{ dir = 8; - pixel_x = -12; - pixel_y = 2 + pixel_x = -12 }, /obj/effect/decal/warning_stripes/yellow/hollow, +/obj/structure/reagent_dispensers/spacecleanertank{ + pixel_x = -32 + }, /turf/simulated/floor/plasteel, /area/janitor) "aBx" = ( @@ -9504,7 +9526,7 @@ dir = 4 }, /obj/machinery/power/rad_collector, -/obj/structure/cable{ +/obj/structure/cable/yellow{ d2 = 8; icon_state = "0-8" }, @@ -9516,7 +9538,7 @@ dir = 8 }, /obj/machinery/power/rad_collector, -/obj/structure/cable{ +/obj/structure/cable/yellow{ d2 = 4; icon_state = "0-4" }, @@ -9793,12 +9815,12 @@ }, /area/maintenance/fore) "aCS" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 2; d2 = 4; icon_state = "2-4" }, -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 1; d2 = 2; icon_state = "1-2" @@ -9814,12 +9836,12 @@ /turf/simulated/floor/plating, /area/maintenance/fore) "aCU" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 2; d2 = 8; icon_state = "2-8" }, -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 1; d2 = 2; icon_state = "1-2" @@ -9910,7 +9932,7 @@ /turf/simulated/floor/plating, /area/engine/controlroom) "aDh" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 1; d2 = 2; icon_state = "1-2" @@ -10273,16 +10295,16 @@ /turf/simulated/floor/plasteel, /area/quartermaster/sorting) "aDT" = ( +/mob/living/simple_animal/bot/mulebot{ + home_destination = "QM #2"; + suffix = "#2" + }, /obj/machinery/navbeacon{ codes_txt = "delivery;dir=4"; dir = 4; location = "QM #2" }, /obj/effect/decal/warning_stripes/yellow, -/mob/living/simple_animal/bot/mulebot{ - home_destination = "QM #2"; - suffix = "#2" - }, /turf/simulated/floor/plasteel, /area/quartermaster/storage) "aDW" = ( @@ -10350,7 +10372,7 @@ }, /area/engine/controlroom) "aEe" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 1; d2 = 2; icon_state = "1-2" @@ -10385,6 +10407,10 @@ pixel_x = -24; shock_proof = 1 }, +/obj/structure/cable/yellow{ + d2 = 4; + icon_state = "0-4" + }, /turf/simulated/floor/engine, /area/engine/supermatter) "aEi" = ( @@ -10404,7 +10430,7 @@ /turf/simulated/floor/plasteel, /area/engine/controlroom) "aEk" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 4; d2 = 8; icon_state = "4-8" @@ -10431,7 +10457,7 @@ }, /area/engine/controlroom) "aEn" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 1; d2 = 4; icon_state = "1-4" @@ -10468,7 +10494,7 @@ /turf/simulated/floor/plasteel, /area/hydroponics/abandoned_garden) "aEs" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 4; d2 = 8; icon_state = "4-8" @@ -10835,28 +10861,28 @@ /turf/simulated/floor/plasteel, /area/engine/controlroom) "aFe" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/simple/visible{ dir = 4 }, /obj/effect/decal/warning_stripes/north, -/turf/simulated/floor/plasteel, -/area/engine/controlroom) -"aFf" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 4; d2 = 8; icon_state = "4-8" }, +/turf/simulated/floor/plasteel, +/area/engine/controlroom) +"aFf" = ( /obj/machinery/atmospherics/trinary/filter{ dir = 8; filter_type = "n2" }, /obj/effect/decal/warning_stripes/north, +/obj/structure/cable/yellow{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/plasteel, /area/engine/controlroom) "aFg" = ( @@ -10868,13 +10894,13 @@ /turf/simulated/wall/r_wall, /area/engine/supermatter) "aFi" = ( -/obj/structure/cable{ +/obj/machinery/atmospherics/pipe/manifold/visible, +/obj/effect/decal/warning_stripes/north, +/obj/structure/cable/yellow{ d1 = 4; d2 = 8; icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/visible, -/obj/effect/decal/warning_stripes/north, /turf/simulated/floor/plasteel, /area/engine/controlroom) "aFj" = ( @@ -10899,7 +10925,7 @@ /turf/simulated/floor/plasteel, /area/engine/controlroom) "aFl" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 1; d2 = 2; icon_state = "1-2" @@ -11183,7 +11209,7 @@ /turf/simulated/wall, /area/quartermaster/storage) "aFV" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 1; d2 = 2; icon_state = "1-2" @@ -11200,25 +11226,25 @@ }, /area/engine/controlroom) "aFX" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/machinery/atmospherics/binary/pump{ dir = 8; name = "Gas to Filter"; on = 1 }, /obj/effect/decal/warning_stripes/north, -/turf/simulated/floor/plasteel, -/area/engine/controlroom) -"aFY" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 4; d2 = 8; icon_state = "4-8" }, +/obj/structure/cable/yellow{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/turf/simulated/floor/plasteel, +/area/engine/controlroom) +"aFY" = ( /obj/machinery/atmospherics/pipe/manifold/visible, /obj/machinery/camera{ c_tag = "Supermatter South"; @@ -11229,47 +11255,52 @@ icon_state = "0-4" }, /obj/effect/decal/warning_stripes/north, -/turf/simulated/floor/plasteel, -/area/engine/supermatter) -"aFZ" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 4; d2 = 8; icon_state = "4-8" }, +/turf/simulated/floor/plasteel, +/area/engine/supermatter) +"aFZ" = ( /obj/machinery/atmospherics/pipe/simple/visible{ dir = 4 }, /obj/effect/decal/warning_stripes/north, -/turf/simulated/floor/plasteel, -/area/engine/supermatter) -"aGa" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 4; d2 = 8; icon_state = "4-8" }, +/turf/simulated/floor/plasteel, +/area/engine/supermatter) +"aGa" = ( /obj/machinery/atmospherics/pipe/manifold/visible, /obj/machinery/meter, /obj/effect/decal/warning_stripes/north, +/obj/structure/cable/yellow{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/plasteel, /area/engine/controlroom) "aGb" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, -/obj/structure/cable{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, /obj/machinery/atmospherics/pipe/simple/visible{ dir = 4 }, /obj/effect/decal/warning_stripes/northwestcorner, /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/cable/yellow{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, /turf/simulated/floor/plasteel, /area/engine/controlroom) "aGc" = ( @@ -11303,8 +11334,7 @@ "aGe" = ( /obj/structure/sink{ dir = 8; - pixel_x = -12; - pixel_y = 2 + pixel_x = -12 }, /obj/structure/sign/nosmoking_2{ pixel_x = -32 @@ -11491,7 +11521,7 @@ /area/crew_quarters/bar) "aGx" = ( /obj/structure/sink/kitchen{ - pixel_y = 28 + pixel_y = 25 }, /obj/machinery/camera{ c_tag = "Bar Backroom" @@ -11766,7 +11796,7 @@ "aHb" = ( /obj/structure/sink{ dir = 4; - pixel_x = 9 + pixel_x = 12 }, /obj/structure/sign/botany{ pixel_x = 32 @@ -11775,7 +11805,7 @@ /turf/simulated/floor/plasteel, /area/hydroponics/abandoned_garden) "aHc" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 1; d2 = 2; icon_state = "1-2" @@ -11853,7 +11883,7 @@ d2 = 8; icon_state = "4-8" }, -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 1; d2 = 2; icon_state = "1-2" @@ -12578,11 +12608,6 @@ /turf/simulated/floor/plasteel, /area/engine/controlroom) "aIH" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/structure/cable{ d1 = 2; d2 = 4; @@ -12590,6 +12615,11 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/cable{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, /turf/simulated/floor/plasteel, /area/engine/controlroom) "aII" = ( @@ -12626,7 +12656,7 @@ /turf/simulated/floor/plasteel, /area/engine/controlroom) "aIL" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 1; d2 = 2; icon_state = "1-2" @@ -12874,7 +12904,9 @@ }, /area/quartermaster/storage) "aJk" = ( -/obj/machinery/computer/arcade/orion_trail, +/obj/machinery/computer/arcade/orion_trail{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "yellow" @@ -12928,11 +12960,6 @@ }, /area/quartermaster/storage) "aJs" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/manifold/visible, /obj/effect/decal/warning_stripes/north, /obj/machinery/door_control{ @@ -12941,6 +12968,11 @@ pixel_y = 24; req_access_txt = "10" }, +/obj/structure/cable/yellow{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/plasteel, /area/engine/controlroom) "aJt" = ( @@ -13078,7 +13110,7 @@ d2 = 8; icon_state = "4-8" }, -/turf/simulated/floor/plasteel, +/turf/simulated/floor/plating, /area/maintenance/auxsolarport) "aJL" = ( /obj/machinery/atmospherics/unary/vent_pump/high_volume{ @@ -13105,7 +13137,7 @@ d2 = 8; icon_state = "4-8" }, -/turf/simulated/floor/plasteel, +/turf/simulated/floor/plating, /area/maintenance/auxsolarport) "aJM" = ( /obj/structure/cable{ @@ -13431,7 +13463,7 @@ d2 = 8; icon_state = "4-8" }, -/turf/simulated/floor/plasteel, +/turf/simulated/floor/plating, /area/maintenance/auxsolarport) "aKp" = ( /obj/structure/table/wood, @@ -13621,8 +13653,8 @@ /obj/machinery/status_display{ pixel_y = 32 }, -/obj/machinery/computer/library/public, /obj/structure/table, +/obj/machinery/computer/library/public, /turf/simulated/floor/plasteel, /area/security/permabrig) "aKS" = ( @@ -13670,7 +13702,7 @@ /turf/simulated/wall, /area/security/execution) "aKX" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d1 = 1; d2 = 2; icon_state = "1-2" @@ -13684,11 +13716,12 @@ /area/engine/controlroom) "aKY" = ( /obj/structure/cable, +/obj/effect/decal/warning_stripes/southwest, /obj/machinery/power/solar_control{ + dir = 4; id = "portsolar"; name = "Aft Port Solar Control" }, -/obj/effect/decal/warning_stripes/southwest, /turf/simulated/floor/plating, /area/maintenance/auxsolarport) "aKZ" = ( @@ -13790,11 +13823,6 @@ }, /area/maintenance/incinerator) "aLj" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/structure/cable{ d1 = 1; d2 = 8; @@ -13921,14 +13949,14 @@ /turf/simulated/floor/plasteel, /area/engine/controlroom) "aLw" = ( -/obj/structure/cable, -/obj/structure/cable{ +/obj/machinery/power/terminal, +/obj/effect/decal/warning_stripes/south, +/obj/structure/cable/yellow, +/obj/structure/cable/yellow{ d1 = 1; d2 = 4; icon_state = "1-4" }, -/obj/machinery/power/terminal, -/obj/effect/decal/warning_stripes/south, /turf/simulated/floor/plasteel, /area/engine/controlroom) "aLx" = ( @@ -14118,16 +14146,16 @@ /turf/simulated/wall, /area/crew_quarters/bar/atrium) "aLV" = ( +/mob/living/simple_animal/bot/mulebot{ + home_destination = "QM #4"; + suffix = "#4" + }, /obj/machinery/navbeacon{ codes_txt = "delivery;dir=4"; dir = 4; location = "QM #4" }, /obj/effect/decal/warning_stripes/yellow, -/mob/living/simple_animal/bot/mulebot{ - home_destination = "QM #4"; - suffix = "#4" - }, /turf/simulated/floor/plasteel, /area/quartermaster/storage) "aLW" = ( @@ -14284,11 +14312,11 @@ }, /area/crew_quarters/bar) "aMj" = ( +/mob/living/carbon/human/monkey/punpun, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 8 }, -/mob/living/carbon/human/monkey/punpun, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "dark" @@ -14358,7 +14386,7 @@ }, /area/medical/medbay) "aMx" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ d2 = 8; icon_state = "0-8" }, @@ -14507,12 +14535,13 @@ d2 = 4; icon_state = "1-4" }, -/obj/machinery/computer/monitor{ - name = "Engineering Power Monitoring Console" - }, /obj/machinery/status_display{ pixel_y = -32 }, +/obj/machinery/computer/monitor{ + dir = 1; + name = "Engineering Power Monitoring Console" + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "dark" @@ -14530,7 +14559,10 @@ }, /obj/machinery/light/small, /obj/machinery/power/smes, -/turf/simulated/floor/greengrid, +/turf/simulated/floor/plasteel{ + dir = 1; + icon_state = "dark" + }, /area/engine/controlroom) "aMU" = ( /obj/structure/cable{ @@ -15087,7 +15119,9 @@ pixel_x = 24 }, /obj/effect/decal/warning_stripes/yellow/hollow, -/obj/machinery/computer/sm_monitor, +/obj/machinery/computer/sm_monitor{ + dir = 8 + }, /turf/simulated/floor/plasteel, /area/engine/controlroom) "aOa" = ( @@ -15469,8 +15503,8 @@ /turf/simulated/floor/plasteel, /area/security/permabrig) "aPb" = ( -/obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/mouse, +/obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plasteel, @@ -16102,6 +16136,9 @@ /obj/structure/chair/comfy/lime{ dir = 4 }, +/obj/machinery/computer/med_data/laptop{ + dir = 1 + }, /turf/simulated/floor/carpet, /area/medical/psych) "aQp" = ( @@ -16301,6 +16338,7 @@ pixel_y = -24 }, /obj/machinery/computer/turbine_computer{ + dir = 1; id = "incineratorturbine" }, /turf/simulated/floor/plasteel{ @@ -17021,7 +17059,9 @@ /turf/simulated/floor/plating, /area/security/permabrig) "aSs" = ( -/obj/machinery/computer/arcade, +/obj/machinery/computer/arcade{ + dir = 1 + }, /turf/simulated/floor/plating, /area/security/permabrig) "aSt" = ( @@ -18496,7 +18536,9 @@ }, /area/quartermaster/storage) "aVa" = ( -/obj/machinery/computer/supplycomp, +/obj/machinery/computer/supplycomp{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "neutralfull" @@ -18551,7 +18593,9 @@ }, /area/quartermaster/qm) "aVj" = ( -/obj/machinery/computer/supplycomp, +/obj/machinery/computer/supplycomp{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "brown" @@ -19208,8 +19252,8 @@ }, /area/quartermaster/office) "aWu" = ( -/obj/effect/decal/warning_stripes/south, /mob/living/simple_animal/pet/sloth/paperwork, +/obj/effect/decal/warning_stripes/south, /turf/simulated/floor/plasteel, /area/quartermaster/storage) "aWv" = ( @@ -20191,7 +20235,9 @@ }, /area/quartermaster/qm) "aYj" = ( -/obj/machinery/computer/security/mining, +/obj/machinery/computer/security/mining{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "brown" @@ -20308,6 +20354,7 @@ }, /obj/machinery/atmospherics/pipe/simple/visible/green, /obj/machinery/computer/general_air_control/large_tank_control{ + dir = 4; frequency = 1441; input_tag = "co2_in"; name = "Carbon Dioxide Supply Control"; @@ -21594,7 +21641,7 @@ /area/security/permabrig) "baQ" = ( /obj/structure/sink/kitchen{ - pixel_y = 30 + pixel_y = 25 }, /obj/effect/decal/warning_stripes/southwest, /turf/simulated/floor/plasteel, @@ -21703,7 +21750,9 @@ }, /area/quartermaster/office) "bbb" = ( -/obj/machinery/computer/supplycomp, +/obj/machinery/computer/supplycomp{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "brown" }, @@ -22227,6 +22276,7 @@ }, /obj/machinery/atmospherics/pipe/simple/visible/green, /obj/machinery/computer/general_air_control/large_tank_control{ + dir = 8; frequency = 1441; input_tag = "o2_in"; name = "Oxygen Supply Control"; @@ -22404,7 +22454,7 @@ c_tag = "Kitchen Backroom" }, /obj/structure/sink/kitchen{ - pixel_y = 30 + pixel_y = 25 }, /obj/effect/decal/warning_stripes/southeast, /turf/simulated/floor/plasteel, @@ -22450,6 +22500,7 @@ dir = 10 }, /obj/machinery/computer/general_air_control/large_tank_control{ + dir = 8; frequency = 1443; input_tag = "air_in"; name = "Mixed Air Supply Control"; @@ -22586,8 +22637,8 @@ /obj/machinery/light{ dir = 1 }, -/obj/machinery/computer/supplycomp/public, /obj/effect/decal/warning_stripes/yellow/hollow, +/obj/machinery/computer/supplycomp/public, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "brown" @@ -23480,6 +23531,7 @@ }, /obj/machinery/atmospherics/pipe/simple/visible/green, /obj/machinery/computer/general_air_control/large_tank_control{ + dir = 4; frequency = 1441; input_tag = "tox_in"; name = "Toxin Supply Control"; @@ -23492,7 +23544,9 @@ }, /area/atmos) "beI" = ( -/obj/machinery/computer/secure_data, +/obj/machinery/computer/secure_data{ + dir = 8 + }, /turf/simulated/floor/plasteel{ icon_state = "grimy" }, @@ -24550,7 +24604,7 @@ /area/security/medbay) "bhc" = ( /obj/structure/sink{ - pixel_y = 26 + pixel_y = 25 }, /obj/machinery/atmospherics/unary/vent_scrubber/on, /obj/structure/disposalpipe/segment{ @@ -24695,6 +24749,7 @@ }, /obj/machinery/atmospherics/pipe/simple/visible/green, /obj/machinery/computer/general_air_control/large_tank_control{ + dir = 8; frequency = 1441; input_tag = "n2_in"; name = "Nitrogen Supply Control"; @@ -24855,7 +24910,7 @@ /area/storage/primary) "bhK" = ( /obj/structure/sink/kitchen{ - pixel_y = 30 + pixel_y = 25 }, /turf/simulated/floor/plasteel{ icon_state = "white" @@ -25422,7 +25477,9 @@ }, /area/security/main) "biF" = ( -/obj/machinery/computer/security, +/obj/machinery/computer/security{ + dir = 8 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -25715,8 +25772,7 @@ "bje" = ( /obj/structure/sink{ dir = 8; - pixel_x = -12; - pixel_y = 2 + pixel_x = -12 }, /obj/machinery/alarm{ dir = 4; @@ -26307,24 +26363,26 @@ }, /area/security/main) "bkn" = ( -/obj/machinery/computer/secure_data, /obj/machinery/firealarm{ dir = 4; pixel_x = 24 }, +/obj/machinery/computer/secure_data{ + dir = 8 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, /area/security/main) "bko" = ( /obj/structure/bed/dogbed, -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_y = 32 - }, /obj/machinery/camera{ c_tag = "Head of Security's Office"; network = list("SS13","Security") }, +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_y = 32 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "vault" @@ -26332,7 +26390,7 @@ /area/security/hos) "bkp" = ( /obj/structure/table/wood, -/obj/machinery/photocopier/faxmachine/longrange{ +/obj/machinery/photocopier/faxmachine{ department = "Head of Security's Office" }, /turf/simulated/floor/plasteel{ @@ -26415,6 +26473,7 @@ }, /obj/machinery/atmospherics/pipe/simple/visible/green, /obj/machinery/computer/general_air_control/large_tank_control{ + dir = 4; frequency = 1441; input_tag = "n2o_in"; name = "Nitrous Oxide Supply Control"; @@ -26652,25 +26711,26 @@ }, /area/security/permabrig) "blf" = ( +/obj/structure/foodcart, +/obj/effect/decal/warning_stripes/yellow, /obj/machinery/firealarm{ dir = 1; pixel_y = -24 }, -/obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel, /area/crew_quarters/kitchen) "blg" = ( -/obj/structure/foodcart, +/obj/machinery/light, +/obj/machinery/vending/dinnerware, /obj/effect/decal/warning_stripes/yellow, /turf/simulated/floor/plasteel, /area/crew_quarters/kitchen) "blh" = ( -/obj/machinery/light, -/obj/machinery/vending/dinnerware, +/obj/machinery/icemachine, +/obj/effect/decal/warning_stripes/yellow, /obj/machinery/status_display{ pixel_y = -32 }, -/obj/effect/decal/warning_stripes/yellow, /turf/simulated/floor/plasteel, /area/crew_quarters/kitchen) "bli" = ( @@ -26686,11 +26746,6 @@ }, /area/crew_quarters/kitchen) "blj" = ( -/obj/machinery/icemachine, -/obj/effect/decal/warning_stripes/yellow, -/turf/simulated/floor/plasteel, -/area/crew_quarters/kitchen) -"blk" = ( /obj/structure/rack, /obj/item/storage/box/donkpockets, /obj/item/storage/box/donkpockets, @@ -26698,7 +26753,7 @@ /obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel, /area/crew_quarters/kitchen) -"bll" = ( +"blk" = ( /obj/structure/table/reinforced, /obj/item/reagent_containers/food/snacks/mint, /obj/item/reagent_containers/food/condiment/enzyme, @@ -26706,6 +26761,10 @@ /obj/machinery/reagentgrinder, /turf/simulated/floor/plasteel, /area/crew_quarters/kitchen) +"bll" = ( +/obj/machinery/kitchen_machine/candy_maker, +/turf/simulated/floor/plasteel, +/area/crew_quarters/kitchen) "blm" = ( /obj/machinery/kitchen_machine/grill, /turf/simulated/floor/plasteel, @@ -26844,7 +26903,9 @@ }, /area/hallway/primary/fore) "blA" = ( -/obj/machinery/computer/merch, +/obj/machinery/computer/merch{ + dir = 1 + }, /turf/simulated/floor/plasteel{ dir = 6; icon_state = "brown" @@ -27028,7 +27089,7 @@ /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 + pixel_y = 25 }, /obj/machinery/camera{ c_tag = "Perma-Brig Garden"; @@ -27896,7 +27957,9 @@ }, /area/security/hos) "bnI" = ( -/obj/machinery/computer/card/minor/hos, +/obj/machinery/computer/card/minor/hos{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "vault" @@ -27909,7 +27972,9 @@ }, /area/crew_quarters/heads/hos) "bnL" = ( -/obj/machinery/computer/prisoner, +/obj/machinery/computer/prisoner{ + dir = 8 + }, /turf/simulated/floor/plasteel{ icon_state = "grimy" }, @@ -28447,10 +28512,10 @@ }, /area/security/prisonershuttle) "boN" = ( -/obj/machinery/computer/security, /obj/item/radio/intercom{ pixel_y = 28 }, +/obj/machinery/computer/security, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "red" @@ -28460,11 +28525,11 @@ /obj/machinery/ai_status_display{ pixel_y = 32 }, -/obj/machinery/computer/secure_data, /obj/machinery/camera{ c_tag = "Labour Camp Access"; network = list("SS13","Security") }, +/obj/machinery/computer/secure_data, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "red" @@ -28774,7 +28839,9 @@ icon_state = "4-8"; tag = "" }, -/obj/machinery/computer/crew, +/obj/machinery/computer/crew{ + dir = 8 + }, /turf/simulated/floor/plasteel{ icon_state = "grimy" }, @@ -29824,10 +29891,12 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/machinery/computer/security, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/machinery/computer/security{ + dir = 1 + }, /turf/simulated/floor/plasteel{ icon_state = "grimy" }, @@ -29848,10 +29917,12 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/machinery/computer/prisoner, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/machinery/computer/prisoner{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "vault" @@ -30591,7 +30662,9 @@ icon_state = "4-8" }, /obj/effect/decal/warning_stripes/west, -/obj/machinery/computer/shuttle/labor, +/obj/machinery/computer/shuttle/labor{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "red" @@ -31545,8 +31618,7 @@ "buP" = ( /obj/structure/sink{ dir = 8; - pixel_x = -12; - pixel_y = 2 + pixel_x = -12 }, /obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel, @@ -31566,7 +31638,7 @@ "buS" = ( /obj/structure/sink{ dir = 4; - pixel_x = 10 + pixel_x = 12 }, /obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel, @@ -32110,6 +32182,7 @@ "bvU" = ( /obj/machinery/atmospherics/pipe/simple/visible/cyan, /obj/machinery/computer/general_air_control/large_tank_control{ + dir = 4; frequency = 1441; input_tag = "waste_in"; name = "Gas Mix Tank Control"; @@ -32688,11 +32761,11 @@ /turf/simulated/floor/plating, /area/engine/break_room) "bwV" = ( +/mob/living/simple_animal/bot/floorbot, /obj/structure/sign/poster/official/help_others{ pixel_x = -32 }, /obj/structure/table/reinforced, -/mob/living/simple_animal/bot/floorbot, /turf/simulated/floor/plasteel{ dir = 9; icon_state = "yellow" @@ -32951,12 +33024,12 @@ }, /area/bridge) "bxw" = ( -/obj/machinery/computer/monitor, /obj/structure/cable{ d2 = 2; icon_state = "0-2"; pixel_y = 1 }, +/obj/machinery/computer/monitor, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "darkyellow" @@ -33429,7 +33502,9 @@ /obj/machinery/status_display{ pixel_x = -32 }, -/obj/machinery/computer/security/engineering, +/obj/machinery/computer/security/engineering{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "caution" @@ -34210,7 +34285,9 @@ /turf/simulated/floor/plasteel, /area/engine/break_room) "bzX" = ( -/obj/machinery/computer/atmoscontrol, +/obj/machinery/computer/atmoscontrol{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "caution" @@ -35060,7 +35137,9 @@ dir = 1; pixel_y = -24 }, -/obj/machinery/computer/station_alert, +/obj/machinery/computer/station_alert{ + dir = 1 + }, /turf/simulated/floor/plasteel{ icon_state = "caution" }, @@ -35070,7 +35149,9 @@ /obj/machinery/newscaster{ pixel_y = -32 }, -/obj/machinery/computer/atmos_alert, +/obj/machinery/computer/atmos_alert{ + dir = 1 + }, /turf/simulated/floor/plasteel{ icon_state = "caution" }, @@ -36343,7 +36424,7 @@ dir = 4; icon_state = "whitebluecorner" }, -/area/maintenance/starboard) +/area/hallway/primary/central) "bDE" = ( /obj/item/twohanded/required/kirbyplants, /obj/machinery/status_display{ @@ -36654,15 +36735,15 @@ d2 = 2; icon_state = "1-2" }, -/obj/machinery/computer/communications, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/computer/communications, /turf/simulated/floor/carpet, /area/bridge) "bEh" = ( /obj/structure/table/wood, -/obj/machinery/computer/security/wooden_tv, /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/computer/security/wooden_tv, /turf/simulated/floor/carpet, /area/bridge) "bEi" = ( @@ -36903,7 +36984,7 @@ dir = 4; icon_state = "whitebluecorner" }, -/area/maintenance/starboard) +/area/hallway/primary/central) "bEI" = ( /turf/simulated/floor/plasteel{ dir = 8; @@ -39279,12 +39360,14 @@ /turf/simulated/floor/wood, /area/crew_quarters/captain) "bJs" = ( -/obj/machinery/computer/security/mining, /obj/machinery/newscaster{ layer = 3.3; pixel_y = -27 }, /obj/effect/decal/warning_stripes/yellow/hollow, +/obj/machinery/computer/security/mining{ + dir = 1 + }, /turf/simulated/floor/plasteel, /area/quartermaster/miningdock) "bJt" = ( @@ -40225,7 +40308,9 @@ name = "Detective Requests Console"; pixel_x = 30 }, -/obj/machinery/computer/med_data, +/obj/machinery/computer/med_data{ + dir = 8 + }, /turf/simulated/floor/plasteel{ icon_state = "carpet" }, @@ -40595,7 +40680,9 @@ /obj/machinery/status_display{ pixel_x = -32 }, -/obj/machinery/computer/card/minor/ce, +/obj/machinery/computer/card/minor/ce{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -40648,8 +40735,10 @@ /turf/simulated/floor/plating, /area/crew_quarters/chief) "bMn" = ( -/obj/machinery/computer/shuttle/mining, /obj/effect/decal/warning_stripes/yellow/hollow, +/obj/machinery/computer/shuttle/mining{ + dir = 1 + }, /turf/simulated/floor/plasteel, /area/quartermaster/miningdock) "bMo" = ( @@ -40664,7 +40753,9 @@ }, /area/engine/break_room) "bMp" = ( -/obj/machinery/computer/drone_control, +/obj/machinery/computer/drone_control{ + dir = 1 + }, /turf/simulated/floor/plasteel{ dir = 7; icon_state = "yellow" @@ -40785,7 +40876,7 @@ /turf/simulated/floor/plasteel{ icon_state = "white" }, -/area/maintenance/starboard) +/area/hallway/primary/central) "bME" = ( /obj/structure/table/reinforced, /obj/machinery/light{ @@ -41211,13 +41302,17 @@ /obj/machinery/status_display{ pixel_x = 32 }, -/obj/machinery/computer/secure_data, +/obj/machinery/computer/secure_data{ + dir = 8 + }, /turf/simulated/floor/plasteel{ icon_state = "carpet" }, /area/security/detectives_office) "bNv" = ( -/obj/machinery/computer/secure_data, +/obj/machinery/computer/secure_data{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "redcorner" @@ -41277,7 +41372,9 @@ }, /area/security/brig) "bNF" = ( -/obj/machinery/computer/secure_data, +/obj/machinery/computer/secure_data{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 6; icon_state = "red" @@ -41438,7 +41535,6 @@ }, /area/engine/break_room) "bNZ" = ( -/obj/machinery/computer/atmos_alert, /obj/machinery/camera{ c_tag = "Chief Engineer's Office"; dir = 4; @@ -41452,6 +41548,9 @@ name = "Chief Engineer Requests Console"; pixel_x = -32 }, +/obj/machinery/computer/atmos_alert{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -41803,7 +41902,9 @@ /turf/simulated/floor/wood, /area/crew_quarters/heads/hop) "bOM" = ( -/obj/machinery/computer/account_database, +/obj/machinery/computer/account_database{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "dark" @@ -41856,10 +41957,10 @@ /turf/simulated/wall, /area/turret_protected/ai_upload) "bOU" = ( +/mob/living/simple_animal/pet/dog/fox/Renault, /obj/structure/bed/dogbed{ name = "fox box" }, -/mob/living/simple_animal/pet/dog/fox/Renault, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "dark" @@ -42061,24 +42162,26 @@ /area/security/detectives_office) "bPp" = ( /obj/structure/table/wood, +/obj/item/flashlight/lamp, +/obj/item/reagent_containers/food/drinks/flask/detflask, /obj/machinery/computer/security/wooden_tv, /turf/simulated/floor/plasteel{ icon_state = "carpet" }, /area/security/detectives_office) "bPq" = ( -/obj/structure/table/wood, -/obj/item/storage/secure/safe{ - pixel_x = 32 +/obj/machinery/computer/arcade{ + dir = 4 }, -/obj/item/flashlight/lamp, -/obj/item/reagent_containers/food/drinks/flask/detflask, /turf/simulated/floor/plasteel{ - icon_state = "carpet" + dir = 5; + icon_state = "dark" }, -/area/security/detectives_office) +/area/maintenance/fore2) "bPr" = ( -/obj/machinery/computer/security, +/obj/machinery/computer/security{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "redcorner" @@ -43215,8 +43318,8 @@ }, /area/construction/hallway) "bRt" = ( -/obj/machinery/computer/teleporter, /obj/effect/decal/warning_stripes/southeast, +/obj/machinery/computer/teleporter, /turf/simulated/floor/plating, /area/turret_protected/aisat) "bRu" = ( @@ -43259,9 +43362,6 @@ /turf/simulated/floor/plasteel, /area/maintenance/starboard) "bRx" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 8 - }, /obj/structure/showcase{ density = 0; dir = 4; @@ -43272,6 +43372,9 @@ pixel_y = 2 }, /obj/effect/decal/warning_stripes/south, +/obj/machinery/atmospherics/pipe/simple/visible/cyan{ + dir = 5 + }, /turf/simulated/floor/plating, /area/turret_protected/aisat) "bRz" = ( @@ -43420,7 +43523,9 @@ /obj/machinery/status_display{ pixel_x = -32 }, -/obj/machinery/computer/station_alert, +/obj/machinery/computer/station_alert{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -43687,9 +43792,7 @@ }, /obj/machinery/meter, /obj/effect/decal/warning_stripes/south, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 9 - }, +/obj/machinery/atmospherics/pipe/manifold/visible/cyan, /turf/simulated/floor/plating, /area/turret_protected/aisat) "bSv" = ( @@ -43826,11 +43929,13 @@ }, /area/turret_protected/ai_upload) "bSJ" = ( -/obj/machinery/computer/aiupload, /obj/machinery/flasher{ id = "AI"; pixel_y = -21 }, +/obj/machinery/computer/aiupload{ + dir = 1 + }, /turf/simulated/floor/bluegrid, /area/turret_protected/ai_upload) "bSK" = ( @@ -43843,10 +43948,12 @@ /turf/simulated/floor/bluegrid, /area/turret_protected/ai_upload) "bSL" = ( -/obj/machinery/computer/borgupload, /obj/item/radio/intercom/private{ pixel_y = -28 }, +/obj/machinery/computer/borgupload{ + dir = 1 + }, /turf/simulated/floor/bluegrid, /area/turret_protected/ai_upload) "bSM" = ( @@ -43871,7 +43978,9 @@ name = "Captain Requests Console"; pixel_x = -30 }, -/obj/machinery/computer/card, +/obj/machinery/computer/card{ + dir = 4 + }, /turf/simulated/floor/carpet/black, /area/crew_quarters/captain) "bSP" = ( @@ -43983,6 +44092,9 @@ dir = 1 }, /obj/effect/decal/warning_stripes/south, +/obj/machinery/atmospherics/pipe/simple/hidden/universal{ + dir = 4 + }, /turf/simulated/floor/plating, /area/turret_protected/aisat) "bTd" = ( @@ -44158,7 +44270,9 @@ icon_state = "2-4"; tag = "" }, -/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 1 + }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, @@ -44249,6 +44363,7 @@ }, /area/turret_protected/aisat) "bTD" = ( +/mob/living/simple_animal/bot/secbot/pingsky, /obj/structure/cable{ d1 = 2; d2 = 8; @@ -44261,7 +44376,6 @@ icon_state = "2-4"; tag = "" }, -/mob/living/simple_animal/bot/secbot/pingsky, /obj/machinery/atmospherics/pipe/manifold4w/hidden/supply, /obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers, /turf/simulated/floor/plasteel{ @@ -44635,11 +44749,11 @@ }, /area/engine/break_room) "bUg" = ( +/mob/living/simple_animal/parrot/Poly, /obj/structure/filingcabinet/chestdrawer, /obj/machinery/light{ dir = 8 }, -/mob/living/simple_animal/parrot/Poly, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -44900,6 +45014,9 @@ icon_state = "1-8" }, /obj/effect/decal/warning_stripes/south, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, /turf/simulated/floor/plating, /area/turret_protected/aisat) "bUG" = ( @@ -45022,10 +45139,12 @@ /turf/simulated/floor/wood, /area/crew_quarters/heads/hop) "bUV" = ( -/obj/machinery/computer/communications, /obj/machinery/ai_status_display{ pixel_x = -32 }, +/obj/machinery/computer/communications{ + dir = 4 + }, /turf/simulated/floor/carpet/black, /area/crew_quarters/captain) "bUW" = ( @@ -45302,12 +45421,12 @@ }, /area/hallway/primary/starboard) "bVp" = ( +/mob/living/simple_animal/bot/secbot/beepsky, /obj/machinery/navbeacon{ codes_txt = "patrol;next_patrol=hall12"; location = "hall11" }, /obj/item/radio/beacon, -/mob/living/simple_animal/bot/secbot/beepsky, /obj/structure/cable{ d1 = 1; d2 = 8; @@ -45655,12 +45774,14 @@ name = "east bump"; pixel_x = 24 }, -/obj/machinery/computer/prisoner, /obj/machinery/camera{ c_tag = "Warden's Office"; dir = 8; network = list("SS13","Security") }, +/obj/machinery/computer/prisoner{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "red" @@ -45717,7 +45838,9 @@ pixel_y = -8; req_access_txt = "11" }, -/obj/machinery/computer/security/engineering, +/obj/machinery/computer/security/engineering{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -45864,7 +45987,7 @@ }, /obj/machinery/alarm{ dir = 1; - pixel_y = -22 + pixel_y = -24 }, /obj/item/twohanded/required/kirbyplants, /turf/simulated/floor/plasteel{ @@ -46580,7 +46703,9 @@ d2 = 8; icon_state = "4-8" }, -/obj/machinery/computer/card, +/obj/machinery/computer/card{ + dir = 1 + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "dark" @@ -46759,7 +46884,9 @@ }, /obj/machinery/door/firedoor, /obj/structure/disposalpipe/segment, -/turf/simulated/floor/plating, +/turf/simulated/floor/plasteel{ + icon_state = "cult" + }, /area/magistrateoffice) "bYQ" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -47144,7 +47271,10 @@ /obj/machinery/power/smes{ charge = 2e+006 }, -/turf/simulated/floor/greengrid, +/turf/simulated/floor/plasteel{ + dir = 5; + icon_state = "dark" + }, /area/engine/engineering) "bZE" = ( /obj/structure/cable{ @@ -47154,7 +47284,10 @@ /obj/machinery/power/smes{ charge = 2e+006 }, -/turf/simulated/floor/greengrid, +/turf/simulated/floor/plasteel{ + dir = 5; + icon_state = "dark" + }, /area/engine/engineering) "bZG" = ( /obj/effect/decal/cleanable/dirt, @@ -47183,11 +47316,11 @@ /area/maintenance/port) "bZJ" = ( /obj/structure/table/wood, -/obj/machinery/computer/library, /obj/machinery/light_switch{ pixel_x = 4; pixel_y = 26 }, +/obj/machinery/computer/library, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -47275,10 +47408,10 @@ /obj/item/radio/intercom{ pixel_y = 26 }, +/obj/effect/decal/cleanable/cobweb, /obj/machinery/computer/security/telescreen/entertainment{ pixel_x = -32 }, -/obj/effect/decal/cleanable/cobweb, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -47324,10 +47457,12 @@ /turf/simulated/wall/r_wall, /area/crew_quarters/heads/hop) "bZX" = ( -/obj/machinery/computer/secure_data, /obj/machinery/light{ dir = 8 }, +/obj/machinery/computer/secure_data{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "dark" @@ -47621,13 +47756,13 @@ /turf/simulated/floor/wood, /area/lawoffice) "caM" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /obj/machinery/computer/prisoner{ req_access = null; req_access_txt = "2" }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plasteel{ icon_state = "cult" }, @@ -47675,7 +47810,6 @@ /obj/item/radio/intercom{ pixel_y = 26 }, -/obj/machinery/computer/med_data/laptop, /obj/machinery/flasher_button{ id = "hopflash"; pixel_x = -38; @@ -47702,6 +47836,7 @@ pixel_x = -24; pixel_y = 8 }, +/obj/machinery/computer/med_data/laptop, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "dark" @@ -48348,6 +48483,9 @@ /obj/structure/sign/poster/official/random{ pixel_x = 32 }, +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_x = 32 + }, /turf/simulated/floor/wood, /area/ntrep) "ccd" = ( @@ -49022,7 +49160,9 @@ /turf/simulated/wall/r_wall, /area/crew_quarters/heads/hop) "cdE" = ( -/obj/machinery/computer/supplycomp, +/obj/machinery/computer/supplycomp{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "dark" @@ -49654,13 +49794,14 @@ name = "Station Intercom (General)"; pixel_y = -29 }, -/obj/machinery/computer/station_alert, /obj/structure/cable{ d1 = 4; d2 = 8; icon_state = "4-8" }, +/obj/machinery/computer/station_alert, /obj/machinery/computer/monitor{ + dir = 1; name = "Grid Power Monitoring Computer" }, /turf/simulated/floor/plasteel{ @@ -49673,12 +49814,14 @@ pixel_x = 28; pixel_y = -28 }, -/obj/machinery/computer/atmos_alert, /obj/structure/cable{ d1 = 4; d2 = 8; icon_state = "4-8" }, +/obj/machinery/computer/atmos_alert{ + dir = 1 + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "dark" @@ -49830,7 +49973,9 @@ d2 = 8; icon_state = "4-8" }, -/obj/machinery/computer/security/mining, +/obj/machinery/computer/security/mining{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "dark" @@ -50539,9 +50684,11 @@ /area/teleporter) "chu" = ( /obj/machinery/light, -/obj/machinery/computer/monitor, /obj/structure/cable, /obj/effect/decal/warning_stripes/north, +/obj/machinery/computer/monitor{ + dir = 1 + }, /turf/simulated/floor/plating, /area/turret_protected/aisat) "chv" = ( @@ -51026,12 +51173,12 @@ /turf/simulated/floor/carpet, /area/crew_quarters/heads/hop) "ciE" = ( +/mob/living/simple_animal/pet/dog/corgi/Ian, /obj/structure/bed/dogbed/ian, /obj/machinery/alarm{ dir = 8; pixel_x = 24 }, -/mob/living/simple_animal/pet/dog/corgi/Ian, /turf/simulated/floor/wood, /area/crew_quarters/heads/hop) "ciF" = ( @@ -51284,6 +51431,7 @@ icon_state = "0-4" }, /obj/machinery/computer/monitor{ + dir = 1; name = "Grid Power Monitoring Computer" }, /turf/simulated/floor/plasteel{ @@ -52890,7 +53038,7 @@ /turf/simulated/floor/plasteel{ icon_state = "white" }, -/area/maintenance/starboard) +/area/hallway/primary/central) "cmv" = ( /obj/structure/cable{ d1 = 1; @@ -53235,10 +53383,10 @@ /area/library) "cnn" = ( /obj/structure/table/wood, -/obj/machinery/computer/library/checkout, /obj/machinery/newscaster{ pixel_x = 32 }, +/obj/machinery/computer/library/checkout, /turf/simulated/floor/plasteel{ icon_state = "grimy" }, @@ -53397,7 +53545,9 @@ /turf/simulated/floor/plating, /area/security/range) "cnG" = ( -/obj/machinery/computer/teleporter, +/obj/machinery/computer/teleporter{ + dir = 8 + }, /turf/simulated/floor/plating, /area/teleporter) "cnH" = ( @@ -53601,7 +53751,7 @@ /area/engine/engineering) "cog" = ( /obj/effect/decal/cleanable/dirt, -/obj/machinery/the_singularitygen, +/obj/machinery/the_singularitygen/tesla, /turf/simulated/floor/plating, /area/engine/engineering) "coh" = ( @@ -53673,11 +53823,6 @@ /obj/effect/decal/warning_stripes/northeast, /turf/simulated/floor/plasteel, /area/engine/engine_smes) -"cop" = ( -/obj/machinery/the_singularitygen, -/obj/effect/decal/warning_stripes/yellow/hollow, -/turf/simulated/floor/plasteel, -/area/engine/engine_smes) "coq" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/door/firedoor, @@ -54957,11 +55102,6 @@ /obj/effect/decal/warning_stripes/northeast, /turf/simulated/floor/plating/airless, /area/space/nearstation) -"cqP" = ( -/obj/machinery/the_singularitygen/tesla, -/obj/effect/decal/warning_stripes/yellow/hollow, -/turf/simulated/floor/plasteel, -/area/engine/engine_smes) "cqQ" = ( /obj/effect/decal/warning_stripes/east, /turf/simulated/floor/plating/airless, @@ -55083,12 +55223,12 @@ "crl" = ( /obj/structure/table/wood, /obj/item/storage/pill_bottle/dice, -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_y = -32 - }, /obj/structure/window/reinforced{ dir = 8 }, +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_y = -32 + }, /turf/simulated/floor/plasteel{ icon_state = "grimy" }, @@ -58958,12 +59098,12 @@ dir = 1; in_use = 1 }, -/obj/machinery/computer/cryopod{ - pixel_y = 32 - }, /obj/machinery/camera{ c_tag = "Cryodorms Fore" }, +/obj/machinery/computer/cryopod{ + pixel_y = 32 + }, /turf/simulated/floor/plasteel{ icon_state = "freezerfloor" }, @@ -61285,8 +61425,7 @@ "cEj" = ( /obj/structure/sink{ dir = 8; - pixel_x = -12; - pixel_y = 2 + pixel_x = -12 }, /obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel, @@ -61624,7 +61763,7 @@ dir = 1; icon_state = "whitebluecorner" }, -/area/maintenance/starboard) +/area/hallway/primary/central) "cFe" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 10 @@ -62679,7 +62818,7 @@ dir = 1; icon_state = "whitebluecorner" }, -/area/maintenance/starboard) +/area/hallway/primary/central) "cGI" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -62892,7 +63031,9 @@ }, /area/crew_quarters/fitness) "cHb" = ( -/obj/machinery/computer/HolodeckControl, +/obj/machinery/computer/HolodeckControl{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/crew_quarters/fitness) "cHc" = ( @@ -64345,7 +64486,7 @@ /obj/effect/spawner/window/reinforced, /obj/machinery/door/firedoor, /turf/simulated/floor/plating, -/area/maintenance/starboard) +/area/medical/psych) "cLb" = ( /obj/machinery/door/airlock/medical{ id_tag = "psychfoyer"; @@ -64354,7 +64495,7 @@ }, /obj/machinery/door/firedoor, /turf/simulated/floor/wood, -/area/maintenance/starboard) +/area/hallway/primary/central) "cLd" = ( /obj/structure/cable{ d2 = 4; @@ -66658,13 +66799,13 @@ /area/crew_quarters/sleep) "cQj" = ( /obj/machinery/light, -/obj/machinery/computer/cryopod{ - pixel_y = -32 - }, /obj/machinery/camera{ c_tag = "Cryodorms Aft"; dir = 1 }, +/obj/machinery/computer/cryopod{ + pixel_y = -32 + }, /turf/simulated/floor/plasteel{ icon_state = "freezerfloor" }, @@ -67583,10 +67724,12 @@ /turf/simulated/floor/plasteel, /area/toxins/xenobiology) "cSh" = ( -/obj/machinery/computer/camera_advanced/xenobio, /obj/machinery/status_display{ pixel_x = 32 }, +/obj/machinery/computer/camera_advanced/xenobio{ + dir = 8 + }, /turf/simulated/floor/plasteel, /area/toxins/xenobiology) "cSi" = ( @@ -67920,7 +68063,7 @@ "cST" = ( /obj/structure/sink{ dir = 4; - pixel_x = 10 + pixel_x = 12 }, /obj/effect/decal/cleanable/vomit, /obj/effect/decal/cleanable/dirt, @@ -68485,7 +68628,7 @@ /turf/simulated/floor/plating, /area/medical/medbay) "cTZ" = ( -/obj/machinery/smartfridge/secure/chemistry, +/obj/machinery/smartfridge/medbay, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -69349,7 +69492,9 @@ /turf/simulated/floor/plating, /area/maintenance/starboardsolar) "cVM" = ( -/obj/machinery/computer/med_data, +/obj/machinery/computer/med_data{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "whitebluecorner" @@ -70065,11 +70210,13 @@ }, /area/medical/medbay3) "cXm" = ( -/obj/machinery/computer/crew, /obj/item/radio/intercom{ dir = 8; pixel_x = -28 }, +/obj/machinery/computer/crew{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "whiteblue" @@ -70428,8 +70575,10 @@ }, /area/toxins/lab) "cYn" = ( -/obj/machinery/computer/rdconsole/core, /obj/effect/decal/warning_stripes/southwest, +/obj/machinery/computer/rdconsole/core{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/toxins/lab) "cYo" = ( @@ -73003,18 +73152,13 @@ }, /area/hallway/primary/aft) "ddL" = ( -/obj/machinery/smartfridge/medbay, +/obj/machinery/smartfridge/secure/medbay, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/machinery/door/window/westleft{ - dir = 4; - name = "Chemistry Desk"; - req_one_access_txt = "5;33" - }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -73646,7 +73790,12 @@ }, /area/library/abandoned) "deV" = ( -/obj/machinery/atmospherics/unary/vent_scrubber/on, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + tag = "" + }, /turf/simulated/floor/plasteel{ icon_state = "whitegreen" }, @@ -74435,11 +74584,11 @@ dir = 1; on = 1 }, -/obj/machinery/computer/cloning, /obj/structure/sign/nosmoking_2{ pixel_y = 32 }, /obj/machinery/atmospherics/unary/vent_scrubber/on, +/obj/machinery/computer/cloning, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "whitepurplecorner" @@ -74786,11 +74935,8 @@ /obj/structure/girder, /obj/structure/grille, /obj/machinery/door/poddoor{ - density = 0; - icon_state = "pdoor0"; id_tag = "maintrobotics"; - name = "Decrepit Blast Door"; - opacity = 0 + name = "Decrepit Blast Door" }, /obj/effect/decal/warning_stripes/east, /obj/effect/decal/warning_stripes/west, @@ -75297,7 +75443,9 @@ /turf/simulated/floor/plasteel, /area/assembly/chargebay) "dio" = ( -/obj/machinery/computer/mech_bay_power_console, +/obj/machinery/computer/mech_bay_power_console{ + dir = 8 + }, /turf/simulated/floor/bluegrid, /area/assembly/chargebay) "dip" = ( @@ -75715,11 +75863,8 @@ /obj/structure/girder, /obj/structure/grille, /obj/machinery/door/poddoor{ - density = 0; - icon_state = "pdoor0"; id_tag = "maintrobotics"; - name = "Decrepit Blast Door"; - opacity = 0 + name = "Decrepit Blast Door" }, /obj/effect/decal/warning_stripes/east, /obj/effect/decal/warning_stripes/west, @@ -75898,8 +76043,10 @@ }, /area/toxins/explab) "dju" = ( -/obj/machinery/computer/rdconsole/experiment, /obj/effect/decal/warning_stripes/yellow/hollow, +/obj/machinery/computer/rdconsole/experiment{ + dir = 1 + }, /turf/simulated/floor/plasteel{ icon_state = "whitepurplecorner" }, @@ -77690,8 +77837,10 @@ /obj/machinery/ai_status_display{ pixel_x = 32 }, -/obj/machinery/computer/card/minor/rd, /obj/effect/decal/warning_stripes/yellow/hollow, +/obj/machinery/computer/card/minor/rd{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "whitepurple" @@ -77710,7 +77859,9 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/computer/aifixer, +/obj/machinery/computer/aifixer{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -77737,6 +77888,7 @@ dir = 4 }, /obj/machinery/computer/general_air_control{ + dir = 4; frequency = 1222; name = "Bomb Mix Monitor"; sensors = list("burn_sensor" = "Burn Mix") @@ -77778,7 +77930,9 @@ }, /area/assembly/chargebay) "dnA" = ( -/obj/machinery/computer/mech_bay_power_console, +/obj/machinery/computer/mech_bay_power_console{ + dir = 8 + }, /turf/simulated/floor/greengrid, /area/assembly/chargebay) "dnB" = ( @@ -77896,8 +78050,8 @@ dir = 1; on = 1 }, -/obj/machinery/computer/scan_consolenew, /obj/effect/decal/warning_stripes/southwest, +/obj/machinery/computer/scan_consolenew, /turf/simulated/floor/plasteel, /area/medical/genetics) "dnO" = ( @@ -77918,6 +78072,7 @@ }, /area/medical/genetics) "dnR" = ( +/mob/living/carbon/human/monkey, /obj/structure/window/reinforced{ dir = 1 }, @@ -77927,7 +78082,6 @@ /obj/structure/window/reinforced{ dir = 8 }, -/mob/living/carbon/human/monkey, /turf/simulated/floor/grass, /area/medical/genetics) "dnT" = ( @@ -78336,8 +78490,10 @@ d2 = 8; icon_state = "4-8" }, -/obj/machinery/computer/mecha, /obj/effect/decal/warning_stripes/yellow/hollow, +/obj/machinery/computer/mecha{ + dir = 8 + }, /turf/simulated/floor/plasteel{ icon_state = "whitepurplecorner" }, @@ -78957,7 +79113,9 @@ /turf/simulated/floor/greengrid, /area/medical/research) "dpV" = ( -/obj/machinery/computer/mech_bay_power_console, +/obj/machinery/computer/mech_bay_power_console{ + dir = 1 + }, /turf/simulated/floor/greengrid, /area/medical/research) "dpW" = ( @@ -79021,8 +79179,10 @@ /obj/machinery/status_display{ pixel_x = 32 }, -/obj/machinery/computer/robotics, /obj/effect/decal/warning_stripes/yellow/hollow, +/obj/machinery/computer/robotics{ + dir = 8 + }, /turf/simulated/floor/plasteel{ icon_state = "whitepurplecorner" }, @@ -79826,6 +79986,7 @@ }, /area/medical/genetics) "drZ" = ( +/mob/living/carbon/human/monkey, /obj/structure/window/reinforced, /obj/structure/window/reinforced{ dir = 4 @@ -79833,7 +79994,6 @@ /obj/structure/window/reinforced{ dir = 8 }, -/mob/living/carbon/human/monkey, /turf/simulated/floor/grass, /area/medical/genetics) "dsb" = ( @@ -79854,6 +80014,7 @@ }, /area/medical/medbay) "dsd" = ( +/mob/living/simple_animal/pet/cat/Runtime, /obj/machinery/light{ dir = 8 }, @@ -79864,7 +80025,6 @@ /obj/structure/bed/dogbed{ name = "kitty basket" }, -/mob/living/simple_animal/pet/cat/Runtime, /obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ icon_state = "dark" @@ -80285,8 +80445,10 @@ /area/medical/genetics) "dsV" = ( /obj/machinery/light, -/obj/machinery/computer/scan_consolenew, /obj/effect/decal/warning_stripes/northwest, +/obj/machinery/computer/scan_consolenew{ + dir = 1 + }, /turf/simulated/floor/plasteel, /area/medical/genetics) "dsW" = ( @@ -80302,7 +80464,6 @@ /area/medical/genetics) "dsX" = ( /obj/structure/table/glass, -/obj/machinery/computer/med_data/laptop, /obj/structure/mirror{ pixel_y = -30 }, @@ -80310,6 +80471,9 @@ dir = 1; icon_state = "pipe-c" }, +/obj/machinery/computer/med_data/laptop{ + dir = 1 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -81021,10 +81185,12 @@ /obj/machinery/ai_status_display{ pixel_x = 32 }, -/obj/machinery/computer/card/minor/cmo, /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 8 }, +/obj/machinery/computer/card/minor/cmo{ + dir = 8 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -81064,11 +81230,13 @@ }, /area/medical/surgery1) "duA" = ( -/obj/machinery/computer/operating, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 5 }, +/obj/machinery/computer/operating{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "darkblue" @@ -81077,7 +81245,7 @@ "duB" = ( /obj/structure/sink{ dir = 4; - pixel_x = 11 + pixel_x = 12 }, /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 8 @@ -81418,19 +81586,28 @@ /obj/effect/landmark/start{ name = "Roboticist" }, +/obj/effect/decal/warning_stripes/southeastcorner, /turf/simulated/floor/plasteel, /area/assembly/robotics) "dvp" = ( -/obj/structure/window/reinforced/polarized, -/obj/effect/decal/warning_stripes/south, -/obj/machinery/computer/rdconsole/robotics, -/turf/simulated/floor/plasteel, +/obj/structure/window/reinforced/polarized{ + dir = 8 + }, +/turf/simulated/floor/plasteel{ + icon_state = "white" + }, /area/assembly/robotics) "dvq" = ( -/obj/structure/window/reinforced/polarized, -/obj/effect/decal/warning_stripes/southeast, -/obj/structure/filingcabinet/chestdrawer, -/turf/simulated/floor/plasteel, +/obj/structure/mirror{ + pixel_x = 32 + }, +/obj/structure/sink{ + dir = 4; + pixel_x = 12 + }, +/turf/simulated/floor/plasteel{ + icon_state = "white" + }, /area/assembly/robotics) "dvr" = ( /obj/structure/chair/office/light{ @@ -81590,7 +81767,6 @@ }, /area/medical/cmo) "dvJ" = ( -/obj/machinery/computer/crew, /obj/machinery/requests_console{ announcementConsole = 1; department = "Chief Medical Officer's Desk"; @@ -81598,6 +81774,9 @@ name = "Chief Medical Officer Requests Console"; pixel_x = 30 }, +/obj/machinery/computer/crew{ + dir = 8 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -81828,7 +82007,9 @@ dir = 4; pixel_x = -24 }, -/obj/machinery/computer/rdservercontrol, +/obj/machinery/computer/rdservercontrol{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -82318,6 +82499,7 @@ /area/toxins/storage) "dxl" = ( /obj/structure/table/reinforced, +/obj/effect/decal/warning_stripes/west, /obj/machinery/computer/security/telescreen{ desc = "Used for watching the test chamber."; dir = 4; @@ -82325,7 +82507,6 @@ name = "Test Chamber Telescreen"; network = list("Toxins") }, -/obj/effect/decal/warning_stripes/west, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -83082,7 +83263,9 @@ /area/toxins/mixing) "dyC" = ( /obj/effect/decal/warning_stripes/northwest, -/obj/machinery/computer/area_atmos, +/obj/machinery/computer/area_atmos{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -83207,7 +83390,7 @@ /turf/simulated/floor/plasteel, /area/assembly/robotics) "dyO" = ( -/obj/effect/decal/warning_stripes/southeastcorner, +/obj/effect/decal/warning_stripes/east, /turf/simulated/floor/plasteel, /area/assembly/robotics) "dyP" = ( @@ -83234,12 +83417,20 @@ }, /area/assembly/robotics) "dyT" = ( -/obj/structure/window/reinforced/polarized, -/obj/effect/decal/warning_stripes/south, -/obj/machinery/r_n_d/circuit_imprinter, -/obj/item/reagent_containers/glass/beaker/sulphuric, -/turf/simulated/floor/plasteel, -/area/assembly/robotics) +/obj/structure/cable{ + d1 = 1; + d2 = 8; + icon_state = "1-8"; + tag = "" + }, +/obj/structure/cable{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/obj/structure/lattice/catwalk, +/turf/space, +/area/maintenance/auxsolarstarboard) "dyU" = ( /obj/machinery/firealarm{ dir = 8; @@ -83855,6 +84046,7 @@ pixel_y = -32 }, /obj/machinery/computer/operating{ + dir = 1; name = "Robotics Operating Computer" }, /turf/simulated/floor/plasteel{ @@ -83994,7 +84186,9 @@ /obj/machinery/newscaster{ pixel_y = -32 }, -/obj/machinery/computer/med_data/laptop, +/obj/machinery/computer/med_data/laptop{ + dir = 1 + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "cmo" @@ -84627,9 +84821,6 @@ /obj/item/bonegel, /obj/item/FixOVein, /obj/item/surgicaldrill, -/obj/structure/mirror{ - pixel_x = 32 - }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -85928,8 +86119,7 @@ }, /obj/structure/sink{ dir = 8; - pixel_x = -12; - pixel_y = 2 + pixel_x = -12 }, /turf/simulated/floor/plating, /area/maintenance/apmaint) @@ -86213,6 +86403,7 @@ pixel_x = -4; pixel_y = 4 }, +/obj/item/reagent_containers/spray/cleaner, /obj/machinery/button/windowtint{ id = 1; pixel_x = 24 @@ -86605,10 +86796,10 @@ /obj/machinery/light/small{ dir = 4 }, +/obj/machinery/atmospherics/unary/vent_scrubber/on, /obj/machinery/computer/security/telescreen/entertainment{ pixel_y = 32 }, -/obj/machinery/atmospherics/unary/vent_scrubber/on, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "whitegreencorner" @@ -86999,15 +87190,15 @@ /area/medical/virology) "dHq" = ( /obj/structure/table/glass, -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_y = 32 - }, /obj/item/radio/intercom{ dir = 4; pixel_x = 28 }, -/obj/machinery/computer/med_data/laptop, /obj/machinery/atmospherics/unary/vent_scrubber/on, +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_y = 32 + }, +/obj/machinery/computer/med_data/laptop, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -87333,8 +87524,7 @@ }, /obj/structure/sink{ dir = 8; - pixel_x = -12; - pixel_y = 2 + pixel_x = -12 }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, @@ -88343,33 +88533,14 @@ /turf/simulated/floor/plating, /area/maintenance/starboardsolar) "dKz" = ( -/obj/effect/spawner/window/reinforced, -/obj/structure/cable{ - d2 = 4; - icon_state = "0-4" - }, -/obj/structure/cable{ - d1 = 2; - d2 = 4; - icon_state = "2-4"; - tag = "" - }, -/turf/simulated/floor/plating, -/area/medical/virology) +/obj/item/stack/cable_coil/random, +/turf/space, +/area/space) "dKA" = ( -/obj/effect/spawner/window/reinforced, -/obj/structure/cable{ - d2 = 2; - icon_state = "0-2" - }, -/obj/structure/cable{ - d1 = 2; - d2 = 4; - icon_state = "2-4"; - tag = "" - }, -/turf/simulated/floor/plating, -/area/medical/virology) +/obj/structure/lattice, +/obj/item/stack/cable_coil/random, +/turf/space, +/area/space/nearstation) "dKB" = ( /obj/effect/spawner/window/reinforced, /obj/structure/cable{ @@ -88579,8 +88750,7 @@ }, /obj/structure/sink{ dir = 8; - pixel_x = -12; - pixel_y = 2 + pixel_x = -12 }, /obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel, @@ -88611,8 +88781,7 @@ "dLd" = ( /obj/structure/sink{ dir = 8; - pixel_x = -12; - pixel_y = 2 + pixel_x = -12 }, /obj/structure/mirror{ pixel_x = -32 @@ -88666,10 +88835,10 @@ }, /area/medical/virology) "dLi" = ( +/mob/living/carbon/human/monkey, /obj/machinery/light/small{ dir = 1 }, -/mob/living/carbon/human/monkey, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -88691,10 +88860,10 @@ }, /area/medical/virology) "dLk" = ( +/mob/living/carbon/human/monkey, /obj/machinery/light/small{ dir = 1 }, -/mob/living/carbon/human/monkey, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, @@ -88985,11 +89154,21 @@ }, /area/medical/virology) "dLR" = ( -/obj/structure/chair/office/dark{ - dir = 1 +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + tag = "" }, +/obj/structure/table/glass, +/obj/structure/reagent_dispensers/virusfood{ + pixel_x = -32 + }, +/obj/machinery/reagentgrinder, +/obj/effect/decal/warning_stripes/east, /turf/simulated/floor/plasteel{ - icon_state = "whitegreen" + dir = 1; + icon_state = "whitegreencorner" }, /area/medical/virology) "dLT" = ( @@ -89168,6 +89347,31 @@ /turf/simulated/floor/plasteel, /area/medical/virology) "dMw" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + tag = "" + }, +/obj/structure/cable{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/obj/structure/cable{ + d1 = 2; + d2 = 4; + icon_state = "2-4"; + tag = "" + }, +/obj/machinery/smartfridge/secure/chemistry/virology/preloaded, +/obj/effect/decal/warning_stripes/east, +/turf/simulated/floor/plasteel{ + dir = 8; + icon_state = "whitegreen" + }, +/area/medical/virology) +"dMx" = ( /obj/structure/cable{ d1 = 4; d2 = 8; @@ -89179,7 +89383,7 @@ icon_state = "whitegreen" }, /area/medical/virology) -"dMx" = ( +"dMy" = ( /obj/structure/disposalpipe/segment{ dir = 4; icon_state = "pipe-c" @@ -89206,26 +89410,6 @@ icon_state = "whitegreen" }, /area/medical/virology) -"dMy" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - tag = "" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 5 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 6 - }, -/turf/simulated/floor/plasteel{ - icon_state = "white" - }, -/area/medical/virology) "dMz" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -89241,12 +89425,6 @@ d2 = 4; icon_state = "1-4" }, -/obj/structure/cable{ - d1 = 2; - d2 = 4; - icon_state = "2-4"; - tag = "" - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, @@ -89259,22 +89437,13 @@ }, /area/medical/virology) "dMA" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; - tag = "" +/obj/item/storage/secure/safe{ + pixel_x = 32 }, -/obj/structure/table/glass, -/obj/item/clothing/gloves/color/latex, -/obj/item/healthanalyzer, -/obj/item/clothing/glasses/hud/health, -/obj/effect/decal/warning_stripes/southeastcorner, /turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "whitegreencorner" + icon_state = "grimy" }, -/area/medical/virology) +/area/security/detectives_office) "dMB" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -89361,19 +89530,17 @@ }, /area/medical/virology) "dMG" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + tag = "" + }, /obj/structure/table/glass, -/obj/item/folder/white, -/obj/item/pen/red, -/obj/item/stack/sheet/mineral/plasma{ - amount = 5 - }, -/obj/machinery/requests_console{ - department = "Virology"; - departmentType = 3; - name = "Virology Requests Console"; - pixel_y = 30 - }, -/obj/effect/decal/warning_stripes/south, +/obj/item/clothing/gloves/color/latex, +/obj/item/healthanalyzer, +/obj/item/clothing/glasses/hud/health, +/obj/effect/decal/warning_stripes/southeastcorner, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "whitegreencorner" @@ -89537,20 +89704,46 @@ }, /area/hallway/secondary/exit) "dNi" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; - tag = "" +/obj/structure/table/glass, +/obj/item/folder/white, +/obj/item/pen/red, +/obj/item/stack/sheet/mineral/plasma{ + amount = 5 }, +/obj/machinery/requests_console{ + department = "Virology"; + departmentType = 3; + name = "Virology Requests Console"; + pixel_y = 30 + }, +/obj/effect/decal/warning_stripes/south, /obj/machinery/computer/pandemic, -/obj/effect/decal/warning_stripes/southeast, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "whitegreencorner" }, /area/medical/virology) "dNj" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + tag = "" + }, +/obj/structure/table/glass, +/obj/item/reagent_containers/spray/cleaner, +/obj/item/reagent_containers/dropper, +/obj/machinery/alarm{ + dir = 4; + pixel_x = -24 + }, +/obj/effect/decal/warning_stripes/east, +/turf/simulated/floor/plasteel{ + dir = 8; + icon_state = "whitegreencorner" + }, +/area/medical/virology) +"dNk" = ( /obj/structure/chair/office/dark{ dir = 8 }, @@ -89562,7 +89755,7 @@ icon_state = "whitegreen" }, /area/medical/virology) -"dNk" = ( +"dNl" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable{ d1 = 1; @@ -89575,7 +89768,7 @@ icon_state = "whitegreen" }, /area/medical/virology) -"dNl" = ( +"dNm" = ( /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 1 }, @@ -89584,19 +89777,7 @@ icon_state = "whitegreen" }, /area/medical/virology) -"dNm" = ( -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "whitegreen" - }, -/area/medical/virology) "dNn" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; - tag = "" - }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "whitegreen" @@ -89609,8 +89790,7 @@ "dNs" = ( /obj/structure/sink{ dir = 8; - pixel_x = -12; - pixel_y = 2 + pixel_x = -12 }, /turf/simulated/floor/plasteel{ dir = 1; @@ -89806,6 +89986,19 @@ /turf/space, /area/space) "dNW" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + tag = "" + }, +/obj/effect/decal/warning_stripes/southeast, +/turf/simulated/floor/plasteel{ + dir = 1; + icon_state = "whitegreencorner" + }, +/area/medical/virology) +"dNX" = ( /obj/structure/filingcabinet/chestdrawer, /obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel{ @@ -89813,7 +90006,7 @@ icon_state = "whitegreen" }, /area/medical/virology) -"dNX" = ( +"dNY" = ( /obj/machinery/light{ dir = 1; on = 1 @@ -89834,19 +90027,6 @@ icon_state = "whitegreencorner" }, /area/medical/virology) -"dNY" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; - tag = "" - }, -/obj/effect/decal/warning_stripes/yellow/hollow, -/turf/simulated/floor/plasteel{ - dir = 4; - icon_state = "whitegreencorner" - }, -/area/medical/virology) "dNZ" = ( /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel{ @@ -89860,23 +90040,16 @@ }, /area/medical/surgery) "dOc" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; - tag = "" +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 }, -/obj/structure/table/glass, -/obj/structure/reagent_dispensers/virusfood{ - pixel_x = -32 +/obj/structure/window/reinforced/polarized, +/obj/effect/decal/warning_stripes/south, +/obj/machinery/computer/rdconsole/robotics{ + dir = 1 }, -/obj/machinery/reagentgrinder, -/obj/effect/decal/warning_stripes/east, -/turf/simulated/floor/plasteel{ - dir = 1; - icon_state = "whitegreencorner" - }, -/area/medical/virology) +/turf/simulated/floor/plasteel, +/area/assembly/robotics) "dOd" = ( /turf/simulated/floor/plasteel{ dir = 8; @@ -90151,6 +90324,16 @@ }, /area/hallway/secondary/exit) "dOD" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/r_n_d/circuit_imprinter, +/obj/item/reagent_containers/glass/beaker/sulphuric, +/obj/structure/window/reinforced/polarized, +/obj/effect/decal/warning_stripes/south, +/turf/simulated/floor/plasteel, +/area/assembly/robotics) +"dOE" = ( /obj/effect/spawner/window/reinforced, /obj/structure/cable{ d2 = 4; @@ -90164,26 +90347,21 @@ }, /turf/simulated/floor/plating, /area/medical/virology) -"dOE" = ( -/obj/effect/spawner/window/reinforced, -/obj/structure/cable, +"dOF" = ( /obj/structure/cable{ d1 = 1; d2 = 8; - icon_state = "1-8" + icon_state = "1-8"; + tag = "" }, -/turf/simulated/floor/plating, -/area/medical/virology) -"dOF" = ( -/obj/effect/spawner/window/reinforced, -/obj/structure/cable, /obj/structure/cable{ - d1 = 1; - d2 = 4; - icon_state = "1-4" + d1 = 2; + d2 = 8; + icon_state = "2-8" }, -/turf/simulated/floor/plating, -/area/medical/virology) +/obj/structure/lattice/catwalk, +/turf/space, +/area/maintenance/starboardsolar) "dOG" = ( /obj/machinery/light{ dir = 8 @@ -90216,8 +90394,7 @@ }, /obj/structure/sink{ dir = 8; - pixel_x = -12; - pixel_y = 2 + pixel_x = -12 }, /turf/simulated/floor/plasteel{ dir = 8; @@ -90447,9 +90624,9 @@ }, /area/medical/surgery2) "dPo" = ( +/mob/living/carbon/human/monkey, /obj/structure/bed/roller, /obj/effect/decal/warning_stripes/yellow/hollow, -/mob/living/carbon/human/monkey, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "whitegreencorner" @@ -90997,16 +91174,10 @@ }, /area/medical/surgery2) "dQv" = ( +/obj/effect/spawner/window/reinforced, /obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - tag = "" - }, -/obj/structure/cable{ - d1 = 1; d2 = 4; - icon_state = "1-4" + icon_state = "0-4" }, /obj/structure/cable{ d1 = 2; @@ -91014,12 +91185,7 @@ icon_state = "2-4"; tag = "" }, -/obj/machinery/smartfridge/secure/chemistry/virology/preloaded, -/obj/effect/decal/warning_stripes/east, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "whitegreen" - }, +/turf/simulated/floor/plating, /area/medical/virology) "dQw" = ( /obj/structure/disposalpipe/segment{ @@ -91122,11 +91288,11 @@ }, /area/hallway/secondary/exit) "dQG" = ( +/mob/living/carbon/human/monkey, /obj/effect/landmark{ name = "revenantspawn" }, /obj/effect/decal/warning_stripes/yellow, -/mob/living/carbon/human/monkey, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /turf/simulated/floor/plasteel{ @@ -91134,24 +91300,18 @@ }, /area/medical/virology) "dQH" = ( +/obj/effect/spawner/window/reinforced, /obj/structure/cable{ - d1 = 1; d2 = 2; - icon_state = "1-2"; + icon_state = "0-2" + }, +/obj/structure/cable{ + d1 = 2; + d2 = 4; + icon_state = "2-4"; tag = "" }, -/obj/structure/table/glass, -/obj/item/reagent_containers/spray/cleaner, -/obj/item/reagent_containers/dropper, -/obj/machinery/alarm{ - dir = 4; - pixel_x = -24 - }, -/obj/effect/decal/warning_stripes/east, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "whitegreencorner" - }, +/turf/simulated/floor/plating, /area/medical/virology) "dQI" = ( /obj/effect/decal/warning_stripes/north, @@ -91218,7 +91378,7 @@ pixel_y = -25 }, /obj/effect/decal/warning_stripes/yellow, -/turf/simulated/floor/plasteel, +/turf/simulated/floor/plating, /area/maintenance/portsolar) "dQM" = ( /obj/structure/cable{ @@ -91407,6 +91567,16 @@ /turf/simulated/floor/plasteel, /area/maintenance/portsolar) "dRf" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/plasteel{ + icon_state = "whitegreen" + }, +/area/medical/virology) +"dRg" = ( /obj/structure/cable{ d1 = 1; d2 = 2; @@ -91422,7 +91592,7 @@ icon_state = "whitegreencorner" }, /area/medical/virology) -"dRg" = ( +"dRh" = ( /obj/structure/table/glass, /obj/structure/sign/deathsposal{ pixel_y = -32 @@ -91434,7 +91604,7 @@ icon_state = "whitegreencorner" }, /area/medical/virology) -"dRh" = ( +"dRi" = ( /obj/machinery/disposal, /obj/structure/disposalpipe/trunk{ dir = 1 @@ -91451,13 +91621,6 @@ icon_state = "whitegreencorner" }, /area/medical/virology) -"dRi" = ( -/obj/item/twohanded/required/kirbyplants, -/obj/effect/decal/warning_stripes/yellow/hollow, -/turf/simulated/floor/plasteel{ - icon_state = "whitegreen" - }, -/area/medical/virology) "dRj" = ( /obj/effect/decal/warning_stripes/north, /turf/simulated/floor/plasteel, @@ -91502,11 +91665,12 @@ /area/hallway/secondary/exit) "dRo" = ( /obj/structure/cable, +/obj/effect/decal/warning_stripes/southwest, /obj/machinery/power/solar_control{ + dir = 4; id = "portsolar"; name = "Aft Port Solar Control" }, -/obj/effect/decal/warning_stripes/southwest, /turf/simulated/floor/plating, /area/maintenance/portsolar) "dRp" = ( @@ -92359,11 +92523,7 @@ }, /area/chapel/office) "dTu" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, +/obj/machinery/atmospherics/unary/vent_scrubber/on, /turf/simulated/floor/plasteel{ icon_state = "whitegreen" }, @@ -92378,20 +92538,14 @@ icon_state = "4-8"; tag = "" }, -/obj/structure/cable{ - d1 = 1; - d2 = 4; - icon_state = "1-4" - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 + dir = 5 }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 + dir = 6 }, /turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "whitegreen" + icon_state = "white" }, /area/medical/virology) "dTw" = ( @@ -93532,22 +93686,15 @@ /area/hallway/primary/central) "dWS" = ( /obj/item/twohanded/required/kirbyplants, -/obj/machinery/light, -/obj/machinery/status_display{ - pixel_y = -32 - }, /obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel{ - dir = 5; - icon_state = "whitegreencorner" + icon_state = "whitegreen" }, /area/medical/virology) "dWT" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; - tag = "" +/obj/machinery/light, +/obj/machinery/status_display{ + pixel_y = -32 }, /obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel{ @@ -93804,8 +93951,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 9 }, -/obj/effect/decal/warning_stripes/east, -/obj/item/twohanded/required/kirbyplants, +/obj/effect/decal/warning_stripes/southeast, +/obj/structure/filingcabinet/chestdrawer, +/obj/structure/window/reinforced/polarized, /turf/simulated/floor/plasteel, /area/assembly/robotics) "dXs" = ( @@ -94280,9 +94428,9 @@ /turf/simulated/floor/plasteel, /area/medical/research) "dYE" = ( +/mob/living/carbon/human/monkey, /obj/structure/bed/roller, /obj/effect/decal/warning_stripes/yellow/hollow, -/mob/living/carbon/human/monkey, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "whitegreencorner" @@ -94985,7 +95133,7 @@ /turf/simulated/floor/plasteel{ icon_state = "white" }, -/area/maintenance/starboard) +/area/hallway/primary/central) "fhF" = ( /turf/space, /area/shuttle/gamma/station) @@ -95581,11 +95729,8 @@ }, /area/security/seceqstorage) "hbU" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; - tag = "" +/obj/structure/chair/office/dark{ + dir = 1 }, /turf/simulated/floor/plasteel{ icon_state = "whitegreen" @@ -95705,7 +95850,7 @@ /turf/simulated/floor/plasteel{ icon_state = "white" }, -/area/maintenance/starboard) +/area/hallway/primary/central) "hzb" = ( /obj/machinery/light{ dir = 4 @@ -95715,6 +95860,20 @@ icon_state = "redcorner" }, /area/security/permasolitary) +"hzl" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/turf/simulated/floor/plasteel{ + icon_state = "dark" + }, +/area/turret_protected/aisat) "hAi" = ( /obj/machinery/vending/scidrobe, /turf/simulated/floor/plasteel{ @@ -95788,18 +95947,31 @@ }, /area/medical/surgery1) "hMu" = ( -/obj/machinery/power/solar{ - name = "Aft Starboard Solar Panel" - }, +/obj/effect/spawner/window/reinforced, +/obj/structure/cable, /obj/structure/cable{ - d2 = 2; - icon_state = "0-2" + d1 = 1; + d2 = 8; + icon_state = "1-8" }, -/turf/space, -/area/maintenance/starboardsolar) +/turf/simulated/floor/plating, +/area/medical/virology) "hOL" = ( /turf/simulated/floor/carpet, /area/magistrateoffice) +"hPT" = ( +/obj/machinery/door/airlock/atmos/glass{ + heat_proof = 1; + name = "Supermatter Chamber"; + req_one_access_txt = "24; 10" + }, +/obj/structure/cable/yellow{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/engine, +/area/engine/supermatter) "hTk" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/structure/rack, @@ -95976,10 +96148,10 @@ pixel_y = 25 }, /obj/structure/table/wood, -/obj/machinery/computer/secure_data/laptop, /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/machinery/computer/secure_data/laptop, /turf/simulated/floor/plasteel{ icon_state = "cult" }, @@ -96114,7 +96286,7 @@ dir = 1; icon_state = "whitebluecorner" }, -/area/maintenance/starboard) +/area/hallway/primary/central) "iXX" = ( /obj/structure/cable{ d1 = 1; @@ -96235,7 +96407,7 @@ /turf/simulated/floor/plasteel{ icon_state = "white" }, -/area/maintenance/starboard) +/area/hallway/primary/central) "jsV" = ( /obj/structure/cable{ d1 = 4; @@ -96360,7 +96532,7 @@ dir = 4; icon_state = "whitebluecorner" }, -/area/maintenance/starboard) +/area/hallway/primary/central) "jLB" = ( /obj/effect/spawner/window/reinforced, /obj/structure/disposalpipe/segment{ @@ -96443,11 +96615,8 @@ pixel_x = -24 }, /obj/item/ammo_box/shotgun/rubbershot, -/obj/item/ammo_box/shotgun/buck, /obj/item/storage/box/rubbershot, /obj/item/storage/box/rubbershot, -/obj/item/storage/box/buck, -/obj/item/storage/box/buck, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "vault" @@ -96480,7 +96649,7 @@ dir = 4; icon_state = "whitebluecorner" }, -/area/maintenance/starboard) +/area/hallway/primary/central) "klk" = ( /obj/machinery/firealarm{ dir = 1; @@ -97421,7 +97590,9 @@ d2 = 8; icon_state = "4-8" }, -/obj/machinery/computer/security, +/obj/machinery/computer/security{ + dir = 8 + }, /turf/simulated/floor/plasteel{ icon_state = "redfull" }, @@ -97474,13 +97645,13 @@ }, /area/security/prisonershuttle) "nFL" = ( -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_y = 32 - }, /obj/machinery/light/small{ dir = 1 }, /obj/machinery/smartfridge/drying_rack, +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_y = 32 + }, /turf/simulated/floor/plating, /area/security/permabrig) "nFN" = ( @@ -97495,12 +97666,15 @@ /turf/simulated/floor/plating, /area/civilian/barber) "nGA" = ( -/obj/machinery/power/solar{ - name = "Aft Starboard Solar Panel" - }, +/obj/effect/spawner/window/reinforced, /obj/structure/cable, -/turf/space, -/area/maintenance/starboardsolar) +/obj/structure/cable{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/turf/simulated/floor/plating, +/area/medical/virology) "nGL" = ( /obj/machinery/bodyscanner{ dir = 4 @@ -97748,9 +97922,6 @@ /area/space/nearstation) "oHv" = ( /obj/structure/table/reinforced, -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_x = 32 - }, /turf/simulated/floor/plasteel{ icon_state = "barber" }, @@ -97949,7 +98120,7 @@ dir = 1; icon_state = "whitebluecorner" }, -/area/maintenance/starboard) +/area/hallway/primary/central) "pGr" = ( /obj/structure/cable{ d1 = 1; @@ -98277,6 +98448,15 @@ /obj/effect/spawner/window/reinforced/plasma, /turf/simulated/floor/plating, /area/toxins/mixing) +"qWs" = ( +/obj/machinery/computer/arcade{ + dir = 1 + }, +/turf/simulated/floor/plasteel{ + dir = 5; + icon_state = "dark" + }, +/area/maintenance/fore2) "qXF" = ( /obj/machinery/alarm{ pixel_y = 24 @@ -98516,7 +98696,7 @@ dir = 1; icon_state = "whitebluecorner" }, -/area/maintenance/starboard) +/area/hallway/primary/central) "rIy" = ( /obj/machinery/door/airlock/research{ name = "Research Break Room" @@ -98668,7 +98848,6 @@ /area/security/permabrig) "sak" = ( /obj/structure/table/wood, -/obj/machinery/computer/med_data/laptop, /turf/simulated/floor/wood, /area/medical/psych) "scA" = ( @@ -98682,6 +98861,14 @@ icon_state = "red" }, /area/hallway/secondary/exit) +"sdP" = ( +/obj/structure/cable/yellow{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/turf/simulated/floor/engine, +/area/engine/supermatter) "shi" = ( /obj/structure/cable{ d2 = 2; @@ -98721,12 +98908,14 @@ }, /area/medical/research) "soN" = ( -/obj/machinery/computer/operating, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 9 }, /obj/structure/disposalpipe/segment, +/obj/machinery/computer/operating{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "darkblue" @@ -98857,15 +99046,16 @@ /area/toxins/mixing) "sPS" = ( /obj/structure/cable, -/obj/machinery/power/solar_control{ - id = "starboardsolar"; - name = "Aft Starboard Solar Control" - }, /obj/machinery/alarm{ dir = 1; pixel_y = -24 }, /obj/effect/decal/warning_stripes/southeast, +/obj/machinery/power/solar_control{ + dir = 8; + id = "starboardsolar"; + name = "Aft Starboard Solar Control" + }, /turf/simulated/floor/plating, /area/maintenance/starboardsolar) "sTz" = ( @@ -99143,7 +99333,7 @@ dir = 4; icon_state = "whitebluecorner" }, -/area/maintenance/starboard) +/area/hallway/primary/central) "tNO" = ( /obj/structure/cable{ d1 = 2; @@ -99570,15 +99760,15 @@ d2 = 8; icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /obj/machinery/computer/security/telescreen{ desc = "Used for watching interrogations."; name = "Interrogation Monitor"; network = list("Interrogation"); pixel_y = -30 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -100137,14 +100327,14 @@ }, /area/medical/research) "xom" = ( +/mob/living/simple_animal/bot/secbot/armsky{ + auto_patrol = 1 + }, /obj/effect/decal/warning_stripes/north, /obj/machinery/navbeacon{ codes_txt = "patrol;next_patrol=Armory_South"; location = "Armory_North" }, -/mob/living/simple_animal/bot/secbot/armsky{ - auto_patrol = 1 - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 6 }, @@ -100206,7 +100396,7 @@ "xwk" = ( /obj/structure/sink{ dir = 4; - pixel_x = 11 + pixel_x = 12 }, /turf/simulated/floor/plasteel{ icon_state = "showroomfloor" @@ -108010,7 +108200,7 @@ btd bNM bPP bUD -bTL +hzl bXI chE bNM @@ -121329,7 +121519,7 @@ abj ash atL atY -abj +dKA dij abj abj @@ -126984,8 +127174,8 @@ aAa aBX aAa aCZ -aAa -aCZ +sdP +hPT aFX aGi aIH @@ -128067,8 +128257,8 @@ bXU bQr bQr clv -cop -cqP +cnb +cnb buB cso cuR @@ -128916,7 +129106,7 @@ aaa aaa abj aaa -aaa +dKz dTV dYP dVn @@ -138647,7 +138837,7 @@ dqm dsL dvl dui -dvn +dOc dvp dam dFw @@ -138904,8 +139094,8 @@ dsH due dvm dws -dvn -dyT +dOD +dav dav dyR dzY @@ -143680,7 +143870,7 @@ arW asJ aKd aux -arW +qWs axm axu ayD @@ -144447,7 +144637,7 @@ apo apw aqp arf -arW +bPq auu atP axf @@ -144965,7 +145155,7 @@ auu asM atR asK -arW +qWs ayS osS wXI @@ -145303,7 +145493,7 @@ rHU cGF iWE pDD -bng +cYP cYP cYP cPO @@ -145952,7 +146142,7 @@ dij abj dij dij -aaa +dKz aaa abj aaa @@ -146887,13 +147077,13 @@ dFG dFG dFG aaa -dKz -dIc -dFG -dFI -dFG -dFH -dOD +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -147144,12 +147334,12 @@ dLd dLY dIW abj -dFJ -dMA -dOc dQv -dQH -dRf +dIc +dFG +dFI +dFG +dFH dOE abj aaa @@ -147401,13 +147591,13 @@ dLQ dMa dFG aaa -dFG +dFJ dMG dLR dMw dNj dRg -dFG +hMu abj aaa aaa @@ -147658,13 +147848,13 @@ dLU dMv dIX abj -dKA +dFG dNi hbU dMx dNk dRh -dOF +dFG aaa aaa aaa @@ -147915,13 +148105,13 @@ dHa dFG dFG aaa -dKB +dQH dNW deV dMy dNl dRi -dKB +nGA aaa aaa aaa @@ -148172,13 +148362,13 @@ dHb dFG aaa aaa -dFG +dKB dNX dTu dTv dNm dWS -dFG +dKB abj aaa aaa @@ -148429,13 +148619,13 @@ dHc dIc abj abj -dFH +dFG dNY -hbU +dRf dMz dNn dWT -dIc +dFG aaa aaa aaa @@ -149124,10 +149314,10 @@ aaa aaa bFS bHP -dDN +dMA bLu bNu -bPq +bLt bFS bTh bVn @@ -149548,7 +149738,7 @@ aaa dij aaa kYo -acj +dyT aco aaa kYo @@ -149556,7 +149746,7 @@ acj aco aaa kYo -acj +dyT aco aaa abj @@ -149809,13 +149999,13 @@ abj aaa aaa kYo -acj +dyT aco aaa aaa abj aaa -aaa +dKz dij aaa aaa @@ -156385,9 +156575,9 @@ aaa abj aaa aaa -hMu -daC -nGA +dak +daz +dbc aaa aaa abj @@ -156647,7 +156837,7 @@ daC dbc aaa dak -daC +daz dbc aaa abj @@ -158445,7 +158635,7 @@ abj cTN abj abj -abj +dKA daG abj aaa @@ -159723,7 +159913,7 @@ aaa dij aaa dak -daT +dOF dbc aaa dak @@ -159731,7 +159921,7 @@ daT dbc aaa dak -daT +dOF dbc aaa dij @@ -159984,7 +160174,7 @@ aaa aaa aaa dak -daT +dOF dbc aaa aaa diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index b52b9d95c79..24ae1527d2e 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -2427,15 +2427,7 @@ /area/maintenance/auxsolarport) "agY" = ( /obj/structure/rack, -/obj/item/storage/box/buck{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/storage/box/buck, -/obj/item/storage/box/buck{ - pixel_x = 3; - pixel_y = -3 - }, +/obj/item/storage/box/tranquilizer, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "vault" @@ -2465,12 +2457,12 @@ }, /area/security/hos) "ahc" = ( -/obj/machinery/computer/secure_data, /obj/structure/cable/yellow{ d1 = 1; d2 = 2; icon_state = "1-2" }, +/obj/machinery/computer/secure_data, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -2481,12 +2473,6 @@ d2 = 8; icon_state = "4-8" }, -/obj/machinery/computer/security/telescreen{ - desc = "Used for watching Prison Wing holding areas."; - name = "Prison Monitor"; - network = list("Prison"); - pixel_y = 30 - }, /obj/machinery/camera{ c_tag = "Prison Hallway Port"; network = list("SS13","Prison") @@ -2502,6 +2488,12 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/machinery/computer/security/telescreen{ + desc = "Used for watching Prison Wing holding areas."; + name = "Prison Monitor"; + network = list("Prison"); + pixel_y = 30 + }, /turf/simulated/floor/plasteel{ icon_state = "redcorner" }, @@ -2591,12 +2583,6 @@ d2 = 8; icon_state = "4-8" }, -/obj/machinery/computer/security/telescreen{ - desc = "Used for watching Prison Wing holding areas."; - name = "Prison Monitor"; - network = list("Prison"); - pixel_y = 30 - }, /obj/structure/cable/yellow{ d1 = 2; d2 = 4; @@ -2608,6 +2594,12 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/machinery/computer/security/telescreen{ + desc = "Used for watching Prison Wing holding areas."; + name = "Prison Monitor"; + network = list("Prison"); + pixel_y = 30 + }, /turf/simulated/floor/plasteel{ icon_state = "redcorner" }, @@ -3642,7 +3634,9 @@ name = "\improper Arcade" }) "ajm" = ( -/obj/machinery/computer/arcade/battle, +/obj/machinery/computer/arcade/battle{ + dir = 4 + }, /turf/simulated/floor/carpet/arcade, /area/crew_quarters/fitness{ name = "\improper Arcade" @@ -3723,6 +3717,10 @@ pixel_x = -24; pixel_y = -20 }, +/obj/machinery/disposal, +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, /obj/machinery/computer/security/telescreen{ desc = "Used for watching certain areas."; dir = 1; @@ -3730,10 +3728,6 @@ network = list("Prison","MiniSat","tcomm"); pixel_y = -30 }, -/obj/machinery/disposal, -/obj/structure/disposalpipe/trunk{ - dir = 4 - }, /turf/simulated/floor/plasteel{ icon_state = "vault" }, @@ -3780,14 +3774,14 @@ /turf/simulated/wall/r_wall, /area/maintenance/auxsolarport) "ajC" = ( -/obj/machinery/power/solar_control{ - id = "foreport"; - name = "Fore Port Solar Control" - }, /obj/structure/cable{ d2 = 4; icon_state = "0-4" }, +/obj/machinery/power/solar_control{ + id = "foreport"; + name = "Fore Port Solar Control" + }, /turf/simulated/floor/plating, /area/maintenance/auxsolarport) "ajD" = ( @@ -4258,10 +4252,10 @@ d2 = 8; icon_state = "4-8" }, -/mob/living/simple_animal/hostile/retaliate/araneus, /obj/structure/disposalpipe/segment{ dir = 4 }, +/mob/living/simple_animal/hostile/retaliate/araneus, /turf/simulated/floor/carpet, /area/security/hos) "akC" = ( @@ -5113,7 +5107,9 @@ name = "\improper Recreation Area" }) "ami" = ( -/obj/machinery/computer/HolodeckControl, +/obj/machinery/computer/HolodeckControl{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/crew_quarters/fitness{ name = "\improper Recreation Area" @@ -5424,12 +5420,12 @@ /turf/simulated/floor/plating, /area/security/brig) "amM" = ( -/obj/machinery/computer/secure_data, /obj/structure/cable/yellow{ d1 = 1; d2 = 2; icon_state = "1-2" }, +/obj/machinery/computer/secure_data, /turf/simulated/floor/plasteel{ icon_state = "vault" }, @@ -6900,15 +6896,15 @@ d2 = 8; icon_state = "4-8" }, -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_y = -32 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_y = -32 + }, /turf/simulated/floor/plasteel{ icon_state = "red" }, @@ -8166,14 +8162,14 @@ /turf/simulated/wall, /area/maintenance/auxsolarstarboard) "asU" = ( -/obj/machinery/power/solar_control{ - id = "forestarboard"; - name = "Fore Starboard Solar Control" - }, /obj/structure/cable{ d2 = 4; icon_state = "0-4" }, +/obj/machinery/power/solar_control{ + id = "forestarboard"; + name = "Fore Starboard Solar Control" + }, /turf/simulated/floor/plating, /area/maintenance/auxsolarstarboard) "asV" = ( @@ -8189,13 +8185,6 @@ }, /area/security/brig) "asW" = ( -/obj/machinery/computer/security/telescreen{ - desc = "Used for watching Prison Wing holding areas."; - dir = 1; - name = "Prison Monitor"; - network = list("Prison"); - pixel_x = 30 - }, /obj/structure/cable/yellow{ d1 = 1; d2 = 2; @@ -8205,6 +8194,13 @@ dir = 8 }, /obj/machinery/vending/security, +/obj/machinery/computer/security/telescreen{ + desc = "Used for watching Prison Wing holding areas."; + dir = 1; + name = "Prison Monitor"; + network = list("Prison"); + pixel_x = 30 + }, /turf/simulated/floor/plasteel{ icon_state = "showroomfloor" }, @@ -8961,6 +8957,7 @@ /area/maintenance/fore) "auM" = ( /obj/machinery/computer/security{ + dir = 4; name = "Labor Camp Monitoring"; network = list("Labor") }, @@ -9161,9 +9158,6 @@ }, /area/security/brig) "avd" = ( -/obj/machinery/computer/security{ - network = list("SS13","Research Outpost","Mining Outpost") - }, /obj/structure/cable/yellow{ d1 = 4; d2 = 8; @@ -9174,6 +9168,10 @@ d2 = 4; icon_state = "2-4" }, +/obj/machinery/computer/security{ + dir = 4; + network = list("SS13","Research Outpost","Mining Outpost") + }, /turf/simulated/floor/plasteel{ icon_state = "showroomfloor" }, @@ -9592,10 +9590,10 @@ name = "Port Maintenance" }) "avY" = ( -/mob/living/simple_animal/mouse, /obj/structure/disposalpipe/segment{ dir = 4 }, +/mob/living/simple_animal/mouse, /turf/simulated/floor/plating, /area/maintenance/fpmaint2{ name = "Port Maintenance" @@ -9677,10 +9675,12 @@ c_tag = "Labor Shuttle Control Desk"; dir = 4 }, -/obj/machinery/computer/shuttle/labor, /obj/machinery/light{ dir = 8 }, +/obj/machinery/computer/shuttle/labor{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -9917,7 +9917,9 @@ }, /area/security/main) "awH" = ( -/obj/machinery/computer/secure_data, +/obj/machinery/computer/secure_data{ + dir = 4 + }, /obj/machinery/computer/security/telescreen{ desc = "Used for watching Prison Wing holding areas."; dir = 1; @@ -10480,7 +10482,9 @@ }, /area/security/main) "axG" = ( -/obj/machinery/computer/prisoner, +/obj/machinery/computer/prisoner{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -10845,7 +10849,9 @@ d2 = 8; icon_state = "4-8" }, -/obj/machinery/computer/prisoner, +/obj/machinery/computer/prisoner{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "showroomfloor" }, @@ -11353,12 +11359,12 @@ name = "Port Maintenance" }) "azC" = ( -/obj/machinery/computer/cryopod{ - pixel_y = -25 - }, /obj/effect/landmark{ name = "JoinLateCryo" }, +/obj/machinery/computer/cryopod{ + pixel_y = -25 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -11992,15 +11998,15 @@ }, /area/security/brig) "aAO" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 4 + }, /obj/machinery/computer/security/telescreen{ dir = 4; name = "MiniSat Monitor"; network = list("MiniSat","tcomm"); pixel_x = -29 }, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 4 - }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "yellow" @@ -13074,7 +13080,9 @@ /area/maintenance/starboard) "aDg" = ( /obj/structure/table, -/obj/machinery/computer/crew, +/obj/machinery/computer/crew{ + dir = 8 + }, /turf/simulated/floor/plasteel{ icon_state = "showroomfloor" }, @@ -14221,7 +14229,9 @@ dir = 8; pixel_x = 24 }, -/obj/machinery/computer/secure_data, +/obj/machinery/computer/secure_data{ + dir = 8 + }, /turf/simulated/floor/carpet, /area/security/detectives_office) "aFy" = ( @@ -14308,12 +14318,12 @@ }, /area/crew_quarters/sleep) "aFH" = ( +/obj/structure/table/wood, /obj/machinery/computer/security/wooden_tv{ density = 0; pixel_x = 3; pixel_y = 2 }, -/obj/structure/table/wood, /obj/machinery/computer/security/telescreen{ desc = "Used for watching Prison Wing holding areas."; name = "Prison Monitor"; @@ -14785,10 +14795,12 @@ /turf/simulated/floor/carpet, /area/security/detectives_office) "aGH" = ( -/obj/machinery/computer/med_data, /obj/machinery/newscaster{ pixel_x = 28 }, +/obj/machinery/computer/med_data{ + dir = 8 + }, /turf/simulated/floor/carpet, /area/security/detectives_office) "aGI" = ( @@ -14920,10 +14932,10 @@ /turf/simulated/floor/plating, /area/maintenance/starboard) "aGX" = ( +/obj/machinery/suit_storage_unit/ce/secure, /obj/machinery/computer/security/telescreen/entertainment{ pixel_y = -29 }, -/obj/machinery/suit_storage_unit/ce/secure, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "vault" @@ -15062,7 +15074,9 @@ /obj/machinery/light{ dir = 8 }, -/obj/machinery/computer/shuttle/mining, +/obj/machinery/computer/shuttle/mining{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 9; icon_state = "brown" @@ -15287,7 +15301,6 @@ name = "Storage Wing" }) "aHS" = ( -/obj/machinery/computer/secure_data, /obj/machinery/flasher_button{ id = "secentranceflasher"; name = "Brig Entrance Flash Control"; @@ -15329,6 +15342,7 @@ pixel_y = 27; req_access_txt = "63" }, +/obj/machinery/computer/secure_data, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -15771,7 +15785,9 @@ name = "Port Maintenance" }) "aIN" = ( -/obj/machinery/computer/security/mining, +/obj/machinery/computer/security/mining{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/quartermaster/miningdock{ name = "\improper Mining Office" @@ -17371,13 +17387,13 @@ }) "aMc" = ( /obj/effect/decal/cleanable/dirt, -/mob/living/simple_animal/mouse, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/mob/living/simple_animal/mouse, /turf/simulated/floor/plating, /area/maintenance/fore) "aMd" = ( @@ -18359,12 +18375,12 @@ /turf/simulated/floor/engine, /area/engine/engineering) "aOb" = ( -/obj/machinery/computer/security{ - network = list("SS13","Research Outpost","Mining Outpost") - }, /obj/machinery/newscaster/security_unit{ pixel_y = -30 }, +/obj/machinery/computer/security{ + network = list("SS13","Research Outpost","Mining Outpost") + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -18431,6 +18447,10 @@ pixel_x = -4; pixel_y = 2 }, +/obj/item/restraints/handcuffs, +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, /obj/machinery/computer/security/telescreen{ desc = "Used for watching Prison Wing holding areas."; dir = 1; @@ -18438,10 +18458,6 @@ network = list("Prison"); pixel_y = -30 }, -/obj/item/restraints/handcuffs, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 1 - }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -19024,8 +19040,8 @@ }) "aPK" = ( /obj/structure/table, -/obj/machinery/computer/guestpass, /obj/effect/decal/warning_stripes/yellow, +/obj/machinery/computer/guestpass, /turf/simulated/floor/plasteel, /area/engine/engineering) "aPL" = ( @@ -19889,11 +19905,11 @@ }, /area/security/brig) "aRQ" = ( -/mob/living/simple_animal/mouse, /obj/machinery/atmospherics/binary/valve, /obj/structure/disposalpipe/segment{ dir = 4 }, +/mob/living/simple_animal/mouse, /turf/simulated/floor/plasteel{ icon_state = "floorgrime" }, @@ -19945,14 +19961,14 @@ /obj/structure/table/wood, /obj/item/book/manual/security_space_law, /obj/item/book/manual/security_space_law, +/obj/item/cartridge/lawyer, +/obj/item/pen/multi, /obj/machinery/computer/security/telescreen{ desc = "Used for watching Prison Wing holding areas."; name = "Prison Monitor"; network = list("Prison"); pixel_y = 30 }, -/obj/item/cartridge/lawyer, -/obj/item/pen/multi, /turf/simulated/floor/wood, /area/lawoffice) "aRX" = ( @@ -20144,7 +20160,9 @@ }) "aSC" = ( /obj/effect/decal/warning_stripes/yellow, -/obj/machinery/computer/sm_monitor, +/obj/machinery/computer/sm_monitor{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/engine/engineering) "aSD" = ( @@ -20193,8 +20211,10 @@ pixel_x = -27; pixel_y = 5 }, -/obj/machinery/computer/supplycomp, /obj/effect/decal/warning_stripes/yellow/hollow, +/obj/machinery/computer/supplycomp{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/quartermaster/storage) "aSH" = ( @@ -20314,7 +20334,6 @@ }, /area/turret_protected/ai_upload) "aSV" = ( -/obj/machinery/computer/borgupload, /obj/structure/window/reinforced{ dir = 1 }, @@ -20330,6 +20349,7 @@ name = "Cyborg Upload Console Window"; req_access_txt = "16" }, +/obj/machinery/computer/borgupload, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -20341,7 +20361,6 @@ }, /area/turret_protected/ai_upload) "aSX" = ( -/obj/machinery/computer/aiupload, /obj/structure/window/reinforced{ dir = 1 }, @@ -20359,6 +20378,7 @@ name = "Upload Console Window"; req_access_txt = "16" }, +/obj/machinery/computer/aiupload, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -21201,12 +21221,12 @@ /turf/simulated/floor/plating, /area/engine/engineering) "aUL" = ( -/obj/machinery/computer/station_alert, /obj/structure/sign/double/map/right{ desc = "A framed picture of the station. Clockwise from security at the top (red), you see engineering (yellow), science (purple), escape (red and white), medbay (green), arrivals (blue and white), and finally cargo (brown)."; icon_state = "map-right-MS"; pixel_y = 32 }, +/obj/machinery/computer/station_alert, /turf/simulated/floor/plasteel{ icon_state = "vault" }, @@ -22133,7 +22153,6 @@ /turf/simulated/floor/plasteel, /area/quartermaster/storage) "aWN" = ( -/obj/machinery/computer/atmos_alert, /obj/structure/sign/double/map/left{ desc = "A framed picture of the station. Clockwise from security at the top (red), you see engineering (yellow), science (purple), escape (red and white), medbay (green), arrivals (blue and white), and finally cargo (brown)."; icon_state = "map-left-MS"; @@ -22143,15 +22162,18 @@ dir = 8; pixel_x = -26 }, +/obj/machinery/computer/atmos_alert, /turf/simulated/floor/plasteel{ icon_state = "vault" }, /area/engine/engineering) "aWO" = ( -/obj/machinery/computer/supplycomp, /obj/machinery/light_switch{ pixel_x = -23 }, +/obj/machinery/computer/supplycomp{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 10; icon_state = "brown" @@ -22244,9 +22266,6 @@ d2 = 4; icon_state = "0-4" }, -/obj/machinery/computer/monitor{ - name = "Engineering Power Monitoring Console" - }, /obj/machinery/status_display{ layer = 4; pixel_y = 32 @@ -22254,6 +22273,9 @@ /obj/machinery/camera{ c_tag = "Engineering - Power Monitoring" }, +/obj/machinery/computer/monitor{ + name = "Engineering Power Monitoring Console" + }, /turf/simulated/floor/plasteel{ icon_state = "vault" }, @@ -22388,7 +22410,9 @@ /turf/simulated/floor/engine, /area/engine/engineering) "aXt" = ( -/obj/machinery/computer/security/mining, +/obj/machinery/computer/security/mining{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "brown" @@ -24668,13 +24692,6 @@ /obj/machinery/light/small{ dir = 4 }, -/obj/machinery/computer/security/telescreen{ - desc = "Used for watching areas on the MiniSat."; - dir = 8; - name = "MiniSat Monitor"; - network = list("MiniSat","tcomm"); - pixel_x = 29 - }, /obj/machinery/camera/motion{ c_tag = "AI Upload Foyer"; network = list("SS13","RD","AIUpload") @@ -24682,6 +24699,13 @@ /obj/machinery/alarm{ pixel_y = 24 }, +/obj/machinery/computer/security/telescreen{ + desc = "Used for watching areas on the MiniSat."; + dir = 8; + name = "MiniSat Monitor"; + network = list("MiniSat","tcomm"); + pixel_x = 29 + }, /turf/simulated/floor/plasteel{ dir = 10; icon_state = "vault" @@ -26062,7 +26086,9 @@ network = list("Singulo"); pixel_x = 32 }, -/obj/machinery/computer/drone_control, +/obj/machinery/computer/drone_control{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "yellow" @@ -27483,7 +27509,6 @@ name = "Customs" }) "biy" = ( -/obj/machinery/computer/card, /obj/machinery/light{ dir = 1 }, @@ -27495,6 +27520,7 @@ /obj/machinery/camera{ c_tag = "Customs Checkpoint" }, +/obj/machinery/computer/card, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "red" @@ -27631,7 +27657,9 @@ /turf/simulated/floor/carpet, /area/crew_quarters/theatre) "biN" = ( -/obj/machinery/computer/supplycomp, +/obj/machinery/computer/supplycomp{ + dir = 1 + }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "brown" @@ -28082,6 +28110,8 @@ /obj/machinery/light{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, /obj/machinery/computer/security/telescreen{ desc = "A telescreen that connects to the engine's camera network."; dir = 8; @@ -28090,8 +28120,6 @@ network = list("engine"); pixel_x = 30 }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "vault" @@ -28122,8 +28150,8 @@ }, /area/engine/chiefs_office) "bjJ" = ( -/obj/machinery/computer/supplycomp/public, /obj/effect/decal/warning_stripes/yellow, +/obj/machinery/computer/supplycomp/public, /turf/simulated/floor/plasteel{ dir = 9; icon_state = "brown" @@ -29746,10 +29774,10 @@ /turf/simulated/floor/plating, /area/maintenance/starboard) "bmS" = ( -/obj/machinery/computer/secure_data, /obj/machinery/newscaster/security_unit{ pixel_y = 30 }, +/obj/machinery/computer/secure_data, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "red" @@ -30640,12 +30668,12 @@ name = "Station Intercom (General)"; pixel_x = -27 }, -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_y = 32 - }, /obj/item/paper/safe_code{ owner = "captain" }, +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_y = 32 + }, /turf/simulated/floor/carpet, /area/crew_quarters/captain{ name = "\improper Captain's Quarters" @@ -32401,7 +32429,9 @@ }, /area/bridge) "bsi" = ( -/obj/machinery/computer/merch, +/obj/machinery/computer/merch{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 10; icon_state = "brown" @@ -33254,19 +33284,19 @@ }, /area/bridge) "btV" = ( -/obj/machinery/computer/communications, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/computer/communications, /turf/simulated/floor/plasteel{ icon_state = "dark" }, /area/bridge) "btW" = ( +/obj/structure/table/glass, /obj/machinery/computer/security/wooden_tv{ pixel_x = 1; pixel_y = 6 }, -/obj/structure/table/glass, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -33292,10 +33322,10 @@ name = "Station Intercom (General)"; pixel_y = 29 }, -/obj/machinery/computer/teleporter, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 6 }, +/obj/machinery/computer/teleporter, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -33414,7 +33444,6 @@ name = "\improper Captain's Quarters" }) "buh" = ( -/obj/machinery/computer/communications, /obj/item/radio/intercom{ dir = 8; name = "Station Intercom (Captain)"; @@ -33427,6 +33456,9 @@ pixel_x = 24; pixel_y = 24 }, +/obj/machinery/computer/communications{ + dir = 8 + }, /turf/simulated/floor/wood, /area/crew_quarters/captain{ name = "\improper Captain's Quarters" @@ -33479,13 +33511,13 @@ d2 = 4; icon_state = "2-4" }, -/obj/machinery/computer/security/mining, /obj/machinery/keycard_auth{ pixel_y = 24 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 10 }, +/obj/machinery/computer/security/mining, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -34588,7 +34620,9 @@ /obj/machinery/newscaster/security_unit{ pixel_x = 32 }, -/obj/machinery/computer/security/mining, +/obj/machinery/computer/security/mining{ + dir = 8 + }, /turf/simulated/floor/wood, /area/crew_quarters/heads) "bwd" = ( @@ -35655,14 +35689,14 @@ }, /area/hallway/primary/port) "bye" = ( +/obj/structure/bed/dogbed/ian, +/mob/living/simple_animal/pet/dog/corgi/Ian, /obj/machinery/computer/security/telescreen{ desc = "Used for watching Prison Wing holding areas."; name = "Prison Monitor"; network = list("Prison"); pixel_y = 30 }, -/obj/structure/bed/dogbed/ian, -/mob/living/simple_animal/pet/dog/corgi/Ian, /turf/simulated/floor/wood, /area/crew_quarters/heads) "byf" = ( @@ -36047,7 +36081,6 @@ }, /area/civilian/barber) "byJ" = ( -/obj/machinery/computer/card, /obj/machinery/light/small{ dir = 4 }, @@ -36058,6 +36091,9 @@ name = "Captain RC"; pixel_x = 32 }, +/obj/machinery/computer/card{ + dir = 8 + }, /turf/simulated/floor/wood, /area/crew_quarters/captain{ name = "\improper Captain's Quarters" @@ -36432,10 +36468,10 @@ name = "\improper MiniSat Exterior" }) "bzr" = ( +/obj/machinery/vending/cigarette, /obj/machinery/computer/security/telescreen/entertainment{ pixel_y = -30 }, -/obj/machinery/vending/cigarette, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "cafeteria" @@ -37055,7 +37091,9 @@ }) "bAT" = ( /obj/machinery/light, -/obj/machinery/computer/station_alert, +/obj/machinery/computer/station_alert{ + dir = 1 + }, /obj/machinery/computer/security/telescreen{ dir = 1; name = "MiniSat Monitor"; @@ -37313,10 +37351,10 @@ /obj/machinery/light_switch{ pixel_x = -23 }, +/obj/machinery/cryopod/robot, /obj/machinery/computer/cryopod/robot{ pixel_y = -28 }, -/obj/machinery/cryopod/robot, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "darkbluecorners" @@ -37590,11 +37628,15 @@ d2 = 2; icon_state = "1-2" }, -/obj/machinery/computer/secure_data, +/obj/machinery/computer/secure_data{ + dir = 1 + }, /turf/simulated/floor/wood, /area/crew_quarters/heads) "bCa" = ( -/obj/machinery/computer/card, +/obj/machinery/computer/card{ + dir = 1 + }, /turf/simulated/floor/wood, /area/crew_quarters/heads) "bCb" = ( @@ -37929,11 +37971,11 @@ /turf/simulated/floor/wood, /area/crew_quarters/bar) "bCJ" = ( -/obj/machinery/computer/arcade, /obj/machinery/alarm{ dir = 8; pixel_x = 24 }, +/obj/machinery/computer/arcade, /obj/machinery/computer/security/telescreen/entertainment{ pixel_y = 32 }, @@ -38948,7 +38990,6 @@ /turf/simulated/floor/engine, /area/engine/engineering) "bEM" = ( -/obj/machinery/computer/atmos_alert, /obj/structure/sign/double/map/left{ desc = "A framed picture of the station. Clockwise from security at the top (red), you see engineering (yellow), science (purple), escape (red and white), medbay (green), arrivals (blue and white), and finally cargo (brown)."; icon_state = "map-left-MS"; @@ -38957,6 +38998,7 @@ /obj/machinery/camera{ c_tag = "Atmospherics - Control Room" }, +/obj/machinery/computer/atmos_alert, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "caution" @@ -39173,14 +39215,15 @@ name = "Arrivals" }) "bFf" = ( -/obj/machinery/computer/monitor{ - name = "Grid Power Monitoring Computer" - }, /obj/item/radio/intercom{ name = "Station Intercom (General)"; pixel_x = 5; pixel_y = -26 }, +/obj/machinery/computer/monitor{ + dir = 1; + name = "Grid Power Monitoring Computer" + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -40117,11 +40160,13 @@ /turf/simulated/floor/wood, /area/security/vacantoffice) "bHi" = ( -/obj/machinery/computer/message_monitor, /obj/machinery/alarm{ dir = 4; pixel_x = -24 }, +/obj/machinery/computer/message_monitor{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "grimy" }, @@ -40299,13 +40344,13 @@ }) "bHC" = ( /obj/machinery/light, +/mob/living/simple_animal/pet/dog/fox/Renault, /obj/machinery/computer/security/telescreen{ dir = 1; name = "MiniSat Monitor"; network = list("MiniSat","tcomm"); pixel_y = -29 }, -/mob/living/simple_animal/pet/dog/fox/Renault, /turf/simulated/floor/carpet, /area/crew_quarters/captain{ name = "\improper Captain's Quarters" @@ -40530,6 +40575,7 @@ /area/atmos) "bIg" = ( /obj/machinery/computer/general_air_control{ + dir = 8; frequency = 1443; level = 3; name = "Distribution and Waste Monitor"; @@ -40824,17 +40870,18 @@ name = "\improper Auxiliary Restrooms" }) "bIY" = ( -/obj/machinery/computer/general_air_control{ - frequency = 1441; - name = "Tank Monitor"; - sensors = list("n2_sensor" = "Nitrogen", "o2_sensor" = "Oxygen", "co2_sensor" = "Carbon Dioxide", "tox_sensor" = "Toxins", "n2o_sensor" = "Nitrous Oxide", "waste_sensor" = "Gas Mix Tank") - }, /obj/machinery/requests_console{ department = "Atmospherics"; departmentType = 4; name = "Atmos RC"; pixel_x = 30 }, +/obj/machinery/computer/general_air_control{ + dir = 8; + frequency = 1441; + name = "Tank Monitor"; + sensors = list("n2_sensor" = "Nitrogen", "o2_sensor" = "Oxygen", "co2_sensor" = "Carbon Dioxide", "tox_sensor" = "Toxins", "n2o_sensor" = "Nitrous Oxide", "waste_sensor" = "Gas Mix Tank") + }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "caution" @@ -41561,14 +41608,15 @@ /turf/simulated/floor/plasteel, /area/atmos) "bKg" = ( +/obj/machinery/atmospherics/pipe/simple/visible/cyan, /obj/machinery/computer/general_air_control/large_tank_control{ + dir = 8; frequency = 1441; input_tag = "waste_in"; name = "Gas Mix Tank Control"; output_tag = "waste_out"; sensors = list("waste_sensor" = "Tank") }, -/obj/machinery/atmospherics/pipe/simple/visible/cyan, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "green" @@ -42897,6 +42945,10 @@ /obj/effect/decal/warning_stripes/yellow/partial{ dir = 1 }, +/obj/machinery/ticket_machine{ + layer = 4; + pixel_x = 32 + }, /turf/simulated/floor/plasteel, /area/bridge/meeting_room{ name = "\improper Command Hallway" @@ -42924,10 +42976,6 @@ }, /obj/effect/decal/warning_stripes/arrow, /obj/effect/decal/warning_stripes/yellow/partial, -/obj/machinery/ticket_machine{ - layer = 4; - pixel_x = -32 - }, /turf/simulated/floor/plasteel, /area/bridge/meeting_room{ name = "\improper Command Hallway" @@ -43293,7 +43341,9 @@ name = "E.V.A. Storage" }) "bNN" = ( -/obj/machinery/computer/card/minor/rd, +/obj/machinery/computer/card/minor/rd{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "cafeteria" @@ -43589,15 +43639,15 @@ /area/library) "bOw" = ( /obj/structure/table/wood, -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_x = -32 - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 5 }, /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 4 }, +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_x = -32 + }, /turf/simulated/floor/wood, /area/library) "bOx" = ( @@ -44244,16 +44294,6 @@ /area/security/vacantoffice) "bPS" = ( /obj/effect/decal/warning_stripes/southeast, -/obj/structure/cable/yellow{ - d1 = 1; - d2 = 4; - icon_state = "1-4" - }, -/obj/structure/cable/yellow{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plasteel, @@ -44698,7 +44738,6 @@ pixel_x = 6; pixel_y = -30 }, -/obj/machinery/computer/card/minor/cmo, /obj/machinery/keycard_auth{ pixel_x = -26; pixel_y = -7 @@ -44709,6 +44748,9 @@ pixel_x = -26; pixel_y = 4 }, +/obj/machinery/computer/card/minor/cmo{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "barber" @@ -45325,11 +45367,11 @@ c_tag = "Club - Aft"; dir = 1 }, +/obj/item/clothing/mask/cigarette/pipe, +/obj/structure/table/wood, /obj/machinery/computer/security/telescreen/entertainment{ pixel_y = -29 }, -/obj/item/clothing/mask/cigarette/pipe, -/obj/structure/table/wood, /turf/simulated/floor/carpet, /area/crew_quarters/bar) "bSk" = ( @@ -45413,17 +45455,18 @@ name = "\improper Command Hallway" }) "bSs" = ( +/obj/machinery/atmospherics/pipe/simple/visible/green, +/obj/structure/window/reinforced{ + dir = 4 + }, /obj/machinery/computer/general_air_control/large_tank_control{ + dir = 8; frequency = 1441; input_tag = "n2o_in"; name = "Nitrous Oxide Supply Control"; output_tag = "n2o_out"; sensors = list("n2o_sensor" = "Tank") }, -/obj/machinery/atmospherics/pipe/simple/visible/green, -/obj/structure/window/reinforced{ - dir = 4 - }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "escape" @@ -45797,12 +45840,13 @@ }, /area/medical/paramedic) "bTf" = ( -/obj/machinery/computer/security{ - network = list("SS13","Research Outpost","Mining Outpost") - }, /obj/machinery/light{ dir = 4 }, +/obj/machinery/computer/security{ + dir = 8; + network = list("SS13","Research Outpost","Mining Outpost") + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -46735,8 +46779,8 @@ "bVd" = ( /obj/structure/table/wood, /obj/item/folder, -/obj/item/stamp/centcom, /obj/item/pen/multi/fountain, +/obj/item/stamp/rep, /turf/simulated/floor/carpet, /area/ntrep) "bVe" = ( @@ -47124,11 +47168,6 @@ d2 = 8; icon_state = "1-8" }, -/obj/structure/cable/yellow{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, /obj/effect/decal/warning_stripes/east, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ @@ -47313,11 +47352,6 @@ dir = 4; pixel_x = -24 }, -/obj/structure/cable/yellow{ - d1 = 2; - d2 = 4; - icon_state = "2-4" - }, /obj/effect/decal/warning_stripes/southwest, /turf/simulated/floor/plasteel, /area/teleporter{ @@ -47463,18 +47497,12 @@ name = "E.V.A. Storage" }) "bWB" = ( -/obj/structure/cable/yellow{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/effect/decal/warning_stripes/south, /turf/simulated/floor/plasteel, /area/teleporter{ name = "\improper Teleporter Room" }) "bWC" = ( -/obj/structure/cable/yellow, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "vault" @@ -47509,7 +47537,6 @@ name = "\improper Teleporter Room" }) "bWF" = ( -/obj/structure/cable/yellow, /obj/machinery/shieldwallgen, /turf/simulated/floor/plasteel{ dir = 4; @@ -47607,11 +47634,6 @@ /obj/item/clothing/mask/gas, /obj/structure/table, /obj/item/radio/off, -/obj/structure/cable/yellow{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, /obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel, /area/teleporter{ @@ -48133,7 +48155,9 @@ }, /area/crew_quarters/kitchen) "bXY" = ( -/obj/machinery/computer/teleporter, +/obj/machinery/computer/teleporter{ + dir = 1 + }, /turf/simulated/floor/plating, /area/teleporter{ name = "\improper Teleporter Room" @@ -48162,17 +48186,18 @@ /turf/simulated/floor/wood, /area/blueshield) "bYc" = ( +/obj/machinery/atmospherics/pipe/simple/visible/green, +/obj/structure/window/reinforced{ + dir = 4 + }, /obj/machinery/computer/general_air_control/large_tank_control{ + dir = 8; frequency = 1441; input_tag = "tox_in"; name = "Toxin Supply Control"; output_tag = "tox_out"; sensors = list("tox_sensor" = "Tank") }, -/obj/machinery/atmospherics/pipe/simple/visible/green, -/obj/structure/window/reinforced{ - dir = 4 - }, /turf/simulated/floor/plasteel{ icon_state = "purplefull" }, @@ -48366,13 +48391,13 @@ }, /area/crew_quarters/kitchen) "bYv" = ( -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_x = 30 - }, /obj/machinery/photocopier, /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 8 }, +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_x = 30 + }, /turf/simulated/floor/wood, /area/library) "bYw" = ( @@ -48481,7 +48506,9 @@ pixel_y = -24; req_access_txt = "67" }, -/obj/machinery/computer/crew, +/obj/machinery/computer/crew{ + dir = 1 + }, /turf/simulated/floor/wood, /area/blueshield) "bYK" = ( @@ -48516,7 +48543,9 @@ pixel_y = -24; req_access_txt = "73" }, -/obj/machinery/computer/secure_data, +/obj/machinery/computer/secure_data{ + dir = 1 + }, /turf/simulated/floor/wood, /area/ntrep) "bYO" = ( @@ -49493,8 +49522,8 @@ /turf/simulated/floor/plating, /area/crew_quarters/hor) "caZ" = ( -/mob/living/simple_animal/mouse, /obj/structure/disposalpipe/segment, +/mob/living/simple_animal/mouse, /turf/simulated/floor/plating, /area/maintenance/starboard) "cba" = ( @@ -50300,17 +50329,18 @@ }, /area/hallway/primary/central) "ccT" = ( +/obj/machinery/atmospherics/pipe/simple/visible/green, +/obj/structure/window/reinforced{ + dir = 4 + }, /obj/machinery/computer/general_air_control/large_tank_control{ + dir = 8; frequency = 1441; input_tag = "co2_in"; name = "Carbon Dioxide Supply Control"; output_tag = "co2_out"; sensors = list("co2_sensor" = "Tank") }, -/obj/machinery/atmospherics/pipe/simple/visible/green, -/obj/structure/window/reinforced{ - dir = 4 - }, /turf/simulated/floor/plasteel{ icon_state = "vault" }, @@ -50637,15 +50667,16 @@ }, /area/gateway) "cdC" = ( -/obj/machinery/power/solar_control{ - id = "aftport"; - name = "Aft Port Solar Control" - }, /obj/structure/cable{ d2 = 4; icon_state = "0-4" }, /obj/structure/cable, +/obj/machinery/power/solar_control{ + dir = 1; + id = "aftport"; + name = "Aft Port Solar Control" + }, /turf/simulated/floor/plating, /area/maintenance/portsolar) "cdD" = ( @@ -51193,11 +51224,11 @@ /turf/simulated/floor/mech_bay_recharge_floor, /area/maintenance/aft) "ceV" = ( -/obj/machinery/computer/mech_bay_power_console, /obj/structure/cable/yellow{ d2 = 2; icon_state = "0-2" }, +/obj/machinery/computer/mech_bay_power_console, /turf/simulated/floor/bluegrid, /area/maintenance/aft) "ceW" = ( @@ -51638,7 +51669,6 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/visible/yellow, -/obj/machinery/atmospherics/pipe/simple/visible/yellow, /turf/simulated/floor/plating, /area/maintenance/incinerator) "cfM" = ( @@ -52450,6 +52480,9 @@ /obj/effect/landmark{ name = "lightsout" }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -52467,6 +52500,12 @@ icon_state = "1-2" }, /obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -52625,7 +52664,9 @@ dir = 8; pixel_x = 24 }, -/obj/machinery/computer/crew, +/obj/machinery/computer/crew{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 6; icon_state = "whiteblue" @@ -52681,6 +52722,8 @@ icon_state = "1-2" }, /obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -52967,16 +53010,17 @@ /area/atmos) "ciN" = ( /obj/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/visible/green{ + dir = 4 + }, /obj/machinery/computer/general_air_control/large_tank_control{ + dir = 1; frequency = 1441; input_tag = "n2_in"; name = "Nitrogen Supply Control"; output_tag = "n2_out"; sensors = list("n2_sensor" = "Tank") }, -/obj/machinery/atmospherics/pipe/simple/visible/green{ - dir = 4 - }, /turf/simulated/floor/plasteel{ icon_state = "redfull" }, @@ -53022,16 +53066,17 @@ /area/atmos) "ciR" = ( /obj/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/visible/green{ + dir = 4 + }, /obj/machinery/computer/general_air_control/large_tank_control{ + dir = 1; frequency = 1441; input_tag = "o2_in"; name = "Oxygen Supply Control"; output_tag = "o2_out"; sensors = list("o2_sensor" = "Tank") }, -/obj/machinery/atmospherics/pipe/simple/visible/green{ - dir = 4 - }, /turf/simulated/floor/plasteel{ icon_state = "bluefull" }, @@ -53083,7 +53128,11 @@ /area/atmos) "ciV" = ( /obj/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/visible/green{ + dir = 4 + }, /obj/machinery/computer/general_air_control/large_tank_control{ + dir = 1; frequency = 1443; input_tag = "air_in"; name = "Mixed Air Supply Control"; @@ -53091,9 +53140,6 @@ pressure_setting = 2000; sensors = list("air_sensor" = "Tank") }, -/obj/machinery/atmospherics/pipe/simple/visible/green{ - dir = 4 - }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "barber" @@ -53366,6 +53412,8 @@ icon_state = "1-2" }, /obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plasteel{ icon_state = "whiteblue" }, @@ -54936,11 +54984,11 @@ icon_state = "map-left-MS"; pixel_y = 32 }, +/obj/item/storage/box/donkpockets, +/obj/structure/table/glass, /obj/machinery/computer/security/telescreen/entertainment{ pixel_x = -32 }, -/obj/item/storage/box/donkpockets, -/obj/structure/table/glass, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "cafeteria" @@ -55221,6 +55269,7 @@ pixel_x = -31 }, /obj/machinery/computer/turbine_computer{ + dir = 1; id = "incineratorturbine" }, /turf/simulated/floor/plating, @@ -55720,10 +55769,10 @@ /obj/item/multitool{ pixel_x = 3 }, +/obj/effect/decal/warning_stripes/east, /obj/machinery/computer/guestpass{ pixel_y = 30 }, -/obj/effect/decal/warning_stripes/east, /turf/simulated/floor/plasteel, /area/toxins/lab) "coI" = ( @@ -56119,6 +56168,8 @@ icon_state = "1-2" }, /obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plasteel{ icon_state = "whitebluefull" }, @@ -56233,10 +56284,10 @@ /area/medical/reception) "cpN" = ( /obj/structure/table, -/obj/machinery/computer/guestpass, /obj/machinery/camera{ c_tag = "Medbay Surgery 1 North" }, +/obj/machinery/computer/guestpass, /turf/simulated/floor/plasteel{ dir = 9; icon_state = "whiteblue" @@ -56244,7 +56295,9 @@ /area/medical/reception) "cpO" = ( /obj/structure/table, -/obj/machinery/computer/crew, +/obj/machinery/computer/crew{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "whiteblue" @@ -56552,12 +56605,14 @@ }, /area/medical/research) "cqv" = ( -/obj/machinery/computer/rdconsole/core, /obj/machinery/alarm{ dir = 4; pixel_x = -24 }, /obj/effect/decal/warning_stripes/south, +/obj/machinery/computer/rdconsole/core{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/toxins/lab) "cqw" = ( @@ -56868,6 +56923,8 @@ icon_state = "1-2" }, /obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "whiteblue" @@ -57813,13 +57870,9 @@ d2 = 8; icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, /obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -58085,7 +58138,9 @@ /turf/simulated/floor/plating/airless, /area/maintenance/incinerator) "ctw" = ( -/obj/machinery/computer/arcade/orion_trail, +/obj/machinery/computer/arcade/orion_trail{ + dir = 4 + }, /turf/simulated/floor/carpet/arcade, /area/crew_quarters/fitness{ name = "\improper Arcade" @@ -58250,12 +58305,14 @@ }, /area/medical/surgery1) "ctW" = ( -/obj/machinery/computer/operating, /obj/structure/cable/yellow{ d1 = 1; d2 = 2; icon_state = "1-2" }, +/obj/machinery/computer/operating{ + dir = 8 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -58326,8 +58383,8 @@ }, /area/medical/chemistry) "cuj" = ( -/obj/machinery/computer/rdconsole/experiment, /obj/effect/decal/warning_stripes/south, +/obj/machinery/computer/rdconsole/experiment, /turf/simulated/floor/plasteel, /area/toxins/explab) "cuk" = ( @@ -58650,7 +58707,9 @@ /area/medical/reception) "cuU" = ( /obj/structure/table, -/obj/machinery/computer/crew, +/obj/machinery/computer/crew{ + dir = 1 + }, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "whiteblue" @@ -59148,7 +59207,9 @@ /area/medical/reception) "cvM" = ( /obj/structure/table, -/obj/machinery/computer/crew, +/obj/machinery/computer/crew{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "whiteblue" }, @@ -60214,6 +60275,10 @@ name = "privacy shutters"; opacity = 0 }, +/obj/structure/cable/yellow{ + d2 = 2; + icon_state = "0-2" + }, /turf/simulated/floor/plating, /area/medical/cmo) "cyt" = ( @@ -60466,7 +60531,6 @@ }, /area/medical/research) "czc" = ( -/obj/machinery/computer/aifixer, /obj/machinery/requests_console{ announcementConsole = 1; department = "Research Director's Desk"; @@ -60478,6 +60542,9 @@ /obj/structure/window/reinforced{ dir = 4 }, +/obj/machinery/computer/aifixer{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "cafeteria" @@ -60523,6 +60590,16 @@ /obj/machinery/camera{ c_tag = "Medbay Surgery 1 North" }, +/obj/structure/cable/yellow{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + d1 = 2; + d2 = 4; + icon_state = "2-4" + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "barber" @@ -60555,6 +60632,11 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/cable/yellow{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -60720,6 +60802,11 @@ pixel_y = 2 }, /obj/item/clothing/accessory/stethoscope, +/obj/structure/cable/yellow{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "barber" @@ -60746,6 +60833,11 @@ /obj/item/folder/white, /obj/item/stamp/cmo, /obj/item/clothing/glasses/hud/health, +/obj/structure/cable/yellow{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "barber" @@ -60924,10 +61016,12 @@ }, /area/crew_quarters/hor) "czT" = ( -/obj/machinery/computer/robotics, /obj/structure/window/reinforced{ dir = 4 }, +/obj/machinery/computer/robotics{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "cafeteria" @@ -61323,7 +61417,6 @@ /turf/simulated/floor/plating, /area/toxins/test_area) "cAM" = ( -/obj/machinery/computer/area_atmos, /obj/machinery/light/small{ dir = 1 }, @@ -61331,6 +61424,7 @@ pixel_y = 32 }, /obj/effect/decal/warning_stripes/northeast, +/obj/machinery/computer/area_atmos, /turf/simulated/floor/plasteel, /area/toxins/storage) "cAN" = ( @@ -61340,10 +61434,12 @@ }, /area/crew_quarters/hor) "cAO" = ( -/obj/machinery/computer/mecha, /obj/structure/window/reinforced{ dir = 4 }, +/obj/machinery/computer/mecha{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "cafeteria" @@ -61490,13 +61586,13 @@ /turf/space, /area/solar/port) "cBf" = ( +/obj/structure/table/reinforced, /obj/machinery/computer/security/telescreen{ desc = "Used for watching the RD's goons from the safety of his office."; name = "Research Monitor"; network = list("RD"); pixel_y = 2 }, -/obj/structure/table/reinforced, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "cafeteria" @@ -61593,12 +61689,27 @@ name = "Chief Medical Officer's Office"; req_access_txt = "40" }, +/obj/structure/cable/yellow{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + d1 = 2; + d2 = 4; + icon_state = "2-4" + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "barber" }, /area/medical/cmo) "cBs" = ( +/obj/structure/cable/yellow{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "barber" @@ -61608,6 +61719,11 @@ /obj/effect/landmark/start{ name = "Chief Medical Officer" }, +/obj/structure/cable/yellow{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "barber" @@ -61615,6 +61731,16 @@ /area/medical/cmo) "cBu" = ( /obj/machinery/hologram/holopad, +/obj/structure/cable/yellow{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "barber" @@ -61666,12 +61792,14 @@ }, /area/medical/genetics_cloning) "cBz" = ( -/obj/machinery/computer/scan_consolenew, /obj/machinery/camera{ c_tag = "Genetics Lab"; dir = 4; network = list("SS13","Medbay") }, +/obj/machinery/computer/scan_consolenew{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "whitebluefull" }, @@ -61712,7 +61840,9 @@ }, /area/medical/genetics) "cBD" = ( -/obj/machinery/computer/scan_consolenew, +/obj/machinery/computer/scan_consolenew{ + dir = 8 + }, /turf/simulated/floor/plasteel{ icon_state = "whitebluefull" }, @@ -62926,23 +63056,23 @@ /area/toxins/storage) "cDO" = ( /obj/structure/bed/dogbed, -/mob/living/simple_animal/pet/cat/Runtime, /obj/machinery/light_switch{ pixel_y = -25 }, +/mob/living/simple_animal/pet/cat/Runtime, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "barber" }, /area/medical/cmo) "cDP" = ( -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_y = -32 - }, /obj/machinery/disposal, /obj/structure/disposalpipe/trunk{ dir = 1 }, +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_y = -32 + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "cafeteria" @@ -63379,10 +63509,12 @@ }, /area/medical/genetics_cloning) "cEW" = ( -/obj/machinery/computer/cloning, /obj/machinery/light{ dir = 4 }, +/obj/machinery/computer/cloning{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "whiteblue" @@ -63572,11 +63704,11 @@ /turf/simulated/floor/mech_bay_recharge_floor, /area/assembly/chargebay) "cFo" = ( -/obj/machinery/computer/mech_bay_power_console, /obj/item/radio/intercom{ name = "Station Intercom (General)"; pixel_y = 20 }, +/obj/machinery/computer/mech_bay_power_console, /turf/simulated/floor/bluegrid{ icon_state = "gcircuit" }, @@ -65109,11 +65241,11 @@ }, /area/medical/morgue) "cIp" = ( +/obj/item/reagent_containers/spray/cleaner, +/obj/structure/table/glass, /obj/machinery/computer/security/telescreen/entertainment{ pixel_y = -30 }, -/obj/item/reagent_containers/spray/cleaner, -/obj/structure/table/glass, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "cafeteria" @@ -65699,6 +65831,7 @@ /obj/structure/chair{ dir = 4 }, +/obj/effect/decal/warning_stripes/northeast, /obj/machinery/computer/security/telescreen{ desc = "Used for watching the test chamber."; dir = 8; @@ -65707,7 +65840,6 @@ network = list("Toxins"); pixel_x = 30 }, -/obj/effect/decal/warning_stripes/northeast, /turf/simulated/floor/plasteel, /area/toxins/mixing{ name = "\improper Toxins Lab" @@ -66121,6 +66253,7 @@ pixel_x = 24; pixel_y = -24 }, +/obj/effect/decal/warning_stripes/southeast, /obj/machinery/computer/security/telescreen{ desc = "Used for watching the test chamber."; dir = 8; @@ -66129,7 +66262,6 @@ network = list("Toxins"); pixel_x = 30 }, -/obj/effect/decal/warning_stripes/southeast, /turf/simulated/floor/plasteel, /area/toxins/mixing{ name = "\improper Toxins Lab" @@ -66170,12 +66302,14 @@ /turf/simulated/floor/plating, /area/maintenance/aft) "cKD" = ( -/obj/machinery/computer/operating, /obj/structure/cable/yellow{ d1 = 1; d2 = 2; icon_state = "1-2" }, +/obj/machinery/computer/operating{ + dir = 8 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -67403,6 +67537,16 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable/yellow{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + d1 = 2; + d2 = 4; + icon_state = "2-4" + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "barber" @@ -67418,6 +67562,11 @@ dir = 4; icon_state = "pipe-c" }, +/obj/structure/cable/yellow{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "barber" @@ -67856,7 +68005,6 @@ }, /area/maintenance/aft) "cNQ" = ( -/obj/machinery/computer/rdconsole/robotics, /obj/machinery/requests_console{ department = "Robotics"; departmentType = 2; @@ -67864,6 +68012,9 @@ pixel_x = -31 }, /obj/effect/decal/warning_stripes/yellow/hollow, +/obj/machinery/computer/rdconsole/robotics{ + dir = 4 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -68988,6 +69139,7 @@ /area/assembly/robotics) "cPS" = ( /obj/machinery/computer/operating{ + dir = 1; name = "Robotics Operating Computer" }, /turf/simulated/floor/plasteel{ @@ -69056,7 +69208,9 @@ name = "Station Intercom (General)"; pixel_y = -28 }, -/obj/machinery/computer/rdservercontrol, +/obj/machinery/computer/rdservercontrol{ + dir = 1 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -69323,6 +69477,7 @@ pixel_x = -24 }, /obj/effect/decal/warning_stripes/east, +/obj/structure/cable/yellow, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -70992,7 +71147,6 @@ name = "\improper Departure Lounge" }) "cTT" = ( -/obj/machinery/computer/secure_data, /obj/structure/cable/yellow{ d1 = 2; d2 = 8; @@ -71004,6 +71158,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/machinery/computer/secure_data{ + dir = 1 + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "red" @@ -71855,12 +72012,12 @@ /obj/machinery/light{ dir = 1 }, -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_y = 29 - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_y = 29 + }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "whitegreen" @@ -71932,7 +72089,9 @@ name = "\improper Departure Lounge" }) "cWc" = ( -/obj/machinery/computer/mech_bay_power_console, +/obj/machinery/computer/mech_bay_power_console{ + dir = 1 + }, /turf/simulated/floor/bluegrid, /area/assembly/chargebay) "cWd" = ( @@ -73605,8 +73764,10 @@ name = "\improper Secure Lab" }) "cZL" = ( -/obj/machinery/computer/camera_advanced/xenobio, /obj/effect/decal/warning_stripes/southwestcorner, +/obj/machinery/computer/camera_advanced/xenobio{ + dir = 1 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -74229,20 +74390,15 @@ /turf/simulated/wall, /area/medical/surgeryobs) "dbv" = ( -/obj/structure/sign/biohazard{ - pixel_x = -32 +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 }, -/obj/structure/cable/yellow{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "whitegreen" + icon_state = "white" }, -/area/maintenance/aft) +/area/medical/medbay2{ + name = "Medbay Storage" + }) "dbw" = ( /obj/item/radio/intercom{ name = "Station Intercom (General)"; @@ -76219,14 +76375,14 @@ name = "Arrivals" }) "dgB" = ( +/obj/structure/table/reinforced, +/obj/effect/decal/warning_stripes/south, /obj/machinery/computer/security/telescreen{ dir = 1; name = "Test Chamber Monitor"; network = list("Xeno"); pixel_y = 2 }, -/obj/structure/table/reinforced, -/obj/effect/decal/warning_stripes/south, /turf/simulated/floor/plasteel, /area/toxins/xenobiology{ name = "\improper Secure Lab" @@ -76324,7 +76480,9 @@ /turf/simulated/wall, /area/engine/mechanic_workshop) "dgW" = ( -/obj/machinery/computer/camera_advanced/xenobio, +/obj/machinery/computer/camera_advanced/xenobio{ + dir = 1 + }, /turf/simulated/floor/plasteel{ icon_state = "whitepurplecorner" }, @@ -76905,6 +77063,7 @@ dir = 4 }, /obj/effect/spawner/window/reinforced, +/obj/structure/cable/yellow, /turf/simulated/floor/plating, /area/medical/cmo) "ebA" = ( @@ -78130,11 +78289,13 @@ dir = 4; pixel_x = 24 }, -/obj/machinery/computer/monitor, /obj/structure/cable/yellow{ d2 = 8; icon_state = "0-8" }, +/obj/machinery/computer/monitor{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 6; icon_state = "yellow" @@ -79106,15 +79267,15 @@ /turf/space, /area/space/nearstation) "kKz" = ( -/obj/machinery/computer/cryopod{ - pixel_y = -25 - }, /obj/effect/landmark{ name = "JoinLateCryo" }, /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 1 }, +/obj/machinery/computer/cryopod{ + pixel_y = -25 + }, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -79330,6 +79491,15 @@ /obj/effect/decal/warning_stripes/southeast, /turf/simulated/floor/engine, /area/engine/engineering) +"lrA" = ( +/obj/structure/sign/biohazard{ + pixel_x = -32 + }, +/turf/simulated/floor/plasteel{ + dir = 8; + icon_state = "whitegreen" + }, +/area/maintenance/aft) "lwN" = ( /obj/effect/spawner/lootdrop{ loot = list(/obj/structure/grille,/obj/structure/grille,/obj/structure/grille,/obj/structure/grille,/obj/structure/grille,/obj/item/cigbutt,/obj/item/trash/cheesie,/obj/item/trash/candy,/obj/item/trash/chips,/obj/item/trash/pistachios,/obj/item/trash/plate,/obj/item/trash/popcorn,/obj/item/trash/raisins,/obj/item/trash/sosjerky,/obj/item/trash/syndi_cakes); @@ -80326,6 +80496,18 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply, /turf/simulated/floor/plasteel, /area/crew_quarters/locker) +"pcN" = ( +/obj/effect/spawner/window/reinforced, +/obj/machinery/door/poddoor{ + density = 0; + icon_state = "open"; + id_tag = "cmoprivacy"; + name = "privacy shutters"; + opacity = 0 + }, +/obj/structure/cable/yellow, +/turf/simulated/floor/plating, +/area/medical/cmo) "pcW" = ( /obj/structure/cable/yellow{ d1 = 4; @@ -80386,6 +80568,10 @@ opacity = 0 }, /obj/effect/spawner/window/reinforced, +/obj/structure/cable/yellow{ + d2 = 2; + icon_state = "0-2" + }, /turf/simulated/floor/plating, /area/medical/cmo) "pjn" = ( @@ -82733,11 +82919,12 @@ icon_state = "1-4"; tag = "90Curve" }, +/obj/structure/cable, /obj/machinery/power/solar_control{ + dir = 1; id = "aftstarboard"; name = "Aft Starboard Solar Control" }, -/obj/structure/cable, /turf/simulated/floor/plating, /area/maintenance/starboardsolar) "wvO" = ( @@ -104258,7 +104445,7 @@ chy bZU cZv day -cZv +lrA bZU cQx bZU @@ -104515,7 +104702,7 @@ cNZ cKV cZq dax -dbv +cZq deg cSl cRj @@ -105012,7 +105199,7 @@ cxt csJ cys cMP -cys +pcN csJ csJ cFd @@ -105255,7 +105442,7 @@ ccD cdT chU cjt -cjt +dbv cjt cjt cLT diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index 4d1213d1e65..bf46b1dc4a1 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -1940,21 +1940,27 @@ }, /area/security/brig) "agR" = ( -/obj/structure/rack, /obj/structure/window/reinforced{ dir = 1 }, -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/item/storage/box/buck{ +/obj/structure/rack, +/obj/item/storage/box/beanbag{ pixel_x = -3; pixel_y = 3 }, -/obj/item/storage/box/buck, -/obj/item/storage/box/buck{ - pixel_x = 3; - pixel_y = -3 +/obj/item/storage/box/beanbag, +/obj/item/storage/box/beanbag{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/storage/box/beanbag{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/storage/box/beanbag, +/obj/item/storage/box/beanbag, +/obj/structure/window/reinforced{ + dir = 4 }, /turf/simulated/floor/plasteel{ dir = 8; @@ -2439,21 +2445,6 @@ dir = 1 }, /obj/structure/rack, -/obj/item/storage/box/beanbag{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/storage/box/beanbag, -/obj/item/storage/box/beanbag{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/storage/box/beanbag{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/storage/box/beanbag, -/obj/item/storage/box/beanbag, /obj/item/storage/box/tranquilizer{ pixel_x = 3; pixel_y = -3 diff --git a/_maps/map_files/generic/Lavaland.dmm b/_maps/map_files/generic/Lavaland.dmm index 02e8c553456..09a796983da 100644 --- a/_maps/map_files/generic/Lavaland.dmm +++ b/_maps/map_files/generic/Lavaland.dmm @@ -886,7 +886,7 @@ }, /obj/effect/decal/cleanable/cobweb, /obj/machinery/computer/prisoner{ - dir = 1 + dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 6 @@ -4371,6 +4371,7 @@ "sO" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/computer/security{ + dir = 4; network = list("Labor Camp") }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ @@ -5275,7 +5276,7 @@ /area/mine/production) "VJ" = ( /obj/machinery/computer/secure_data{ - dir = 1 + dir = 8 }, /turf/simulated/floor/plasteel{ dir = 1; diff --git a/_maps/map_files/generic/centcomm.dmm b/_maps/map_files/generic/centcomm.dmm index 1acf135edc8..d7bf2abfaa2 100644 --- a/_maps/map_files/generic/centcomm.dmm +++ b/_maps/map_files/generic/centcomm.dmm @@ -651,7 +651,9 @@ /turf/simulated/floor/mineral/plastitanium/red, /area/shuttle/administration) "cH" = ( -/obj/machinery/computer/shuttle/ferry, +/obj/machinery/computer/shuttle/ferry{ + dir = 8 + }, /turf/simulated/floor/plating, /area/centcom/evac) "cI" = ( @@ -661,7 +663,9 @@ /turf/simulated/floor/plating/airless, /area/shuttle/specops) "cK" = ( -/obj/machinery/computer/shuttle/admin, +/obj/machinery/computer/shuttle/admin{ + dir = 8 + }, /turf/simulated/floor/plating, /area/centcom/evac) "cL" = ( @@ -1387,7 +1391,9 @@ /turf/simulated/floor/wood, /area/syndicate_mothership) "fi" = ( -/obj/machinery/computer/shuttle/syndicate/recall, +/obj/machinery/computer/shuttle/syndicate/recall{ + dir = 1 + }, /turf/simulated/floor/wood, /area/syndicate_mothership) "fj" = ( @@ -1411,8 +1417,8 @@ /turf/simulated/wall/indestructible/riveted, /area/centcom/gamma) "fn" = ( -/obj/machinery/computer/library/checkout, /obj/structure/table/wood, +/obj/machinery/computer/library/checkout, /turf/simulated/floor/engine/cult, /area/wizard_station) "fo" = ( @@ -2028,7 +2034,9 @@ /turf/simulated/floor/plasteel/dark, /area/syndicate_mothership) "hP" = ( -/obj/machinery/computer/communications, +/obj/machinery/computer/communications{ + dir = 8 + }, /turf/simulated/floor/mineral/plastitanium/red, /area/shuttle/administration) "hQ" = ( @@ -3500,7 +3508,9 @@ /turf/simulated/floor/carpet, /area/centcom/control) "mP" = ( -/obj/machinery/computer/pod/deathsquad, +/obj/machinery/computer/pod/deathsquad{ + dir = 8 + }, /turf/simulated/floor/plasteel/dark{ dir = 1; icon_state = "vault" @@ -3523,7 +3533,9 @@ /turf/simulated/floor/wood, /area/centcom/control) "mV" = ( -/obj/machinery/computer/card/centcom, +/obj/machinery/computer/card/centcom{ + dir = 8 + }, /turf/simulated/floor/wood, /area/centcom/control) "mW" = ( @@ -3588,7 +3600,9 @@ /turf/simulated/floor/carpet, /area/centcom/control) "nh" = ( -/obj/machinery/computer/communications, +/obj/machinery/computer/communications{ + dir = 8 + }, /turf/simulated/floor/carpet, /area/centcom/control) "nj" = ( @@ -4013,9 +4027,9 @@ /area/syndicate_mothership) "oB" = ( /obj/structure/closet/secure_closet/guncabinet, -/obj/item/ammo_box/shotgun/buck, -/obj/item/ammo_box/shotgun/buck, -/obj/item/ammo_box/shotgun/buck, +/obj/item/ammo_box/shotgun/beanbag, +/obj/item/ammo_box/shotgun/beanbag, +/obj/item/ammo_box/shotgun/beanbag, /obj/item/gun/projectile/shotgun/automatic/combat, /obj/item/gun/projectile/shotgun/automatic/combat, /obj/item/gun/projectile/shotgun/automatic/combat, @@ -4306,7 +4320,9 @@ d2 = 8; icon_state = "0-8" }, -/obj/machinery/computer/mech_bay_power_console, +/obj/machinery/computer/mech_bay_power_console{ + dir = 1 + }, /turf/simulated/floor/mineral/plastitanium/red, /area/shuttle/gamma/space) "pu" = ( @@ -4417,12 +4433,12 @@ /turf/simulated/floor/carpet, /area/centcom/specops) "pP" = ( +/obj/structure/table/wood, /obj/machinery/computer/security/telescreen{ desc = "Used for watching the Special Ops."; name = "Special Ops. Monitor"; network = list("ERT") }, -/obj/structure/table/wood, /turf/simulated/floor/carpet, /area/centcom/specops) "pQ" = ( @@ -4430,10 +4446,12 @@ /turf/simulated/floor/plasteel/dark, /area/centcom/specops) "pR" = ( -/obj/machinery/computer/station_alert, /obj/structure/sign/poster/official/nanotrasen_logo{ pixel_x = 32 }, +/obj/machinery/computer/station_alert{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "darkyellow" @@ -4940,7 +4958,9 @@ }, /area/centcom/evac) "rz" = ( -/obj/machinery/computer/communications, +/obj/machinery/computer/communications{ + dir = 8 + }, /turf/simulated/floor/plasteel/dark, /area/centcom/specops) "rA" = ( @@ -5185,10 +5205,12 @@ /turf/simulated/floor/wood, /area/centcom/evac) "sy" = ( -/obj/machinery/computer/secure_data, /obj/machinery/light/spot{ dir = 8 }, +/obj/machinery/computer/secure_data{ + dir = 4 + }, /turf/simulated/floor/mineral/plastitanium/red, /area/centcom/evac) "sz" = ( @@ -6168,7 +6190,9 @@ /turf/simulated/floor/plasteel/grimy, /area/centcom/specops) "vf" = ( -/obj/machinery/computer/secure_data, +/obj/machinery/computer/secure_data{ + dir = 4 + }, /turf/simulated/floor/plasteel, /area/centcom/control) "vg" = ( @@ -6185,7 +6209,9 @@ /turf/simulated/floor/plasteel, /area/admin) "vi" = ( -/obj/machinery/computer/med_data, +/obj/machinery/computer/med_data{ + dir = 8 + }, /turf/simulated/floor/plasteel, /area/centcom/control) "vj" = ( @@ -6235,11 +6261,11 @@ /turf/simulated/floor/plasteel, /area/admin) "vp" = ( -/obj/machinery/computer/mech_bay_power_console, /obj/structure/cable{ d2 = 2; icon_state = "0-2" }, +/obj/machinery/computer/mech_bay_power_console, /turf/simulated/floor/plasteel, /area/admin) "vr" = ( @@ -6257,24 +6283,33 @@ /area/admin) "vs" = ( /obj/machinery/computer/security{ + dir = 1; network = list("SS13","Telecomms","Research Outpost","Mining Outpost","ERT","CentComm","Thunderdome") }, /turf/simulated/floor/plasteel, /area/centcom/control) "vt" = ( -/obj/machinery/computer/station_alert, +/obj/machinery/computer/station_alert{ + dir = 1 + }, /turf/simulated/floor/plasteel, /area/centcom/control) "vu" = ( -/obj/machinery/computer/communications, +/obj/machinery/computer/communications{ + dir = 1 + }, /turf/simulated/floor/plasteel, /area/centcom/control) "vv" = ( -/obj/machinery/computer/robotics, +/obj/machinery/computer/robotics{ + dir = 1 + }, /turf/simulated/floor/plasteel, /area/centcom/control) "vw" = ( -/obj/machinery/computer/crew, +/obj/machinery/computer/crew{ + dir = 1 + }, /turf/simulated/floor/plasteel, /area/centcom/control) "vx" = ( @@ -6852,8 +6887,10 @@ /turf/simulated/floor/carpet, /area/admin) "wS" = ( -/obj/machinery/computer/secure_data, /obj/item/paper/sop, +/obj/machinery/computer/secure_data{ + dir = 8 + }, /turf/simulated/floor/carpet, /area/admin) "wT" = ( @@ -6881,11 +6918,15 @@ /turf/simulated/floor/carpet, /area/admin) "wY" = ( -/obj/machinery/computer/communications, +/obj/machinery/computer/communications{ + dir = 4 + }, /turf/simulated/floor/carpet, /area/admin) "wZ" = ( -/obj/machinery/computer/med_data, +/obj/machinery/computer/med_data{ + dir = 8 + }, /turf/simulated/floor/carpet, /area/admin) "xa" = ( @@ -7363,7 +7404,9 @@ }, /area/trader_station/sol) "yJ" = ( -/obj/machinery/computer/communications, +/obj/machinery/computer/communications{ + dir = 1 + }, /turf/simulated/floor/plasteel, /area/admin) "yK" = ( @@ -7380,7 +7423,9 @@ }, /area/trader_station/sol) "yP" = ( -/obj/machinery/computer/atmos_alert, +/obj/machinery/computer/atmos_alert{ + dir = 1 + }, /turf/simulated/floor/plasteel, /area/admin) "yQ" = ( @@ -7390,12 +7435,15 @@ }, /area/centcom/evac) "yR" = ( -/obj/machinery/computer/message_monitor, /obj/item/paper/monitorkey, +/obj/machinery/computer/message_monitor{ + dir = 1 + }, /turf/simulated/floor/plasteel, /area/admin) "yS" = ( /obj/machinery/computer/account_database{ + dir = 1; name = "Admin Accounts Database" }, /turf/simulated/floor/plasteel, @@ -7407,7 +7455,9 @@ /turf/simulated/floor/plating, /area/centcom/evac) "yU" = ( -/obj/machinery/computer/secure_data, +/obj/machinery/computer/secure_data{ + dir = 1 + }, /turf/simulated/floor/plasteel, /area/admin) "yV" = ( @@ -7452,7 +7502,9 @@ /turf/simulated/floor/plasteel, /area/admin) "zc" = ( -/obj/machinery/computer/arcade, +/obj/machinery/computer/arcade{ + dir = 8 + }, /turf/simulated/floor/mineral/titanium/blue, /area/centcom/evac) "zd" = ( @@ -7473,7 +7525,9 @@ /turf/simulated/floor/plasteel/dark, /area/admin) "zh" = ( -/obj/machinery/computer/card, +/obj/machinery/computer/card{ + dir = 4 + }, /turf/simulated/floor/mineral/plastitanium/red, /area/centcom/evac) "zi" = ( @@ -7944,7 +7998,9 @@ /turf/simulated/floor/plasteel, /area/admin) "AS" = ( -/obj/machinery/computer/teleporter, +/obj/machinery/computer/teleporter{ + dir = 1 + }, /turf/simulated/floor/plasteel, /area/admin) "AT" = ( @@ -8000,11 +8056,15 @@ /turf/simulated/floor/plasteel/dark, /area/syndicate_mothership) "Bb" = ( -/obj/machinery/computer/crew, +/obj/machinery/computer/crew{ + dir = 4 + }, /turf/simulated/floor/mineral/titanium/blue, /area/centcom/evac) "Bc" = ( -/obj/machinery/computer/communications, +/obj/machinery/computer/communications{ + dir = 8 + }, /turf/simulated/floor/mineral/titanium/blue, /area/centcom/evac) "Bd" = ( @@ -8040,6 +8100,7 @@ /area/centcom/evac) "Bj" = ( /obj/machinery/computer{ + dir = 1; name = "EMERGENCY SHUTTLE COMPUTER" }, /turf/simulated/floor/mineral/titanium/blue, @@ -8100,7 +8161,9 @@ /turf/simulated/floor/plasteel/dark, /area/syndicate_mothership) "Bv" = ( -/obj/machinery/computer/camera_advanced, +/obj/machinery/computer/camera_advanced{ + dir = 8 + }, /turf/simulated/floor/plasteel/dark, /area/syndicate_mothership) "Bw" = ( @@ -8117,6 +8180,7 @@ /area/syndicate_mothership) "By" = ( /obj/machinery/computer/shuttle/syndicate{ + dir = 1; name = "Nuclear Operatives Shuttle Console" }, /turf/simulated/floor/plasteel/dark, @@ -9000,7 +9064,9 @@ /turf/simulated/floor/mineral/titanium/blue, /area/shuttle/supply) "FJ" = ( -/obj/machinery/computer/secure_data, +/obj/machinery/computer/secure_data{ + dir = 4 + }, /turf/simulated/floor/plasteel{ dir = 10; icon_state = "darkred" @@ -9043,7 +9109,9 @@ }, /area/shuttle/escape) "Ga" = ( -/obj/machinery/computer/shuttle/ert, +/obj/machinery/computer/shuttle/ert{ + dir = 1 + }, /turf/simulated/floor/plasteel/dark, /area/centcom/specops) "Gd" = ( @@ -9119,7 +9187,9 @@ /turf/simulated/wall/mineral/plastitanium, /area/shuttle/syndicate_sit) "GD" = ( -/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate/sst, +/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate/sst{ + dir = 1 + }, /turf/simulated/floor/mineral/plastitanium/red, /area/shuttle/syndicate_elite) "GJ" = ( @@ -9376,10 +9446,12 @@ /turf/simulated/floor/plating, /area/tdome/tdome2) "Il" = ( -/obj/machinery/computer/communications, /obj/item/radio/intercom/specops{ pixel_y = -28 }, +/obj/machinery/computer/communications{ + dir = 1 + }, /turf/simulated/floor/mineral/plastitanium/red, /area/shuttle/specops) "Io" = ( @@ -9622,7 +9694,9 @@ /turf/simulated/floor/mineral/plastitanium/red/nitrogen, /area/shuttle/vox) "JH" = ( -/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate/sit, +/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate/sit{ + dir = 1 + }, /turf/simulated/floor/mineral/plastitanium/red, /area/shuttle/syndicate_sit) "JM" = ( @@ -9636,6 +9710,7 @@ /area/shuttle/administration) "JO" = ( /obj/machinery/computer/security{ + dir = 1; network = list("SS13","Research Outpost","Mining Outpost") }, /turf/simulated/floor/mineral/plastitanium/red, @@ -10628,7 +10703,9 @@ }, /area/shuttle/escape) "PU" = ( -/obj/machinery/computer/shuttle/sit, +/obj/machinery/computer/shuttle/sit{ + dir = 1 + }, /turf/simulated/floor/mineral/plastitanium/red, /area/shuttle/syndicate_sit) "PX" = ( @@ -11190,12 +11267,13 @@ }, /area/holodeck/source_thunderdomecourt) "TA" = ( -/obj/machinery/computer/security{ - network = list("SS13","Research Outpost","Mining Outpost","Telecomms") - }, /obj/structure/sign/poster/official/nanotrasen_logo{ pixel_x = -32 }, +/obj/machinery/computer/security{ + dir = 4; + network = list("SS13","Research Outpost","Mining Outpost","Telecomms") + }, /turf/simulated/floor/plasteel{ dir = 9; icon_state = "darkred" @@ -11379,7 +11457,9 @@ }, /area/holodeck/source_knightarena) "UJ" = ( -/obj/machinery/computer/shuttle/sst, +/obj/machinery/computer/shuttle/sst{ + dir = 1 + }, /turf/simulated/floor/mineral/plastitanium/red, /area/shuttle/syndicate_elite) "UK" = ( @@ -11495,6 +11575,7 @@ /area/shuttle/escape) "Vr" = ( /obj/machinery/computer/camera_advanced/shuttle_docker/admin{ + dir = 8; name = "NTV Argos shuttle navigation computer" }, /turf/simulated/floor/mineral/plastitanium/red, @@ -11568,7 +11649,9 @@ }, /area/shuttle/escape) "VS" = ( -/obj/machinery/computer/atmos_alert, +/obj/machinery/computer/atmos_alert{ + dir = 8 + }, /turf/simulated/floor/plasteel{ dir = 6; icon_state = "darkyellow" @@ -11600,6 +11683,7 @@ /area/shuttle/vox) "Wc" = ( /obj/machinery/computer/shuttle/admin{ + dir = 8; name = "NTV Argos shuttle console" }, /turf/simulated/floor/mineral/plastitanium/red, @@ -12043,7 +12127,6 @@ }, /area/shuttle/escape) "YV" = ( -/obj/machinery/computer/shuttle/trade/sol, /obj/machinery/door_control{ id = "soltrader_south"; name = "Trade Deposits Door"; @@ -12057,6 +12140,9 @@ pixel_x = 24; pixel_y = -8 }, +/obj/machinery/computer/shuttle/trade/sol{ + dir = 8 + }, /turf/simulated/floor/mineral/titanium/blue, /area/shuttle/trade/sol) "YW" = ( diff --git a/_maps/map_files/shuttles/admin_armory.dmm b/_maps/map_files/shuttles/admin_armory.dmm index d2873d05de7..766ce3e588c 100644 --- a/_maps/map_files/shuttles/admin_armory.dmm +++ b/_maps/map_files/shuttles/admin_armory.dmm @@ -565,11 +565,11 @@ layer = 2.9 }, /obj/structure/rack, -/obj/item/gun/projectile/shotgun/riot/buckshot{ +/obj/item/gun/projectile/shotgun/riot{ pixel_x = -3; pixel_y = 3 }, -/obj/item/gun/projectile/shotgun/riot/buckshot, +/obj/item/gun/projectile/shotgun/riot, /turf/simulated/floor/mineral/plastitanium/red, /area/shuttle/administration) "Gx" = ( @@ -705,11 +705,11 @@ layer = 2.9 }, /obj/structure/rack, -/obj/item/gun/projectile/shotgun/riot/buckshot{ +/obj/item/gun/projectile/shotgun/riot{ pixel_x = -3; pixel_y = 3 }, -/obj/item/gun/projectile/shotgun/riot/buckshot, +/obj/item/gun/projectile/shotgun/riot, /turf/simulated/floor/mineral/plastitanium/red, /area/shuttle/administration) "Ns" = ( @@ -914,11 +914,11 @@ /obj/structure/window/reinforced{ dir = 4 }, -/obj/item/gun/projectile/shotgun/riot/buckshot{ +/obj/item/gun/projectile/shotgun/riot{ pixel_x = -3; pixel_y = 3 }, -/obj/item/gun/projectile/shotgun/riot/buckshot, +/obj/item/gun/projectile/shotgun/riot, /turf/simulated/floor/mineral/plastitanium/red, /area/shuttle/administration) diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 5b8074a4658..d3655b164f5 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -124,6 +124,17 @@ #define WEAPON_MEDIUM 2 #define WEAPON_HEAVY 3 +//His Grace. +#define HIS_GRACE_SATIATED 0 //He hungers not. If bloodthirst is set to this, His Grace is asleep. +#define HIS_GRACE_PECKISH 20 //Slightly hungry. +#define HIS_GRACE_HUNGRY 60 //Getting closer. Increases damage up to a minimum of 20. +#define HIS_GRACE_FAMISHED 100 //Dangerous. Increases damage up to a minimum of 25 and cannot be dropped. +#define HIS_GRACE_STARVING 120 //Incredibly close to breaking loose. Increases damage up to a minimum of 30. +#define HIS_GRACE_CONSUME_OWNER 140 //His Grace consumes His owner at this point and becomes aggressive. +#define HIS_GRACE_FALL_ASLEEP 160 //If it reaches this point, He falls asleep and resets. + +#define HIS_GRACE_FORCE_BONUS 4 //How much force is gained per kill. + #define EXPLODE_NONE 0 //Don't even ask me why we need this. #define EXPLODE_DEVASTATE 1 #define EXPLODE_HEAVY 2 diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index a198421a2cb..6e85ef5ba14 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -115,3 +115,11 @@ #define _2FA_ENABLED_IP "ENABLED_IP" /// Client will be prompted for 2FA always #define _2FA_ENABLED_ALWAYS "ENABLED_ALWAYS" + + +#define MAX_SAVE_SLOTS 30 // Save slots for regular players +#define MAX_SAVE_SLOTS_MEMBER 30 // Save slots for BYOND members + +#define TAB_CHAR 0 +#define TAB_GAME 1 +#define TAB_GEAR 2 diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index ce91d2ccf31..aa4b044ed0f 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -13,6 +13,8 @@ // BUFFS // /////////// +#define STATUS_EFFECT_HISGRACE /datum/status_effect/his_grace //His Grace. + #define STATUS_EFFECT_SHADOW_MEND /datum/status_effect/shadow_mend //Quick, powerful heal that deals damage afterwards. Heals 15 brute/burn every second for 3 seconds. #define STATUS_EFFECT_VOID_PRICE /datum/status_effect/void_price //The price of healing yourself with void energy. Deals 3 brute damage every 3 seconds for 30 seconds. #define STATUS_EFFECT_EXERCISED /datum/status_effect/exercised //Prevents heart disease @@ -27,7 +29,6 @@ //#define STATUS_EFFECT_POWERREGEN /datum/status_effect/cyborg_power_regen //Regenerates power on a given cyborg over time -//#define STATUS_EFFECT_HISGRACE /datum/status_effect/his_grace //His Grace. //#define STATUS_EFFECT_WISH_GRANTERS_GIFT /datum/status_effect/wish_granters_gift //If you're currently resurrecting with the Wish Granter @@ -53,7 +54,7 @@ //#define MAX_MANIA_SEVERITY 100 //how high the mania severity can go //#define MANIA_DAMAGE_TO_CONVERT 90 //how much damage is required before it'll convert affected targets -//#define STATUS_EFFECT_HISWRATH /datum/status_effect/his_wrath //His Wrath. +#define STATUS_EFFECT_HISWRATH /datum/status_effect/his_wrath //His Wrath. #define STATUS_EFFECT_SUMMONEDGHOST /datum/status_effect/cultghost //is a cult ghost: can see dead people, can't manifest more ghosts diff --git a/code/__HELPERS/AnimationLibrary.dm b/code/__HELPERS/AnimationLibrary.dm index 1f0c3dd9ab1..738783ed826 100644 --- a/code/__HELPERS/AnimationLibrary.dm +++ b/code/__HELPERS/AnimationLibrary.dm @@ -188,3 +188,21 @@ animate(A, transform = matrix(punchstr, MATRIX_ROTATE), pixel_y = 16, time = 2, color = "#eeeeee", easing = BOUNCE_EASING) animate(transform = matrix(-punchstr, MATRIX_ROTATE), pixel_y = original_y, time = 2, color = "#ffffff", easing = BOUNCE_EASING) animate(transform = null, time = 3, easing = BOUNCE_EASING) + +/proc/animate_rumble(atom/A) + var/static/list/transforms + if(!transforms) + var/matrix/M1 = matrix() + var/matrix/M2 = matrix() + var/matrix/M3 = matrix() + var/matrix/M4 = matrix() + M1.Translate(-1, 0) + M2.Translate(0, 1) + M3.Translate(1, 0) + M4.Translate(0, -1) + transforms = list(M1, M2, M3, M4) + + animate(A, transform = transforms[1], time = 0.2, loop = -1) + animate(transform = transforms[2], time = 0.1) + animate(transform = transforms[3], time = 0.2) + animate(transform = transforms[4], time = 0.3) diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm index 612f7b5abef..402ba2c7e3b 100644 --- a/code/__HELPERS/cmp.dm +++ b/code/__HELPERS/cmp.dm @@ -51,3 +51,6 @@ return A.plane - B.plane else return A.layer - B.layer + +/proc/cmp_login_processor_priority(datum/client_login_processor/A, datum/client_login_processor/B) + return A.priority - B.priority diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 282ad53cd06..2171422a5aa 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -128,6 +128,13 @@ continue GLOB.world_topic_handlers[wth.topic_key] = topic_handler_type + // Setup client login processors. + for(var/processor_type in subtypesof(/datum/client_login_processor)) + var/datum/client_login_processor/CLP = new processor_type + GLOB.client_login_processors += CLP + // Sort them by priority, lowest first + sortTim(GLOB.client_login_processors, /proc/cmp_login_processor_priority) + /* // Uncomment to debug chemical reaction list. /client/verb/debug_chemical_list() diff --git a/code/__HELPERS/matrices.dm b/code/__HELPERS/matrices.dm index 0520ab6b077..414a16636ec 100644 --- a/code/__HELPERS/matrices.dm +++ b/code/__HELPERS/matrices.dm @@ -3,7 +3,7 @@ Turn(.) //BYOND handles cases such as -270, 360, 540 etc. DOES NOT HANDLE 180 TURNS WELL, THEY TWEEN AND LOOK LIKE SHIT -/atom/proc/SpinAnimation(speed = 10, loops = -1, clockwise = 1, segments = 3) +/atom/proc/SpinAnimation(speed = 10, loops = -1, clockwise = 1, segments = 3, parallel = TRUE) if(!segments) return var/segment = 360/segments @@ -19,7 +19,10 @@ speed /= segments - animate(src, transform = matrices[1], time = speed, loops) + if(parallel) + animate(src, transform = matrices[1], time = speed, loops , flags = ANIMATION_PARALLEL) + else + animate(src, transform = matrices[1], time = speed, loops) for(var/i in 2 to segments) //2 because 1 is covered above animate(transform = matrices[i], time = speed) //doesn't have an object argument because this is "Stacking" with the animate call above diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 8b4cea27947..688db849a33 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -464,12 +464,15 @@ Turf and target are seperate in case you want to teleport some distance from a t if(GLOB.stealthminID[P] == txt) return P -// Returns the atom sitting on the turf. -// For example, using this on a disk, which is in a bag, on a mob, will return the mob because it's on the turf. -/proc/get_atom_on_turf(atom/movable/M) +//Returns the atom sitting on the turf. +//For example, using this on a disk, which is in a bag, on a mob, will return the mob because it's on the turf. +//Optional arg 'type' to stop once it reaches a specific type instead of a turf. +/proc/get_atom_on_turf(atom/movable/M, stop_type) var/atom/loc = M - while(loc && loc.loc && !istype(loc.loc, /turf/)) + while(loc?.loc && !isturf(loc.loc)) loc = loc.loc + if(stop_type && istype(loc, stop_type)) + break return loc /* @@ -1536,7 +1539,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) shift.Translate(0,radius) transform = shift - SpinAnimation(rotation_speed, -1, clockwise, rotation_segments) + SpinAnimation(rotation_speed, -1, clockwise, rotation_segments, parallel = FALSE) while(orbiting && orbiting == A && A.loc) var/targetloc = get_turf(A) diff --git a/code/_globalvars/lists/misc.dm b/code/_globalvars/lists/misc.dm index 5464ed64bb4..c5afa64cfba 100644 --- a/code/_globalvars/lists/misc.dm +++ b/code/_globalvars/lists/misc.dm @@ -56,3 +56,5 @@ GLOBAL_LIST_INIT(cooking_ingredients, list(RECIPE_MICROWAVE = list(), RECIPE_OVE GLOBAL_LIST_INIT(cooking_reagents, list(RECIPE_MICROWAVE = list(), RECIPE_OVEN = list(), RECIPE_GRILL = list(), RECIPE_CANDY = list())) #define EGG_LAYING_MESSAGES list("lays an egg.", "squats down and croons.", "begins making a huge racket.", "begins clucking raucously.") + +GLOBAL_LIST_EMPTY(client_login_processors) diff --git a/code/controllers/subsystem/changelog.dm b/code/controllers/subsystem/changelog.dm index 55221263033..488be1d32c0 100644 --- a/code/controllers/subsystem/changelog.dm +++ b/code/controllers/subsystem/changelog.dm @@ -54,9 +54,8 @@ SUBSYSTEM_DEF(changelog) /datum/controller/subsystem/changelog/proc/UpdatePlayerChangelogDate(client/C) if(!ss_ready) return // Only return here, we dont have to worry about a queue list because this will be called from ShowChangelog() - // Technically this is only for the date but we can also do the UI button at the same time - var/datum/preferences/P = GLOB.preferences_datums[C.ckey] - if(P.toggles & PREFTOGGLE_UI_DARKMODE) + + if(C.prefs.toggles & PREFTOGGLE_UI_DARKMODE) winset(C, "rpane.changelog", "background-color=#40628a;font-color=#ffffff;font-style=none") else winset(C, "rpane.changelog", "background-color=none;font-style=none") diff --git a/code/controllers/subsystem/jobs.dm b/code/controllers/subsystem/jobs.dm index f7660f4d75a..04e1c5fb5df 100644 --- a/code/controllers/subsystem/jobs.dm +++ b/code/controllers/subsystem/jobs.dm @@ -65,7 +65,7 @@ SUBSYSTEM_DEF(jobs) return type_occupations[jobtype] /datum/controller/subsystem/jobs/proc/GetPlayerAltTitle(mob/new_player/player, rank) - return player.client.prefs.GetPlayerAltTitle(GetJob(rank)) + return player.client.prefs.active_character.GetPlayerAltTitle(GetJob(rank)) /datum/controller/subsystem/jobs/proc/AssignRole(mob/new_player/player, rank, latejoin = 0) Debug("Running AR, Player: [player], Rank: [rank], LJ: [latejoin]") @@ -121,7 +121,7 @@ SUBSYSTEM_DEF(jobs) 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]") + 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.active_character.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 @@ -140,7 +140,7 @@ SUBSYSTEM_DEF(jobs) 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) + if(player.client.prefs.active_character.GetJobDepartment(job, level) & job.flag) Debug("FOC pass, Player: [player], Level:[level]") candidates += player return candidates @@ -367,12 +367,12 @@ SUBSYSTEM_DEF(jobs) 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(player.client.prefs.active_character.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]") + Debug(" - Job Flag: [job.flag] Job Department: [player.client.prefs.active_character.GetJobDepartment(job, level)] Job Current Pos: [job.current_positions] Job Spawn Positions = [job.spawn_positions]") AssignRole(player, job.title) unassigned -= player break @@ -380,7 +380,7 @@ SUBSYSTEM_DEF(jobs) // 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) + if(player.client.prefs.active_character.alternate_option == GET_RANDOM_JOB) GiveRandomJob(player) Debug("DO, Standard Check end") @@ -390,7 +390,7 @@ SUBSYSTEM_DEF(jobs) // Antags, who have to get in, come first for(var/mob/new_player/player in unassigned) if(player.mind.special_role) - if(player.client.prefs.alternate_option != BE_ASSISTANT) + if(player.client.prefs.active_character.alternate_option != BE_ASSISTANT) GiveRandomJob(player) if(player in unassigned) AssignRole(player, "Civilian") @@ -399,10 +399,10 @@ SUBSYSTEM_DEF(jobs) // 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) + if(player.client.prefs.active_character.alternate_option == BE_ASSISTANT) Debug("AC2 Assistant located, Player: [player]") AssignRole(player, "Civilian") - else if(player.client.prefs.alternate_option == RETURN_TO_LOBBY) + else if(player.client.prefs.active_character.alternate_option == RETURN_TO_LOBBY) player.ready = 0 unassigned -= player @@ -564,11 +564,11 @@ SUBSYSTEM_DEF(jobs) if(job.barred_by_disability(player.client)) disabled++ continue - if(player.client.prefs.GetJobDepartment(job, 1) & job.flag) + if(player.client.prefs.active_character.GetJobDepartment(job, 1) & job.flag) high++ - else if(player.client.prefs.GetJobDepartment(job, 2) & job.flag) + else if(player.client.prefs.active_character.GetJobDepartment(job, 2) & job.flag) medium++ - else if(player.client.prefs.GetJobDepartment(job, 3) & job.flag) + else if(player.client.prefs.active_character.GetJobDepartment(job, 3) & job.flag) low++ else never++ //not selected diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 579a6b7c07c..0185aa5931b 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -209,7 +209,7 @@ SUBSYSTEM_DEF(vote) /datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key, code_invoked = FALSE) if(!mode) - if(started_time != null && !check_rights(R_ADMIN)) + if(usr && started_time != null && !check_rights(R_ADMIN)) // Allow the game to call votes whenever. But check other callers var/next_allowed_time = (started_time + GLOB.configuration.vote.vote_delay) if(next_allowed_time > world.time) return 0 diff --git a/code/datums/spells/horsemask.dm b/code/datums/spells/horsemask.dm index d5f686fb763..f22689067d8 100644 --- a/code/datums/spells/horsemask.dm +++ b/code/datums/spells/horsemask.dm @@ -30,7 +30,7 @@ var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead magichead.flags |= NODROP | DROPDEL //curses! magichead.flags_inv = null //so you can still see their face - magichead.voicechange = 1 //NEEEEIIGHH + magichead.voicechange = TRUE //NEEEEIIGHH target.visible_message( "[target]'s face lights up in fire, and after the event a horse's head takes its place!", \ "Your face burns up, and shortly after the fire you realise you have the face of a horse!") if(!target.unEquip(target.wear_mask)) diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index 0494e14d647..54735988b9c 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -1,5 +1,58 @@ //Largely beneficial effects go here, even if they have drawbacks. An example is provided in Shadow Mend. +/datum/status_effect/his_grace + id = "his_grace" + duration = -1 + tick_interval = 4 + alert_type = /obj/screen/alert/status_effect/his_grace + var/bloodlust = 0 + +/obj/screen/alert/status_effect/his_grace + name = "His Grace" + desc = "His Grace hungers, and you must feed Him." + icon_state = "his_grace" + alerttooltipstyle = "hisgrace" + +/obj/screen/alert/status_effect/his_grace/MouseEntered(location, control, params) + desc = initial(desc) + var/datum/status_effect/his_grace/HG = attached_effect + desc += "
Current Bloodthirst: [HG.bloodlust]\ +
Becomes undroppable at [HIS_GRACE_FAMISHED]\ +
Will consume you at [HIS_GRACE_CONSUME_OWNER]" + ..() + +/datum/status_effect/his_grace/on_apply() + add_attack_logs(owner, owner, "gained His Grace's stun immunity", ATKLOG_ALL) + owner.add_stun_absorption("hisgrace", INFINITY, 3, null, "His Grace protects you from the stun!") + return ..() + +/datum/status_effect/his_grace/tick() + bloodlust = 0 + var/graces = 0 + var/list/held_items = list() + held_items += owner.l_hand + held_items += owner.r_hand + for(var/obj/item/his_grace/HG in held_items) + if(HG.bloodthirst > bloodlust) + bloodlust = HG.bloodthirst + if(HG.awakened) + graces++ + if(!graces) + owner.apply_status_effect(STATUS_EFFECT_HISWRATH) + qdel(src) + return + var/grace_heal = bloodlust * 0.05 + owner.adjustBruteLoss(-grace_heal) + owner.adjustFireLoss(-grace_heal) + owner.adjustToxLoss(-grace_heal) + owner.adjustOxyLoss(-(grace_heal * 2)) + owner.adjustCloneLoss(-grace_heal) + +/datum/status_effect/his_grace/on_remove() + add_attack_logs(owner, owner, "lost His Grace's stun immunity", ATKLOG_ALL) + if(islist(owner.stun_absorption) && owner.stun_absorption["hisgrace"]) + owner.stun_absorption -= "hisgrace" + /datum/status_effect/shadow_mend id = "shadow_mend" duration = 30 diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index d8b5e4d9cbe..498bb042497 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -1,5 +1,28 @@ //OTHER DEBUFFS +/datum/status_effect/his_wrath //does minor damage over time unless holding His Grace + id = "his_wrath" + duration = -1 + tick_interval = 4 + alert_type = /obj/screen/alert/status_effect/his_wrath + +/obj/screen/alert/status_effect/his_wrath + name = "His Wrath" + desc = "You fled from His Grace instead of feeding Him, and now you suffer." + icon_state = "his_grace" + alerttooltipstyle = "hisgrace" + +/datum/status_effect/his_wrath/tick() + var/list/held_items = list() + held_items += owner.l_hand + held_items += owner.r_hand + for(var/obj/item/his_grace/HG in held_items) + qdel(src) + return + owner.adjustBruteLoss(0.1) + owner.adjustFireLoss(0.1) + owner.adjustToxLoss(0.2) + /datum/status_effect/cultghost //is a cult ghost and can't use manifest runes id = "cult_ghost" duration = -1 diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index a70a81bb285..d4a97bc16e1 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -412,28 +412,6 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY cost = 80 containername = "combat shotgun crate" -/datum/supply_packs/security/armory/buckshotammo - name = "Buckshot Ammo Crate" - contains = list(/obj/item/ammo_box/shotgun/buck, - /obj/item/storage/box/buck, - /obj/item/storage/box/buck, - /obj/item/storage/box/buck, - /obj/item/storage/box/buck, - /obj/item/storage/box/buck) - cost = 45 - containername = "buckshot ammo crate" - -/datum/supply_packs/security/armory/slugammo - name = "Slug Ammo Crate" - contains = list(/obj/item/ammo_box/shotgun, - /obj/item/storage/box/slug, - /obj/item/storage/box/slug, - /obj/item/storage/box/slug, - /obj/item/storage/box/slug, - /obj/item/storage/box/slug) - cost = 45 - containername = "slug ammo crate" - /datum/supply_packs/security/armory/expenergy name = "Energy Guns Crate" contains = list(/obj/item/gun/energy/gun, diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index b2eb0ba224d..4e59d8ad6dd 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -257,10 +257,13 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) job = list("Chaplain") /datum/uplink_item/jobspecific/artistic_toolbox - name = "Artistic Toolbox" - desc = "An accursed toolbox that grants its followers extreme power at the cost of requiring repeated sacrifices to it. If sacrifices are not provided, it will turn on its follower." - reference = "HGAT" - item = /obj/item/storage/toolbox/green/memetic + name = "His Grace" + desc = "An incredibly dangerous weapon recovered from a station overcome by the grey tide. Once activated, He will thirst for blood and must be used to kill to sate that thirst. \ + His Grace grants gradual regeneration and complete stun immunity to His wielder, but be wary: if He gets too hungry, He will become impossible to drop and eventually kill you if not fed. \ + However, if left alone for long enough, He will fall back to slumber. \ + To activate His Grace, simply unlatch Him." + reference = "HG" + item = /obj/item/his_grace cost = 20 job = list("Chaplain") surplus = 0 //No lucky chances from the crate; if you get this, this is ALL you're getting @@ -1171,6 +1174,15 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 4 excludefrom = list(/datum/game_mode/nuclear) +/datum/uplink_item/stealthy_tools/voice_modulator + name = "Chameleon Voice Modulator Mask" + desc = "A syndicate tactical mask equipped with chameleon technology and a sound modulator for disguising your voice. \ + While the mask is active, your voice will sound unrecognizable to others" + reference = "CVMM" + item = /obj/item/clothing/mask/gas/voice_modulator/chameleon + cost = 1 + excludefrom = list(/datum/game_mode/nuclear) + /datum/uplink_item/stealthy_tools/chameleon/nuke reference = "NCHAM" cost = 6 diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 7232239d6f5..bac3f4c3349 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -420,6 +420,7 @@ if(spin && !no_spin && !no_spin_thrown) SpinAnimation(5, 1) + SEND_SIGNAL(src, COMSIG_MOVABLE_POST_THROW, TT, spin) SSthrowing.processing[src] = TT TT.tick() diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm index f315d79eb99..38dfbfab5d4 100644 --- a/code/game/gamemodes/changeling/traitor_chan.dm +++ b/code/game/gamemodes/changeling/traitor_chan.dm @@ -23,7 +23,7 @@ secondary_enemies = CEILING((secondary_enemies_scaling * num_players()), 1) for(var/mob/new_player/player in GLOB.player_list) - if((player.mind in possible_changelings) && (player.client.prefs.species in secondary_protected_species)) + if((player.mind in possible_changelings) && (player.client.prefs.active_character.species in secondary_protected_species)) possible_changelings -= player.mind if(possible_changelings.len > 0) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 7411622d358..fe0fe6447ba 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -251,7 +251,7 @@ // Get a list of all the people who want to be the antagonist for this round, except those with incompatible species for(var/mob/new_player/player in players) if(!player.client.skip_antag) - if((role in player.client.prefs.be_special) && !(player.client.prefs.species in protected_species)) + if((role in player.client.prefs.be_special) && !(player.client.prefs.active_character.species in protected_species)) player_draft_log += "[player.key] had [roletext] enabled, so we are drafting them." candidates += player.mind players -= player diff --git a/code/game/gamemodes/intercept_report.dm b/code/game/gamemodes/intercept_report.dm index aaf5dd1eea7..7b3fd4d52fc 100644 --- a/code/game/gamemodes/intercept_report.dm +++ b/code/game/gamemodes/intercept_report.dm @@ -110,7 +110,7 @@ /datum/intercept_text/proc/get_suspect() var/list/dudes = list() for(var/mob/living/carbon/human/man in GLOB.player_list) - if(man.client && man.client.prefs.nanotrasen_relation == "Opposed") + if(man.client && man.client.prefs.active_character.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 SSticker.mode.protected_jobs) || (man.mind.assigned_role in SSticker.mode.restricted_jobs)) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index 1ace6f6a836..6aef09163d3 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -279,14 +279,6 @@ synd_mob.equip_to_slot_or_del(U, slot_in_backpack) if(synd_mob.dna.species) - - /* - Incase anyone ever gets the burning desire to have nukeops with randomized apperances. -- Dave - synd_mob.gender = pick(MALE, FEMALE) // Randomized appearances for the nukeops. - var/datum/preferences/pref = new() - A.randomize_appearance_for(synd_mob) - */ - var/race = synd_mob.dna.species.name switch(race) diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index e4d3aecd279..47c41d841fe 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -507,7 +507,7 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) if(SSticker.current_state == GAME_STATE_SETTING_UP) for(var/mob/new_player/P in GLOB.player_list) if(P.client && P.ready && P.mind != owner) - if(P.client.prefs && (P.client.prefs.species == "Machine")) // Special check for species that can't be absorbed. No better solution. + if(P.client.prefs && (P.client.prefs.active_character.species == "Machine")) // Special check for species that can't be absorbed. No better solution. continue n_p++ else if(SSticker.current_state == GAME_STATE_PLAYING) diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm index 3b491765919..c764028ac41 100644 --- a/code/game/gamemodes/shadowling/shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm @@ -418,7 +418,7 @@ qdel(B) /datum/reagent/shadowling_blindness_smoke //Blinds non-shadowlings, heals shadowlings/thralls - name = "odd black liquid" + name = "Odd black liquid" id = "blindness_smoke" description = "<::ERROR::> CANNOT ANALYZE REAGENT <::ERROR::>" color = "#000000" //Complete black (RGB: 0, 0, 0) diff --git a/code/game/gamemodes/vampire/traitor_vamp.dm b/code/game/gamemodes/vampire/traitor_vamp.dm index 9eac23187ca..eea069b3f15 100644 --- a/code/game/gamemodes/vampire/traitor_vamp.dm +++ b/code/game/gamemodes/vampire/traitor_vamp.dm @@ -24,7 +24,7 @@ secondary_enemies = CEILING((secondary_enemies_scaling * num_players()), 1) for(var/mob/new_player/player in GLOB.player_list) - if((player.mind in possible_vampires) && (player.client.prefs.species in secondary_protected_species)) + if((player.mind in possible_vampires) && (player.client.prefs.active_character.species in secondary_protected_species)) possible_vampires -= player.mind if(possible_vampires.len > 0) diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index 259de282382..ddace2bf4ed 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -347,9 +347,9 @@ GLOBAL_LIST_EMPTY(multiverse) /obj/item/multisword/proc/spawn_copy(client/C, turf/T, mob/user) var/mob/living/carbon/human/M = new/mob/living/carbon/human(T) if(duplicate_self) - user.client.prefs.copy_to(M) + user.client.prefs.active_character.copy_to(M) else - C.prefs.copy_to(M) + C.prefs.active_character.copy_to(M) M.key = C.key M.mind.name = user.real_name to_chat(M, "You are an alternate version of [user.real_name] from another universe! Help [user.p_them()] accomplish [user.p_their()] goals at all costs.") diff --git a/code/game/gamemodes/wizard/raginmages.dm b/code/game/gamemodes/wizard/raginmages.dm index d50a6200764..88cd471b372 100644 --- a/code/game/gamemodes/wizard/raginmages.dm +++ b/code/game/gamemodes/wizard/raginmages.dm @@ -147,7 +147,7 @@ if(!G || !G.key) return // Let's not steal someone's soul here var/mob/living/carbon/human/new_character = new(pick(GLOB.latejoin)) - G.client.prefs.copy_to(new_character) + G.client.prefs.active_character.copy_to(new_character) new_character.key = G.key return new_character diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index 67ad3a2ebae..0eef296334d 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -1029,7 +1029,7 @@ var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead magichead.flags |= NODROP | DROPDEL //curses! magichead.flags_inv = null //so you can still see their face - magichead.voicechange = 1 //NEEEEIIGHH + magichead.voicechange = TRUE //NEEEEIIGHH if(!user.unEquip(user.wear_mask)) qdel(user.wear_mask) user.equip_to_slot_if_possible(magichead, slot_wear_mask, TRUE, TRUE) diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm index c39e1ff555f..7922cb721f7 100644 --- a/code/game/jobs/job/job.dm +++ b/code/game/jobs/job/job.dm @@ -123,7 +123,7 @@ var/list/prohibited_disabilities = list(DISABILITY_FLAG_BLIND, DISABILITY_FLAG_DEAF, DISABILITY_FLAG_MUTE, DISABILITY_FLAG_DIZZY) for(var/i = 1, i < prohibited_disabilities.len, i++) var/this_disability = prohibited_disabilities[i] - if(C.prefs.disabilities & this_disability) + if(C.prefs.active_character.disabilities & this_disability) return 1 return 0 @@ -173,8 +173,8 @@ if(box && H.dna.species.speciesbox) box = H.dna.species.speciesbox - if(allow_loadout && H.client && (H.client.prefs.loadout_gear && H.client.prefs.loadout_gear.len)) - for(var/gear in H.client.prefs.loadout_gear) + if(allow_loadout && H.client && length(H.client.prefs.active_character.loadout_gear)) + for(var/gear in H.client.prefs.active_character.loadout_gear) var/datum/gear/G = GLOB.gear_datums[gear] if(G) var/permitted = FALSE @@ -212,7 +212,7 @@ 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.loadout_gear[G.display_name])) + var/atom/placed_in = H.equip_or_collect(G.spawn_item(null, H.client.prefs.active_character.loadout_gear[G.display_name])) if(istype(placed_in)) if(isturf(placed_in)) to_chat(H, "Placing [G.display_name] on [placed_in]!") diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index 78895d0d099..1e6efe52565 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -462,6 +462,17 @@ drop_computer_parts() return ..() // will qdel the frame +/obj/structure/computerframe/AltClick(mob/user) + if(user.incapacitated()) + to_chat(user, "You can't do that right now!") + return + if(!Adjacent(user)) + return + if(anchored) + to_chat(user, "The frame is anchored to the floor!") + return + setDir(turn(dir, 90)) + /obj/structure/computerframe/obj_break(damage_flag) deconstruct() @@ -544,7 +555,8 @@ if(STATE_GLASS) to_chat(user, "You connect the monitor.") I.play_tool_sound(src) - var/B = new circuit.build_path(loc) + var/obj/machinery/computer/B = new circuit.build_path(loc) + B.setDir(dir) if(istype(circuit, /obj/item/circuitboard/supplycomp)) var/obj/machinery/computer/supplycomp/SC = B var/obj/item/circuitboard/supplycomp/C = circuit diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm index c4af2849947..a5c01d63ae4 100644 --- a/code/game/objects/effects/spawners/lootdrop.dm +++ b/code/game/objects/effects/spawners/lootdrop.dm @@ -144,6 +144,8 @@ /obj/item/stamp/chameleon = 2, /obj/item/clothing/shoes/chameleon/noslip = 5, /obj/item/clothing/mask/chameleon = 2, + /obj/item/clothing/mask/gas/voice_modulator = 2, + /obj/item/clothing/mask/gas/voice_modulator/chameleon = 2, /obj/item/dnascrambler = 1, /obj/item/storage/backpack/satchel_flat = 2, /obj/item/storage/toolbox/syndicate = 2, @@ -156,7 +158,7 @@ /obj/item/storage/secure/briefcase/syndie = 2, /obj/item/storage/fancy/cigarettes/cigpack_syndicate = 2, /obj/item/storage/pill_bottle/fakedeath = 2, - "" = 68 + "" = 64 // Reduce this number if you add things above. Make sure all the numbers in the list add to 100 EXACTLY ) /obj/effect/spawner/lootdrop/crate_spawner // for ruins diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index aa637dc0332..b04457ac866 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -118,7 +118,7 @@ else if(issilicon(M)) add_attack_logs(user, M, "Flashed with [src]") if(M.flash_eyes(affect_silicon = 1)) - M.Weaken(rand(5,10)) + M.Weaken(rand(4, 6)) user.visible_message("[user] overloads [M]'s sensors with [src]!", "You overload [M]'s sensors with [src]!") return 1 user.visible_message("[user] fails to blind [M] with [src]!", "You fail to blind [M] with [src]!") diff --git a/code/game/objects/items/devices/voice.dm b/code/game/objects/items/devices/voice.dm index 43a95ae86d7..c18af96333d 100644 --- a/code/game/objects/items/devices/voice.dm +++ b/code/game/objects/items/devices/voice.dm @@ -1,6 +1,6 @@ /obj/item/voice_changer name = "voice changer" - desc = "A voice scrambling module." + desc = "A voice mimicking module." icon = 'icons/obj/device.dmi' icon_state = "voice_changer_off" @@ -42,3 +42,9 @@ voice = sanitize(copytext(chosen_voice, 1, MAX_MESSAGE_LEN)) to_chat(user, "You are now mimicking [voice].") + +/obj/item/voice_changer/voice_modulator + name = "voice modulator" + desc = "A voice scrambling module." + voice = "Unknown" + actions_types = list(/datum/action/item_action/voice_changer/toggle) diff --git a/code/game/objects/items/his_grace.dm b/code/game/objects/items/his_grace.dm new file mode 100644 index 00000000000..e86d82fef36 --- /dev/null +++ b/code/game/objects/items/his_grace.dm @@ -0,0 +1,263 @@ +//His Grace is a very special weapon granted only to traitor chaplains. +//When awakened, He thirsts for blood and begins ticking a "bloodthirst" counter. +//The wielder of His Grace is immune to stuns and gradually heals. +//If the wielder fails to feed His Grace in time, He will devour them and become incredibly aggressive. +//Leaving His Grace alone for some time will reset His thirst and put Him to sleep. +//Using His Grace effectively requires extreme speed and care. + +/obj/item/his_grace + name = "artistic toolbox" + desc = "A toolbox painted bright green. Looking at it makes you feel uneasy." + icon = 'icons/obj/storage.dmi' + icon_state = "green" + item_state = "artistic_toolbox" + lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi' + w_class = WEIGHT_CLASS_GIGANTIC + force = 12 + attack_verb = list("robusted") + hitsound = 'sound/weapons/smash.ogg' + drop_sound = 'sound/items/handling/toolbox_drop.ogg' + pickup_sound = 'sound/items/handling/toolbox_pickup.ogg' + var/awakened = FALSE + var/bloodthirst = HIS_GRACE_SATIATED + var/prev_bloodthirst = HIS_GRACE_SATIATED + var/force_bonus = 0 + var/ascended = FALSE + var/victims_needed = 25 + var/ascend_bonus = 15 + +/obj/item/his_grace/Initialize(mapload) + . = ..() + START_PROCESSING(SSprocessing, src) + GLOB.poi_list |= src + RegisterSignal(src, COMSIG_MOVABLE_POST_THROW, .proc/move_gracefully) + update_icon() + +/obj/item/his_grace/Destroy() + STOP_PROCESSING(SSprocessing, src) + for(var/mob/living/L in src) + L.forceMove(get_turf(src)) + GLOB.poi_list -= src + return ..() + +/obj/item/his_grace/update_icon() + icon_state = ascended ? "gold" : "green" + item_state = ascended ? "toolbox_gold" : "artistic_toolbox" + cut_overlays() + if(ascended) + add_overlay("triple_latch") + else if(awakened) + add_overlay("single_latch_open") + else + add_overlay("single_latch") + +/obj/item/his_grace/attack_self(mob/living/user) + if(!awakened) + INVOKE_ASYNC(src, .proc/awaken, user) + +/obj/item/his_grace/attack(mob/living/M, mob/user) + if(awakened && M.stat) + consume(M) + else + ..() + +/obj/item/his_grace/can_be_pulled(user, grab_state, force, show_message = FALSE) //you can't pull his grace + return FALSE + +/obj/item/his_grace/examine(mob/user) + . = ..() + if(awakened) + switch(bloodthirst) + if(HIS_GRACE_SATIATED to HIS_GRACE_PECKISH) + . += "[src] isn't very hungry. Not yet." + if(HIS_GRACE_PECKISH to HIS_GRACE_HUNGRY) + . += "[src] would like a snack." + if(HIS_GRACE_HUNGRY to HIS_GRACE_FAMISHED) + . += "[src] is quite hungry now." + if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING) + . += "[src] is openly salivating at the sight of you. Be careful." + if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER) + . += "You walk a fine line. [src] is very close to devouring you." + if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP) + . += "[src] is shaking violently and staring directly at you." + else + . += "[src] is latched closed." + +/obj/item/his_grace/relaymove(mob/living/user, direction) //Allows changelings, etc. to climb out of Him after they revive, provided He isn't active + if(!awakened) + user.forceMove(get_turf(src)) + user.visible_message("[user] scrambles out of [src]!", "You climb out of [src]!") + +/obj/item/his_grace/process() + if(!bloodthirst) + drowse() + return + if(bloodthirst < HIS_GRACE_CONSUME_OWNER && !ascended) + adjust_bloodthirst(1 + FLOOR(length(contents) * 0.5, 1)) //Maybe adjust this? + else + adjust_bloodthirst(1) //don't cool off rapidly once we're at the point where His Grace consumes all. + var/mob/living/master = get_atom_on_turf(src, /mob/living) + var/list/held_items = list() + if(istype(master)) + held_items += master.l_hand + held_items += master.r_hand + if(istype(master) && (src in held_items)) + switch(bloodthirst) + if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP) + master.visible_message("[src] turns on [master]!", "[src] turns on you!") + do_attack_animation(master, null, src) + master.emote("scream") + master.remove_status_effect(STATUS_EFFECT_HISGRACE) + flags &= ~NODROP + master.Weaken(3) + master.adjustBruteLoss(1000) + playsound(master, 'sound/effects/splat.ogg', 100, FALSE) + else + master.apply_status_effect(STATUS_EFFECT_HISGRACE) + return + forceMove(get_turf(src)) //no you can't put His Grace in a locker you just have to deal with Him + if(bloodthirst < HIS_GRACE_CONSUME_OWNER) + return + if(bloodthirst >= HIS_GRACE_FALL_ASLEEP) + drowse() + return + var/list/targets = list() + for(var/mob/living/L in oview(2, src)) + targets += L + if(!length(targets)) + return + var/mob/living/L = pick(targets) + step_to(src, L) + if(Adjacent(L)) + if(!L.stat) + L.visible_message("[src] lunges at [L]!", "[src] lunges at you!") + do_attack_animation(L, null, src) + playsound(L, 'sound/weapons/smash.ogg', 50, TRUE) + playsound(L, 'sound/misc/desceration-01.ogg', 50, TRUE) + L.adjustBruteLoss(force) + adjust_bloodthirst(-5) //Don't stop attacking they're right there! + else + consume(L) + +/obj/item/his_grace/proc/awaken(mob/user) //Good morning, Mr. Grace. + if(awakened) + return + awakened = TRUE + user.visible_message("[src] begins to rattle. He thirsts.", "You flick [src]'s latch up. You hope this is a good idea.") + name = "His Grace" + desc = "A bloodthirsty artifact created by a profane rite." + gender = MALE + adjust_bloodthirst(1) + force_bonus = HIS_GRACE_FORCE_BONUS * length(contents) + playsound(user, 'sound/effects/pope_entry.ogg', 100) + update_icon() + move_gracefully() + +/obj/item/his_grace/proc/move_gracefully() + SIGNAL_HANDLER + + if(!awakened) + return + animate_rumble(src) + +/obj/item/his_grace/proc/drowse() //Good night, Mr. Grace. + if(!awakened || ascended) + return + var/turf/T = get_turf(src) + T.visible_message("[src] slowly stops rattling and falls still, His latch snapping shut.") + playsound(loc, 'sound/weapons/batonextend.ogg', 100, TRUE) + name = initial(name) + desc = initial(desc) + animate(src, transform = matrix()) + gender = initial(gender) + force = initial(force) + force_bonus = initial(force_bonus) + awakened = FALSE + bloodthirst = 0 + update_icon() + +/obj/item/his_grace/proc/consume(mob/living/meal) //Here's your dinner, Mr. Grace. + if(!meal) + return + var/victims = 0 + meal.visible_message("[src] swings open and devours [meal]!", "[src] consumes you!") + meal.adjustBruteLoss(300) + playsound(meal, 'sound/misc/desceration-02.ogg', 75, TRUE) + playsound(src, 'sound/items/eatfood.ogg', 100, TRUE) + meal.forceMove(src) + force_bonus += HIS_GRACE_FORCE_BONUS + prev_bloodthirst = bloodthirst + if(prev_bloodthirst < HIS_GRACE_CONSUME_OWNER) + bloodthirst = max(length(contents), 1) //Never fully sated, and His hunger will only grow. + else + bloodthirst = HIS_GRACE_CONSUME_OWNER + for(var/mob/living/C in contents) + if(C.mind) + victims++ + if(victims >= victims_needed) + ascend() + update_stats() + +/obj/item/his_grace/proc/adjust_bloodthirst(amt) + prev_bloodthirst = bloodthirst + if(prev_bloodthirst < HIS_GRACE_CONSUME_OWNER && !ascended) + bloodthirst = clamp(bloodthirst + amt, HIS_GRACE_SATIATED, HIS_GRACE_CONSUME_OWNER) + else if(!ascended) + bloodthirst = clamp(bloodthirst + amt, HIS_GRACE_CONSUME_OWNER, HIS_GRACE_FALL_ASLEEP) + update_stats() + +/obj/item/his_grace/proc/update_stats() + flags &= ~NODROP + var/mob/living/master = get_atom_on_turf(src, /mob/living) + switch(bloodthirst) + if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP) + if(HIS_GRACE_CONSUME_OWNER > prev_bloodthirst) + master.visible_message("[src] enters a frenzy!") + if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER) + flags |= NODROP + if(HIS_GRACE_STARVING > prev_bloodthirst) + master.visible_message("[src] is starving!", "[src]'s bloodlust overcomes you. [src] must be fed, or you will become His meal.\ + [force_bonus < 15 ? " And still, His power grows.":""]") + force_bonus = max(force_bonus, 15) + if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING) + flags |= NODROP + if(HIS_GRACE_FAMISHED > prev_bloodthirst) + master.visible_message("[src] is very hungry!", "Spines sink into your hand. [src] must feed immediately.\ + [force_bonus < 10 ? " His power grows.":""]") + force_bonus = max(force_bonus, 10) + if(prev_bloodthirst >= HIS_GRACE_STARVING) + master.visible_message("[src] is now only very hungry!", "Your bloodlust recedes.") + if(HIS_GRACE_HUNGRY to HIS_GRACE_FAMISHED) + if(HIS_GRACE_HUNGRY > prev_bloodthirst) + master.visible_message("[src] is getting hungry.", "You feel [src]'s hunger within you.\ + [force_bonus < 5 ? " His power grows.":""]") + force_bonus = max(force_bonus, 5) + if(prev_bloodthirst >= HIS_GRACE_FAMISHED) + master.visible_message("[src] is now only somewhat hungry.", "[src]'s hunger recedes a little...") + if(HIS_GRACE_PECKISH to HIS_GRACE_HUNGRY) + if(HIS_GRACE_PECKISH > prev_bloodthirst) + master.visible_message("[src] is feeling snackish.", "[src] begins to hunger.") + if(prev_bloodthirst >= HIS_GRACE_HUNGRY) + master.visible_message("[src] is now only a little peckish.", "[src]'s hunger recedes somewhat...") + if(HIS_GRACE_SATIATED to HIS_GRACE_PECKISH) + if(prev_bloodthirst >= HIS_GRACE_PECKISH) + master.visible_message("[src] is satiated.", "[src]'s hunger recedes...") + force = initial(force) + force_bonus + +/obj/item/his_grace/proc/ascend() + if(ascended) + return + force_bonus += ascend_bonus + desc = "A legendary toolbox and a distant artifact from The Age of Three Powers. On its three latches engraved are the words \"The Sun\", \"The Moon\", and \"The Stars\". The entire toolbox has the words \"The World\" engraved into its sides." + icon_state = "his_grace_ascended" + item_state = "toolbox_gold" + ascended = TRUE + update_icon() + playsound(src, 'sound/effects/his_grace_ascend.ogg', 100) + var/mob/living/carbon/human/master = loc + if(istype(master)) + master.visible_message("Gods will be watching.") + name = "[master]'s mythical toolbox of three powers" + master.update_inv_l_hand() + master.update_inv_r_hand() diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index f1487a09986..52877118b88 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -31,6 +31,115 @@ playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1) add_attack_logs(user, M, "Stunned with [src] ([uppertext(user.a_intent)])") +#define CYBORG_HUGS 0 +#define CYBORG_HUG 1 +#define CYBORG_SHOCK 2 +#define CYBORG_CRUSH 3 + +/obj/item/borg/cyborghug + name = "hugging module" + icon_state = "hugmodule" + desc = "For when a someone really needs a hug." + var/mode = CYBORG_HUGS //0 = Hugs 1 = "Hug" 2 = Shock 3 = CRUSH + var/ccooldown = 0 + var/scooldown = 0 + var/shockallowed = FALSE //Can it be a stunarm when emagged. Only PK borgs get this by default. + +/obj/item/borg/cyborghug/attack_self(mob/living/user) + if(isrobot(user)) + var/mob/living/silicon/robot/P = user + if(P.emagged && shockallowed) + if(mode < CYBORG_CRUSH) + mode++ + else + mode = CYBORG_HUGS + else if(mode < CYBORG_HUG) + mode++ + else + mode = CYBORG_HUGS + switch(mode) + if(CYBORG_HUGS) + to_chat(user, "Power reset. Hugs!") + if(CYBORG_HUG) + to_chat(user, "Power increased!") + if(CYBORG_SHOCK) + to_chat(user, "BZZT. Electrifying arms...") + if(CYBORG_CRUSH) + to_chat(user, "ERROR: ARM ACTUATORS OVERLOADED.") + +/obj/item/borg/cyborghug/attack(mob/living/M, mob/living/silicon/robot/user, params) + if(M == user) + return + switch(mode) + if(CYBORG_HUGS) + if(M.health >= 0) + if(isanimal(M)) + var/list/modifiers = params2list(params) + M.attack_hand(user, modifiers) //This enables borgs to get the floating heart icon and mob emote from simple_animal's that have petbonus == true. + return + if(user.zone_selected == BODY_ZONE_HEAD) + user.visible_message("[user] playfully boops [M] on the head!", "You playfully boop [M] on the head!") + user.do_attack_animation(M, ATTACK_EFFECT_BOOP) + playsound(loc, 'sound/weapons/tap.ogg', 50, TRUE, -1) + else if(ishuman(M)) + if(user.lying) + user.visible_message("[user] shakes [M] trying to get [M.p_them()] up!", "You shake [M] trying to get [M.p_them()] up!") + else + user.visible_message("[user] hugs [M] to make [M.p_them()] feel better!", "You hug [M] to make [M.p_them()] feel better!") + if(M.resting) + M.resting = FALSE + M.update_canmove() + else + user.visible_message("[user] pets [M]!", "You pet [M]!") + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) + if(CYBORG_HUG) + if(M.health >= 0) + if(ishuman(M)) + if(M.lying) + user.visible_message("[user] shakes [M] trying to get [M.p_them()] up!", "You shake [M] trying to get [M.p_them()] up!") + else if(user.zone_selected == BODY_ZONE_HEAD) + user.visible_message("[user] bops [M] on the head!", "You bop [M] on the head!") + user.do_attack_animation(M, ATTACK_EFFECT_PUNCH) + else + user.visible_message("[user] hugs [M] in a firm bear-hug! [M] looks uncomfortable...", "You hug [M] firmly to make [M.p_them()] feel better! [M] looks uncomfortable...") + if(M.resting) + M.resting = FALSE + M.update_canmove() + else + user.visible_message("[user] bops [M] on the head!", "You bop [M] on the head!") + playsound(loc, 'sound/weapons/tap.ogg', 50, TRUE, -1) + if(CYBORG_SHOCK) + if(scooldown < world.time) + if(M.health >= 0) + if(ishuman(M)) + M.electrocute_act(5, "[user]", flags = SHOCK_NOGLOVES) + user.visible_message("[user] electrocutes [M] with [user.p_their()] touch!", "You electrocute [M] with your touch!") + else + if(!isrobot(M)) + M.adjustFireLoss(10) + user.visible_message("[user] shocks [M]!", "You shock [M]!") + else + user.visible_message("[user] shocks [M]. It does not seem to have an effect", "You shock [M] to no effect.") + playsound(loc, 'sound/effects/sparks2.ogg', 50, TRUE, -1) + user.cell.use(500) + scooldown = world.time + 20 + if(CYBORG_CRUSH) + if(ccooldown < world.time) + if(M.health >= 0) + if(ishuman(M)) + user.visible_message("[user] crushes [M] in [user.p_their()] grip!", "You crush [M] in your grip!") + else + user.visible_message("[user] crushes [M]!", "You crush [M]!") + playsound(loc, 'sound/weapons/smash.ogg', 50, TRUE, -1) + M.adjustBruteLoss(15) + user.cell.use(300) + ccooldown = world.time + 10 + +#undef CYBORG_HUGS +#undef CYBORG_HUG +#undef CYBORG_SHOCK +#undef CYBORG_CRUSH + /obj/item/borg/overdrive name = "Overdrive" icon = 'icons/obj/decals.dmi' diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 4b7ec1b350b..f2e006e24c8 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -1066,6 +1066,50 @@ w_class = WEIGHT_CLASS_SMALL resistance_flags = FLAMMABLE +/obj/item/toy/windup_toolbox + name = "windup toolbox" + desc = "A replica toolbox that rumbles when you turn the key." + icon = 'icons/obj/storage.dmi' + icon_state = "green" + item_state = "artistic_toolbox" + lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi' + hitsound = 'sound/weapons/smash.ogg' + drop_sound = 'sound/items/handling/toolbox_drop.ogg' + pickup_sound = 'sound/items/handling/toolbox_pickup.ogg' + attack_verb = list("robusted") + var/active = FALSE + +/obj/item/toy/windup_toolbox/Initialize(mapload) + . = ..() + update_icon() + +/obj/item/toy/windup_toolbox/update_icon() + ..() + cut_overlays() + if(active) + add_overlay("single_latch_open") + else + add_overlay("single_latch") + +/obj/item/toy/windup_toolbox/attack_self(mob/user) + if(!active) + to_chat(user, "You wind up [src], it begins to rumble.") + active = TRUE + update_icon() + playsound(src, 'sound/effects/pope_entry.ogg', 100) + animate_rumble(src) + addtimer(CALLBACK(src, .proc/stopRumble), 60 SECONDS) + else + to_chat(user, "[src] is already active!") + +/obj/item/toy/windup_toolbox/proc/stopRumble() + active = FALSE + update_icon() + visible_message("[src] slowly stops rattling and falls still, its latch snapping shut.") //subtle difference + playsound(loc, 'sound/weapons/batonextend.ogg', 100, TRUE) + animate(src, transform = matrix()) + /* * Toy/fake flash */ diff --git a/code/game/objects/items/weapons/storage/artistic_toolbox.dm b/code/game/objects/items/weapons/storage/artistic_toolbox.dm deleted file mode 100644 index 3fbaa1d468d..00000000000 --- a/code/game/objects/items/weapons/storage/artistic_toolbox.dm +++ /dev/null @@ -1,223 +0,0 @@ -/obj/item/storage/toolbox/green - name = "artistic toolbox" - desc = "A metal container designed to hold various tools. This variety holds art supplies." - icon_state = "green" - item_state = "artistic_toolbox" - -/obj/item/storage/toolbox/green/memetic - name = "artistic toolbox" - desc = "His Grace." - force = 5 - throwforce = 10 - origin_tech = "combat=4;engineering=4;syndicate=2" - actions_types = list(/datum/action/item_action/toggle) - var/list/servantlinks = list() - var/hunger = 0 - var/hunger_message_level = 0 - var/mob/living/carbon/human/original_owner = null - var/activated = FALSE - -/obj/item/storage/toolbox/green/memetic/ui_action_click(mob/user) - if(user.HasDisease(new /datum/disease/memetic_madness(0))) - var/obj/item/storage/toolbox/green/memetic/M = user.get_active_hand() - if(istype(M)) - to_chat(user, "His Grace [flags & NODROP ? "releases from" : "binds to"] your hand!") - flags ^= NODROP - else if(!activated && loc == user) - if(link_user(user)) - to_chat(user, "Call to His Grace again if you wish it bound to your hand!") - else - to_chat(user, "You can't seem to understand what this does.") - - -/obj/item/storage/toolbox/green/memetic/attack_hand(mob/living/carbon/user) - if(!activated && loc == user) - link_user(user) - return - ..() - -/obj/item/storage/toolbox/green/memetic/proc/link_user(mob/living/carbon/user) - if(ishuman(user) && !user.HasDisease(new /datum/disease/memetic_madness(0))) - activated = TRUE - user.ForceContractDisease(new /datum/disease/memetic_madness(0)) - for(var/datum/disease/memetic_madness/DD in user.viruses) - DD.progenitor = src - servantlinks.Add(DD) - break - force += 4 - throwforce += 4 - SEND_SOUND(user, sound('sound/goonstation/effects/screech.ogg')) - shake_camera(user, 20, 1) - var/acount = 0 - var/amax = rand(10, 15) - var/up_and_down - var/asize = 1 - while(acount <= amax) - up_and_down += "a" - if(acount > (amax * 0.5)) - asize-- - else - asize++ - acount++ - to_chat(user, "[up_and_down]") - to_chat(user, "His Grace accepts thee, spread His will! All who look close to the Enlightened may share His gifts.") - original_owner = user - return TRUE - return FALSE - -/obj/item/storage/toolbox/green/memetic/attackby(obj/item/I, mob/user) - if(activated) - if(istype(I, /obj/item/grab)) - var/obj/item/grab/G = I - var/mob/living/victim = G.affecting - if(!user.HasDisease(new /datum/disease/memetic_madness(0))) - to_chat(user, "You can't seem to find the latch to open this.") - return - if(!victim) - return - if(!victim.stat && !victim.restrained() && !victim.IsWeakened()) - to_chat(user, "They're moving too much to feed to His Grace!") - return - user.visible_message("[user] is trying to feed [victim] to [src]!") - if(!do_mob(user, victim, 30)) - return - - user.visible_message("[user] has fed [victim] to [src]!") - - consume(victim) - qdel(G) - - to_chat(user, "You have done well...") - force += 5 - throwforce += 5 - return - - return ..() - -/obj/item/storage/toolbox/green/memetic/proc/consume(mob/living/L) - if(!L) - return - hunger = 0 - hunger_message_level = 0 - playsound(loc, 'sound/goonstation/misc/burp_alien.ogg', 50, 0) - - if(L != original_owner) - var/list/equipped_items = L.get_equipped_items(TRUE) - if(L.l_hand) - equipped_items += L.l_hand - if(L.r_hand) - equipped_items += L.r_hand - if(equipped_items.len) - var/obj/item/storage/box/B = new(src) - B.name = "Box-'[L.real_name]'" - for(var/obj/item/SI in equipped_items) - L.unEquip(SI, TRUE) - SI.forceMove(B) - equipped_items.Cut() - - L.forceMove(src) - - L.emote("scream") - L.death() - L.ghostize() - if(L == original_owner) - L.unEquip(src, TRUE) - qdel(L) - var/obj/item/storage/toolbox/green/fake_toolbox = new(get_turf(src)) - fake_toolbox.desc = "It looks a lot duller than it used to." - qdel(src) - else - qdel(L) - -/obj/item/storage/toolbox/green/memetic/Destroy() - for(var/datum/disease/memetic_madness/D in servantlinks) - D.cure() - - servantlinks.Cut() - servantlinks = null - original_owner = null - visible_message("[src] screams!") - playsound(loc, 'sound/goonstation/effects/screech.ogg', 100, 1) - return ..() - -/datum/disease/memetic_madness - name = "Memetic Kill Agent" - max_stages = 4 - stage_prob = 8 - spread_text = "Non-Contagious" - spread_flags = SPECIAL - cure_text = "Unknown" - viable_mobtypes = list(/mob/living/carbon/human) - severity = BIOHAZARD - disease_flags = CAN_CARRY - spread_flags = NON_CONTAGIOUS - virus_heal_resistant = TRUE - var/obj/item/storage/toolbox/green/memetic/progenitor = null - -/datum/disease/memetic_madness/Destroy() - if(progenitor) - progenitor.servantlinks.Remove(src) - progenitor = null - if(affected_mob) - affected_mob.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE - return ..() - -/datum/disease/memetic_madness/stage_act() - ..() - if(!progenitor) //if someone admin spawns this, cure it right away; this should only ever be given directly from the toolbox itself. - cure() - return - if(progenitor in affected_mob.contents) - affected_mob.adjustOxyLoss(-5) - affected_mob.adjustBruteLoss(-12) - affected_mob.adjustFireLoss(-12) - affected_mob.adjustToxLoss(-5) - affected_mob.setStaminaLoss(0) - var/status = CANSTUN | CANWEAKEN | CANPARALYSE - affected_mob.status_flags &= ~status - affected_mob.AdjustDizzy(-10) - affected_mob.AdjustDrowsy(-10) - affected_mob.SetSleeping(0) - affected_mob.SetSlowed(0) - affected_mob.SetConfused(0) - stage = 1 - switch(progenitor.hunger) - if(10 to 60) - if(progenitor.hunger_message_level < 1) - progenitor.hunger_message_level = 1 - to_chat(affected_mob, "Feed Me the unclean ones...They will be purified...") - if(61 to 120) - if(progenitor.hunger_message_level < 2) - progenitor.hunger_message_level = 2 - to_chat(affected_mob, "I hunger for the flesh of the impure...") - if(121 to 210) - if(prob(10) && progenitor.hunger_message_level < 3) - progenitor.hunger_message_level = 3 - to_chat(affected_mob, "The hunger of your Master grows with every passing moment. Feed Me at once.") - if(211 to 399) - if(progenitor.hunger_message_level < 4) - progenitor.hunger_message_level = 4 - to_chat(affected_mob, "His Grace starves in your hands. Feed Me the unclean or suffer.") - if(400 to INFINITY) - affected_mob.visible_message("[progenitor] consumes [affected_mob] whole!") - progenitor.consume(affected_mob) - return - - progenitor.hunger += min(max((progenitor.force / 10), 1), 10) - - else - affected_mob.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE - - if(stage == 4) - if(get_dist(get_turf(progenitor), get_turf(affected_mob)) <= 7) - stage = 1 - return - if(prob(4)) - to_chat(affected_mob, "You are too far from His Grace...") - affected_mob.adjustToxLoss(5) - else if(prob(6)) - to_chat(affected_mob, "You feel weak.") - affected_mob.adjustBruteLoss(5) - - if(ismob(progenitor.loc)) - progenitor.hunger++ diff --git a/code/game/objects/items/weapons/storage/toolbox.dm b/code/game/objects/items/weapons/storage/toolbox.dm index db3e97b4154..6e52acb93df 100644 --- a/code/game/objects/items/weapons/storage/toolbox.dm +++ b/code/game/objects/items/weapons/storage/toolbox.dm @@ -132,3 +132,24 @@ new /obj/item/stack/cable_coil(src, 30, paramcolor = pickedcolor) new /obj/item/wirecutters(src) new /obj/item/multitool(src) + +/obj/item/storage/toolbox/artistic + name = "artistic toolbox" + desc = "A toolbox painted bright green. Why anyone would store art supplies in a toolbox is beyond you, but it has plenty of extra space." + icon_state = "green" + item_state = "artistic_toolbox" + w_class = WEIGHT_CLASS_GIGANTIC //Holds more than a regular toolbox! + max_combined_w_class = 20 + storage_slots = 10 + +/obj/item/storage/toolbox/artistic/populate_contents() + new /obj/item/storage/fancy/crayons(src) + new /obj/item/crowbar(src) + new /obj/item/stack/cable_coil(src) + new /obj/item/stack/cable_coil/yellow(src) + new /obj/item/stack/cable_coil/blue(src) + new /obj/item/stack/cable_coil/green(src) + new /obj/item/stack/cable_coil/pink(src) + new /obj/item/stack/cable_coil/orange(src) + new /obj/item/stack/cable_coil/cyan(src) + new /obj/item/stack/cable_coil/white(src) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 5e1d4036171..5b0ea16350c 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -130,7 +130,7 @@ GLOBAL_VAR_INIT(nologevent, 0) if(GLOB.configuration.url.forum_playerinfo_url) body += "WebInfo | " if(M.client) - if(check_watchlist(M.client.ckey)) + if(M.client.watchlisted) body += "Remove from Watchlist | " body += "Edit Watchlist Reason " else diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index 5d8196a8d88..8cbd56311dc 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -95,6 +95,24 @@ you will have to do something like if(client.holder.rights & R_ADMIN) yourself. to_chat(user, "Error: You are not an admin.") return 0 +// Basically the above proc but checks at a /client level +/proc/check_rights_client(rights_required, show_msg = TRUE, client/C) + if(C) + if(rights_required) + if(C.holder) + if(rights_required & C.holder.rights) + return TRUE + else + if(show_msg) + to_chat(C, "Error: You do not have sufficient rights to do that. You require one of the following flags:[rights2text(rights_required," ")].") + else + if(C.holder) + return TRUE + else + if(show_msg) + to_chat(C, "Error: You are not an admin.") + return FALSE + //probably a bit iffy - will hopefully figure out a better solution /proc/check_if_greater_rights_than(client/other) if(usr && usr.client) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 185f3343519..94b10cf04a7 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1361,7 +1361,7 @@ to_chat(usr, "[M] doesn't seem to have an active client.") return - if(M.flavor_text == "" && M.client.prefs.flavor_text == "") + if(M.flavor_text == "" && M.client.prefs.active_character.flavor_text == "") to_chat(usr, "[M] has no flavor text set.") return @@ -1375,8 +1375,8 @@ M.flavor_text = "" // Clear and save the DB character's flavor text - M.client.prefs.flavor_text = "" - M.client.prefs.save_character(M.client) + M.client.prefs.active_character.flavor_text = "" + M.client.prefs.active_character.save(M.client) else if(href_list["userandomname"]) if(!check_rights(R_ADMIN)) @@ -1399,12 +1399,12 @@ message_admins("[key_name_admin(usr)] has forced [key_name_admin(M)] to use a random name.") // Update the mob's name with a random one straight away - var/random_name = random_name(M.client.prefs.gender, M.client.prefs.species) + var/random_name = random_name(M.client.prefs.active_character.gender, M.client.prefs.active_character.species) M.rename_character(M.real_name, random_name) // Save that random name for next rounds - M.client.prefs.real_name = random_name - M.client.prefs.save_character(M.client) + M.client.prefs.active_character.real_name = random_name + M.client.prefs.active_character.save(M.client) else if(href_list["asays"]) if(!check_rights(R_ADMIN)) diff --git a/code/modules/admin/verbs/gimmick_team.dm b/code/modules/admin/verbs/gimmick_team.dm index 884569c96fa..c9d0c3a4363 100644 --- a/code/modules/admin/verbs/gimmick_team.dm +++ b/code/modules/admin/verbs/gimmick_team.dm @@ -63,9 +63,10 @@ for(var/mob/thisplayer in players_to_spawn) var/mob/living/carbon/human/H = new /mob/living/carbon/human(T) H.name = random_name(pick(MALE,FEMALE)) - var/datum/preferences/A = new() //Randomize appearance - A.real_name = H.name - A.copy_to(H) + var/datum/character_save/S = new //Randomize appearance + S.randomise() + S.real_name = H.name + S.copy_to(H) H.dna.ready_dna(H) H.mind_initialize() diff --git a/code/modules/admin/verbs/infiltratorteam_syndicate.dm b/code/modules/admin/verbs/infiltratorteam_syndicate.dm index 1199a8e5ea5..6917c95d3b9 100644 --- a/code/modules/admin/verbs/infiltratorteam_syndicate.dm +++ b/code/modules/admin/verbs/infiltratorteam_syndicate.dm @@ -124,9 +124,10 @@ GLOBAL_VAR_INIT(sent_syndicate_infiltration_team, 0) var/syndicate_infiltrator_name = random_name(pick(MALE,FEMALE)) - var/datum/preferences/A = new() //Randomize appearance - A.real_name = syndicate_infiltrator_name - A.copy_to(new_syndicate_infiltrator) + var/datum/character_save/S = new //Randomize appearance + S.randomise() + S.real_name = syndicate_infiltrator_name + S.copy_to(new_syndicate_infiltrator) new_syndicate_infiltrator.dna.ready_dna(new_syndicate_infiltrator) //Creates mind stuff. diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 9708f2b74ec..884baa9a11d 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -32,7 +32,7 @@ if(M.stat || !M.mind || M.mind.special_role || M.mind.offstation_role) return FALSE if(temp) - if((M.mind.assigned_role in temp.restricted_jobs) || (M.client.prefs.species in temp.protected_species)) + if((M.mind.assigned_role in temp.restricted_jobs) || (M.client.prefs.active_character.species in temp.protected_species)) return FALSE if(role) // Don't even bother evaluating if there's no role if(player_old_enough_antag(M.client,role) && (role in M.client.prefs.be_special) && !M.client.skip_antag && (!jobban_isbanned(M, role))) @@ -374,8 +374,8 @@ //First we spawn a dude. var/mob/living/carbon/human/new_character = new(pick(GLOB.latejoin))//The mob being spawned. - var/datum/preferences/A = new(G_found.client) - A.copy_to(new_character) + // Then clone stuff over + G_found.client.prefs.active_character.copy_to(new_character) new_character.dna.ready_dna(new_character) new_character.key = G_found.key @@ -388,13 +388,14 @@ var/syndicate_commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major") var/syndicate_commando_name = pick(GLOB.last_names) - var/datum/preferences/A = new()//Randomize appearance for the commando. + var/datum/character_save/S = new //Randomize appearance for the commando. + S.randomise() if(syndicate_leader_selected) - A.real_name = "[syndicate_commando_leader_rank] [syndicate_commando_name]" - A.age = rand(35,45) + S.real_name = "[syndicate_commando_leader_rank] [syndicate_commando_name]" + S.age = rand(35, 45) else - A.real_name = "[syndicate_commando_rank] [syndicate_commando_name]" - A.copy_to(new_syndicate_commando) + S.real_name = "[syndicate_commando_rank] [syndicate_commando_name]" + S.copy_to(new_syndicate_commando) new_syndicate_commando.dna.ready_dna(new_syndicate_commando)//Creates DNA. @@ -576,7 +577,8 @@ if(candidates.len) var/teamOneMembers = 5 var/teamTwoMembers = 5 - var/datum/preferences/A = new() + var/datum/character_save/S = new + S.randomise() for(var/thing in GLOB.landmarks_list) var/obj/effect/landmark/L = thing if(L.name == "tdome1") @@ -585,7 +587,7 @@ var/mob/living/carbon/human/newMember = new(L.loc) - A.copy_to(newMember) + S.copy_to(newMember) newMember.dna.ready_dna(newMember) @@ -607,7 +609,7 @@ var/mob/living/carbon/human/newMember = new(L.loc) - A.copy_to(newMember) + S.copy_to(newMember) newMember.dna.ready_dna(newMember) diff --git a/code/modules/admin/verbs/onlyone.dm b/code/modules/admin/verbs/onlyone.dm index 32ec86541ab..ac21f06c4e4 100644 --- a/code/modules/admin/verbs/onlyone.dm +++ b/code/modules/admin/verbs/onlyone.dm @@ -11,8 +11,9 @@ continue if(is_type_in_list(H.dna.species, incompatible_species)) H.set_species(/datum/species/human) - var/datum/preferences/A = new() // Randomize appearance - A.copy_to(H) + var/datum/character_save/S = new // Randomize appearance + S.randomise() + S.copy_to(H) SSticker.mode.traitors += H.mind H.mind.special_role = SPECIAL_ROLE_TRAITOR diff --git a/code/modules/admin/verbs/onlyoneteam.dm b/code/modules/admin/verbs/onlyoneteam.dm index a822367b68c..311a0bac2d8 100644 --- a/code/modules/admin/verbs/onlyoneteam.dm +++ b/code/modules/admin/verbs/onlyoneteam.dm @@ -12,8 +12,9 @@ continue if(is_type_in_list(H.dna.species, incompatible_species)) H.set_species(/datum/species/human) - var/datum/preferences/A = new() // Randomize appearance - A.copy_to(H) + var/datum/character_save/S = new // Randomize appearance + S.randomise() + S.copy_to(H) for(var/obj/item/I in H) if(istype(I, /obj/item/implant)) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index b12d3de9963..07d5d1e5d7b 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -396,10 +396,12 @@ Traitors and the like can also be revived with the previous role mostly intact. new_character.age = record_found.fields["age"] new_character.dna.blood_type = record_found.fields["blood_type"] else + // We make a random character new_character.change_gender(pick(MALE,FEMALE)) - var/datum/preferences/A = new() - A.real_name = G_found.real_name - A.copy_to(new_character) + var/datum/character_save/S = new + S.randomise() + S.real_name = G_found.real_name + S.copy_to(new_character) if(!new_character.real_name) new_character.real_name = random_name(new_character.gender) diff --git a/code/modules/admin/verbs/striketeam.dm b/code/modules/admin/verbs/striketeam.dm index 55895e5b282..877dff5cd69 100644 --- a/code/modules/admin/verbs/striketeam.dm +++ b/code/modules/admin/verbs/striketeam.dm @@ -138,13 +138,14 @@ GLOBAL_VAR_INIT(sent_strike_team, 0) var/commando_leader_rank = pick("Lieutenant", "Captain", "Major") var/commando_name = pick(GLOB.commando_names) - var/datum/preferences/A = new()//Randomize appearance for the commando. + var/datum/character_save/S = new //Randomize appearance for the commando. + S.randomise() if(is_leader) - A.age = rand(35,45) - A.real_name = "[commando_leader_rank] [commando_name]" + S.age = rand(35, 45) + S.real_name = "[commando_leader_rank] [commando_name]" else - A.real_name = "[commando_name]" - A.copy_to(new_commando) + S.real_name = "[commando_name]" + S.copy_to(new_commando) new_commando.dna.ready_dna(new_commando)//Creates DNA. diff --git a/code/modules/admin/verbs/striketeam_syndicate.dm b/code/modules/admin/verbs/striketeam_syndicate.dm index 0c359e532b6..b40f9b6aae6 100644 --- a/code/modules/admin/verbs/striketeam_syndicate.dm +++ b/code/modules/admin/verbs/striketeam_syndicate.dm @@ -104,13 +104,14 @@ GLOBAL_VAR_INIT(sent_syndicate_strike_team, 0) var/syndicate_commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major") var/syndicate_commando_name = pick(GLOB.last_names) - var/datum/preferences/A = new()//Randomize appearance for the commando. + var/datum/character_save/S = new //Randomize appearance for the commando. + S.randomise() if(is_leader) - A.age = rand(35,45) - A.real_name = "[syndicate_commando_leader_rank] [syndicate_commando_name]" + S.age = rand(35, 45) + S.real_name = "[syndicate_commando_leader_rank] [syndicate_commando_name]" else - A.real_name = "[syndicate_commando_rank] [syndicate_commando_name]" - A.copy_to(new_syndicate_commando) + S.real_name = "[syndicate_commando_rank] [syndicate_commando_name]" + S.copy_to(new_syndicate_commando) new_syndicate_commando.dna.ready_dna(new_syndicate_commando)//Creates DNA. diff --git a/code/modules/admin/watchlist.dm b/code/modules/admin/watchlist.dm index 89288bd13ab..6b98a6050cf 100644 --- a/code/modules/admin/watchlist.dm +++ b/code/modules/admin/watchlist.dm @@ -16,8 +16,21 @@ qdel(query_watchfind) return else + qdel(query_watchfind) target_ckey = new_ckey - if(check_watchlist(target_ckey)) + + var/already_watched = FALSE + var/datum/db_query/query_watch = SSdbcore.NewQuery("SELECT reason FROM watch WHERE ckey=:target_ckey", list( + "target_ckey" = target_ckey + )) + if(!query_watch.warn_execute()) + qdel(query_watch) + return + if(query_watch.NextRow()) + already_watched = TRUE + qdel(query_watch) + + if(already_watched) to_chat(usr, "[target_ckey] is already on the watchlist.") return var/reason = input(usr,"Please state the reason","Reason") as message|null @@ -132,18 +145,3 @@ output += "
[reason]
" usr << browse(output, "window=watchwin;size=900x500") qdel(query_watchlist) - -/proc/check_watchlist(target_ckey) - var/datum/db_query/query_watch = SSdbcore.NewQuery("SELECT reason FROM watch WHERE ckey=:target_ckey", list( - "target_ckey" = target_ckey - )) - if(!query_watch.warn_execute()) - qdel(query_watch) - return - if(query_watch.NextRow()) - var/entry = query_watch.item[1] - qdel(query_watch) - return entry - else - qdel(query_watch) - return 0 diff --git a/code/modules/arcade/prize_datums.dm b/code/modules/arcade/prize_datums.dm index 8ffc59825cb..8be89339134 100644 --- a/code/modules/arcade/prize_datums.dm +++ b/code/modules/arcade/prize_datums.dm @@ -251,6 +251,12 @@ GLOBAL_DATUM_INIT(global_prizes, /datum/prizes, new()) typepath = /obj/item/toy/foamblade cost = 100 +/datum/prize_item/wind_up_toolbox + name = "Wind Up Toolbox" + desc = "A replica toolbox that rumbles when you turn the key." + typepath = /obj/item/toy/windup_toolbox + cost = 100 + /datum/prize_item/redbutton name = "Shiny Red Button" desc = "PRESS IT!" diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 8a07b9fe4d0..c841c759229 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -268,8 +268,8 @@ show_update_prompt = TRUE else if(byond_version == SUGGESTED_CLIENT_VERSION && byond_build < SUGGESTED_CLIENT_BUILD) show_update_prompt = TRUE - // Actually sent to client much later, so it appears after MOTD. + // Actually sent to client much later, so it appears after MOTD. to_chat(src, "If the title screen is black, resources are still downloading. Please be patient until the title screen appears.") GLOB.directory[ckey] = src @@ -278,25 +278,53 @@ if(GLOB.configuration.admin.enable_localhost_autoadmin) if(is_connecting_from_localhost()) new /datum/admins("!LOCALHOST!", R_HOST, ckey) // Makes localhost rank + holder = GLOB.admin_datums[ckey] if(holder) GLOB.admins += src holder.owner = src - //preferences datum - also holds some persistant data for the client (because we may as well keep these datums to a minimum) - prefs = GLOB.preferences_datums[ckey] - if(!prefs) - prefs = new /datum/preferences(src) - GLOB.preferences_datums[ckey] = prefs + log_client_to_db(tdata) // Make sure our client exists in the DB + + // This is where we load all of the clients stuff from the DB + if(SSdbcore.IsConnected()) + // Load in all our client data from the DB + var/list/datum/db_query/login_queries = list() // List of queries to run for login processing + + for(var/datum/client_login_processor/CLP as anything in GLOB.client_login_processors) + login_queries[CLP.type] = CLP.get_query(src) + + SSdbcore.MassExecute(login_queries, TRUE, FALSE, TRUE, FALSE) // Warn, no qdel, assoc, no log + + // Now do fancy things with the results + for(var/datum/client_login_processor/CLP as anything in GLOB.client_login_processors) + CLP.process_result(login_queries[CLP.type], src) + + QDEL_LIST_ASSOC_VAL(login_queries) // Clear out the used queries else - prefs.parent = src + // Set vars here that need to be set if the DB is offline + + // Give blank prefs + prefs = new /datum/preferences(src) + prefs.character_saves = list() + + // Random character + prefs.character_saves += new /datum/character_save + prefs.active_character = prefs.character_saves[1] + + // ToS accepted + tos_consent = TRUE + + prefs.last_ip = address //these are gonna be used for banning prefs.last_id = computer_id //these are gonna be used for banning - if(world.byond_version >= 511 && byond_version >= 511 && prefs.clientfps) - fps = prefs.clientfps + fps = prefs.clientfps - // Check if the client has or has not accepted TOS - check_tos_consent() + // Log alts + if(length(related_accounts_ip)) + log_admin("[key_name(src)] Alts by IP: [jointext(related_accounts_ip, " ")]") + if(length(related_accounts_cid)) + log_admin("[key_name(src)] Alts by CID: [jointext(related_accounts_cid, " ")]") // This has to go here to avoid issues // If you sleep past this point, you will get SSinput errors as well as goonchat errors @@ -320,7 +348,6 @@ winset(src, null, "command=\".configure graphics-hwmode off\"") winset(src, null, "command=\".configure graphics-hwmode on\"") - log_client_to_db(tdata) . = ..() //calls mob.Login() @@ -332,7 +359,6 @@ if(SSinput.initialized) set_macros() - donator_check() check_ip_intel() send_resources() @@ -383,8 +409,6 @@ if(world.TgsAvailable() && length(GLOB.revision_info.testmerges)) to_chat(src, GLOB.revision_info.get_testmerge_chatmessage(TRUE)) - INVOKE_ASYNC(src, .proc/cid_count_check) - if(check_rights(R_ADMIN, FALSE, mob)) // Mob is required. Dont even try without it. to_chat(src, "The queue server is currently [SSqueue.queue_enabled ? "enabled" : "disabled"], with a threshold of [SSqueue.queue_threshold]. This [SSqueue.persist_queue ? "will" : "will not"] persist through rounds.") @@ -420,52 +444,18 @@ return QDEL_HINT_HARDDEL_NOW -/client/proc/donator_check() - set waitfor = FALSE // This needs to run async because any sleep() inside /client/New() breaks stuff badly - if(IsGuestKey(key)) - return - - if(!SSdbcore.IsConnected()) - return - - if(check_rights(R_ADMIN, 0, mob)) // Yes, the mob is required, regardless of other examples in this file, it won't work otherwise - donator_level = DONATOR_LEVEL_MAX - donor_loadout_points() - return - - //Donator stuff. - var/datum/db_query/query_donor_select = SSdbcore.NewQuery("SELECT ckey, tier, active FROM donators WHERE ckey=:ckey", list( - "ckey" = ckey - )) - - if(!query_donor_select.warn_execute()) - qdel(query_donor_select) - return - - while(query_donor_select.NextRow()) - if(!text2num(query_donor_select.item[3])) - // Inactive donator. - donator_level = 0 - qdel(query_donor_select) - return - donator_level = text2num(query_donor_select.item[2]) - donor_loadout_points() - break - qdel(query_donor_select) - /client/proc/donor_loadout_points() if(donator_level > 0 && prefs) prefs.max_gear_slots = GLOB.configuration.general.base_loadout_points + 5 /client/proc/log_client_to_db(connectiontopic) - set waitfor = FALSE // This needs to run async because any sleep() inside /client/New() breaks stuff badly if(IsGuestKey(key)) return if(!SSdbcore.IsConnected()) return - var/datum/db_query/query = SSdbcore.NewQuery("SELECT id, datediff(Now(),firstseen) as age FROM player WHERE ckey=:ckey", list( + var/datum/db_query/query = SSdbcore.NewQuery("SELECT id, datediff(Now(), firstseen) as age FROM player WHERE ckey=:ckey", list( "ckey" = ckey )) if(!query.warn_execute()) @@ -480,67 +470,29 @@ break qdel(query) - var/datum/db_query/query_ip = SSdbcore.NewQuery("SELECT ckey FROM player WHERE ip=:address", list( - "address" = address - )) - if(!query_ip.warn_execute()) - qdel(query_ip) - return - related_accounts_ip = list() - while(query_ip.NextRow()) - if(ckey != query_ip.item[1]) - related_accounts_ip.Add("[query_ip.item[1]]") - - qdel(query_ip) - - var/datum/db_query/query_cid = SSdbcore.NewQuery("SELECT ckey FROM player WHERE computerid=:cid", list( - "cid" = computer_id - )) - if(!query_cid.warn_execute()) - qdel(query_cid) - return - - related_accounts_cid = list() - while(query_cid.NextRow()) - if(ckey != query_cid.item[1]) - related_accounts_cid.Add("[query_cid.item[1]]") - - qdel(query_cid) var/admin_rank = "Player" + // Admins don't get slammed by this, I guess if(holder) admin_rank = holder.rank - // Admins don't get slammed by this, I guess else if(check_randomizer(connectiontopic)) return - //Log all the alts - if(related_accounts_cid.len) - log_admin("[key_name(src)] alts:[jointext(related_accounts_cid, " - ")]") - - - var/watchreason = check_watchlist(ckey) - if(watchreason) - message_admins("Notice: [key_name_admin(src)] is on the watchlist and has just connected - Reason: [watchreason]") - SSdiscord.send2discord_simple_noadmins("**\[Watchlist]** [key_name(src)] is on the watchlist and has just connected - Reason: [watchreason]") - watchlisted = TRUE - - - //Just the standard check to see if it's actually a number if(sql_id) + //Just the standard check to see if it's actually a number if(istext(sql_id)) sql_id = text2num(sql_id) if(!isnum(sql_id)) - return + return // Return here because if we somehow didnt pull a number from an INT column, EVERYTHING is breaking - if(sql_id) var/client_address = address if(!client_address) // Localhost can sometimes have no address set client_address = "127.0.0.1" + //Player already identified previously, we need to just update the 'lastseen', 'ip' and 'computer_id' variables - var/datum/db_query/query_update = SSdbcore.NewQuery("UPDATE player SET lastseen = Now(), ip=:sql_ip, computerid=:sql_cid, lastadminrank=:sql_ar WHERE id=:sql_id", list( + var/datum/db_query/query_update = SSdbcore.NewQuery("UPDATE player SET lastseen=NOW(), ip=:sql_ip, computerid=:sql_cid, lastadminrank=:sql_ar WHERE id=:sql_id", list( "sql_ip" = client_address, "sql_cid" = computer_id, "sql_ar" = admin_rank, @@ -550,6 +502,7 @@ if(!query_update.warn_execute()) qdel(query_update) return + qdel(query_update) // After the regular update INVOKE_ASYNC(src, /client/.proc/get_byond_account_date, FALSE) // Async to avoid other procs in the client chain being delayed by a web request @@ -565,7 +518,7 @@ qdel(query_insert) return qdel(query_insert) - // This is their first connection instance, so TRUE here to nofiy admins + // This is their first connection instance, so TRUE here to notify admins // This needs to happen here to ensure they actually have a row to update INVOKE_ASYNC(src, /client/.proc/get_byond_account_date, TRUE) // Async to avoid other procs in the client chain being delayed by a web request @@ -1051,7 +1004,7 @@ qdel(query_date) - // They have a date, lets bail + // They have a date already, lets bail if(byondacc_date) return @@ -1092,120 +1045,6 @@ /client/proc/show_update_notice() to_chat(src, "Your BYOND client (v: [byond_version].[byond_build]) is out of date. This can cause glitches. We highly suggest you download the latest client from byond.com before playing. You can also update via the BYOND launcher application.") -/** - * Checks if the client has accepted TOS - * - * Runs some checks against vars and the DB to see if the client has accepted TOS. - * Returns TRUE or FALSE if they have or have not - */ -/client/proc/check_tos_consent() - // If there is no TOS, auto accept - if(!GLOB.join_tos) - tos_consent = TRUE - return TRUE - - // If theres no DB, assume yes - if(!SSdbcore.IsConnected()) - tos_consent = TRUE - return TRUE - - var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey FROM privacy WHERE ckey=:ckey AND consent=1", list( - "ckey" = ckey - )) - if(!query.warn_execute()) - qdel(query) - // If our query failed, just assume yes - tos_consent = TRUE - return TRUE - - // If we returned a row, they accepted - while(query.NextRow()) - qdel(query) - tos_consent = TRUE - return TRUE - - qdel(query) - // If we are here, they have not accepted, and need to read it - return FALSE - -/** - * Checks if the client has more than a configured amount of CIDs tied to them in the past - */ -/client/proc/cid_count_check() - // If the config is 0, disable this - if(GLOB.configuration.general.max_client_cid_history == 0) - return - - // If we have no DB, dont even bother - if(!SSdbcore.IsConnected()) - return - - // Now query how many cids they have - var/datum/db_query/query_cidcheck = SSdbcore.NewQuery("SELECT COUNT(DISTINCT computerID) FROM connection_log WHERE ckey=:ckey", list( - "ckey" = ckey - )) - if(!query_cidcheck.warn_execute()) - qdel(query_cidcheck) - return - - var/cidcount = 0 - if(query_cidcheck.NextRow()) - cidcount = query_cidcheck.item[1] - qdel(query_cidcheck) - - if(cidcount > GLOB.configuration.general.max_client_cid_history) - // Check their notes for CID tracking in the past - var/has_note = FALSE - var/note_text = "" - var/datum/db_query/query_find_track_note = SSdbcore.NewQuery("SELECT notetext FROM notes WHERE ckey=:ckey AND adminckey=:ackey", list( - "ckey" = ckey, - "ackey" = CIDTRACKING_PSUEDO_CKEY - )) - if(!query_find_track_note.warn_execute()) - qdel(query_find_track_note) - return - if(query_find_track_note.NextRow()) - note_text = query_find_track_note.item[1] // Grab existing note text - has_note = TRUE - qdel(query_find_track_note) - - - if(has_note) // They have a note. Update it. - var/new_text = "Connected on the date of this note with unique CID #[cidcount]" - // Only update the note if the text is different. Otherwise it bumps the timestamp when it shouldnt - if(note_text != new_text) - var/datum/db_query/query_update_track_note = SSdbcore.NewQuery("UPDATE notes SET notetext=:notetext, timestamp=NOW(), round_id=:rid WHERE ckey=:ckey AND adminckey=:ackey", list( - "notetext" = new_text, - "ckey" = ckey, - "ackey" = CIDTRACKING_PSUEDO_CKEY, - "rid" = GLOB.round_id - )) - if(!query_update_track_note.warn_execute()) - qdel(query_update_track_note) - return - qdel(query_update_track_note) - - else // They dont have a note. Make one. - // NOT logged because its automatic and will spam logs otherwise - // Also right checking must be disabled because its a psuedockey, not a real one - add_note(ckey, "Connected on the date of this note with unique CID #[cidcount]", adminckey = CIDTRACKING_PSUEDO_CKEY, logged = FALSE, checkrights = FALSE, automated = TRUE) - - var/show_warning = TRUE - // Check if they have a note that matches the warning suppressor - var/datum/db_query/query_find_note = SSdbcore.NewQuery("SELECT id FROM notes WHERE ckey=:ckey AND notetext=:notetext", list( - "ckey" = ckey, - "notetext" = CIDWARNING_SUPPRESSED_NOTETEXT - )) - if(!query_find_note.warn_execute()) - qdel(query_find_note) - return - if(query_find_note.NextRow()) - show_warning = FALSE - qdel(query_find_note) - - if(show_warning) - message_admins("[ckey] has just connected and has a history of [cidcount] different CIDs. (WebInfo) (Suppress Warning)") - /client/proc/update_ambience_pref() if(prefs.sound & SOUND_AMBIENCE) if(SSambience.ambience_listening_clients[src] > world.time) diff --git a/code/modules/client/login_processing/10-load_preferences.dm b/code/modules/client/login_processing/10-load_preferences.dm new file mode 100644 index 00000000000..ed4f947b40d --- /dev/null +++ b/code/modules/client/login_processing/10-load_preferences.dm @@ -0,0 +1,31 @@ +/datum/client_login_processor/load_preferences + priority = 10 + +/datum/client_login_processor/load_preferences/get_query(client/C) + var/datum/db_query/query = SSdbcore.NewQuery({"SELECT + ooccolor, + UI_style, + UI_style_color, + UI_style_alpha, + be_role, + default_slot, + toggles, + toggles_2, + sound, + volume_mixer, + lastchangelog, + exp, + clientfps, + atklog, + fuid, + parallax, + 2fa_status + FROM player + WHERE ckey=:ckey"}, list( + "ckey" = C.ckey + )) + + return query + +/datum/client_login_processor/load_preferences/process_result(datum/db_query/Q, client/C) + C.prefs = new /datum/preferences(C, Q) diff --git a/code/modules/client/login_processing/20-load_characters.dm b/code/modules/client/login_processing/20-load_characters.dm new file mode 100644 index 00000000000..68bd1458c47 --- /dev/null +++ b/code/modules/client/login_processing/20-load_characters.dm @@ -0,0 +1,102 @@ +/datum/client_login_processor/load_characters + priority = 20 + +/datum/client_login_processor/load_characters/get_query(client/C) + // Get all their characters + var/datum/db_query/query = SSdbcore.NewQuery({"SELECT + OOC_Notes, + real_name, + name_is_always_random, + gender, + age, + species, + language, + hair_colour, + secondary_hair_colour, + facial_hair_colour, + secondary_facial_hair_colour, + skin_tone, + skin_colour, + marking_colours, + head_accessory_colour, + hair_style_name, + facial_style_name, + marking_styles, + head_accessory_style_name, + alt_head_name, + eye_colour, + underwear, + undershirt, + backbag, + b_type, + alternate_option, + job_support_high, + job_support_med, + job_support_low, + job_medsci_high, + job_medsci_med, + job_medsci_low, + job_engsec_high, + job_engsec_med, + job_engsec_low, + job_karma_high, + job_karma_med, + job_karma_low, + flavor_text, + med_record, + sec_record, + gen_record, + disabilities, + player_alt_titles, + organ_data, + rlimb_data, + nanotrasen_relation, + speciesprefs, + socks, + body_accessory, + gear, + autohiss, + slot + FROM characters WHERE ckey=:ckey"}, list( + "ckey" = C.ckey + )) + + return query + +/datum/client_login_processor/load_characters/process_result(datum/db_query/Q, client/C) + // If we already loaded their characters, dont do it all again + if(C.prefs.characters_loaded) + return + // Step one, initialize their list of characters + C.prefs.character_saves = list() + C.prefs.character_saves.len = C.prefs.max_save_slots // Fill the list with empty indexes + // Fill it with blank characters first + for(var/i in 1 to C.prefs.max_save_slots) + var/datum/character_save/CS = new + CS.slot_number = i + C.prefs.character_saves[i] = CS + + // Did we load at all + var/character_loaded = FALSE + + while(Q.NextRow()) + character_loaded = TRUE + var/datum/character_save/CS = C.prefs.character_saves[Q.item[53]] // Get the slot referenced by this query + CS.load(Q) // Let the save handle the query processing + CS.valid_save = TRUE + + if(character_loaded) + // They have a character, set their active as their default slot + C.prefs.active_character = C.prefs.character_saves[C.prefs.default_slot] + else + // If we are here, they dont have a character. Lets make them a random one + var/datum/character_save/CS = C.prefs.character_saves[1] // Get slot 1 + CS.randomise() + CS.real_name = random_name(CS.gender) // Pick a name + CS.valid_save = TRUE + CS.save(C) + C.prefs.active_character = C.prefs.character_saves[1] // Set slot 1 as their active + C.prefs.default_slot = 1 + C.prefs.save_preferences(C) + + C.prefs.characters_loaded = TRUE // Avoid this happening again diff --git a/code/modules/client/login_processing/30-tos_consent.dm b/code/modules/client/login_processing/30-tos_consent.dm new file mode 100644 index 00000000000..452a638cc02 --- /dev/null +++ b/code/modules/client/login_processing/30-tos_consent.dm @@ -0,0 +1,24 @@ +/datum/client_login_processor/tos_consent + priority = 30 + +/datum/client_login_processor/tos_consent/get_query(client/C) + var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey FROM privacy WHERE ckey=:ckey AND consent=1", list( + "ckey" = C.ckey + )) + return query + +/datum/client_login_processor/tos_consent/process_result(datum/db_query/Q, client/C) + // If there is no TOS, auto accept + if(!GLOB.join_tos) + C.tos_consent = TRUE + return + + // If our query failed, just assume yes + if(Q.last_error) + C.tos_consent = TRUE + return + + // If we returned a row, they accepted + while(Q.NextRow()) + C.tos_consent = TRUE + diff --git a/code/modules/client/login_processing/35-donator_check.dm b/code/modules/client/login_processing/35-donator_check.dm new file mode 100644 index 00000000000..fabcb6bdcdf --- /dev/null +++ b/code/modules/client/login_processing/35-donator_check.dm @@ -0,0 +1,27 @@ +/datum/client_login_processor/donator_check + priority = 35 + +/datum/client_login_processor/donator_check/get_query(client/C) + var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey, tier, active FROM donators WHERE ckey=:ckey", list( + "ckey" = C.ckey + )) + return query + +/datum/client_login_processor/donator_check/process_result(datum/db_query/Q, client/C) + if(IsGuestKey(C.key)) + return + + // Admins get all donor perks + if(check_rights_client(R_ADMIN, FALSE, C)) + C.donator_level = DONATOR_LEVEL_MAX + C.donor_loadout_points() + return + + while(Q.NextRow()) + if(!text2num(Q.item[3])) + // Inactive donator. + C.donator_level = 0 + return + + C.donator_level = text2num(Q.item[2]) + C.donor_loadout_points() diff --git a/code/modules/client/login_processing/36-watchlist.dm b/code/modules/client/login_processing/36-watchlist.dm new file mode 100644 index 00000000000..fa58d3b57f9 --- /dev/null +++ b/code/modules/client/login_processing/36-watchlist.dm @@ -0,0 +1,15 @@ +/datum/client_login_processor/watchlist + priority = 36 + +/datum/client_login_processor/watchlist/get_query(client/C) + var/datum/db_query/query = SSdbcore.NewQuery("SELECT reason FROM watch WHERE ckey=:ckey", list( + "ckey" = C.ckey + )) + return query + +/datum/client_login_processor/watchlist/process_result(datum/db_query/Q, client/C) + if(Q.NextRow()) + var/watchreason = Q.item[1] + message_admins("Notice: [key_name_admin(C)] is on the watchlist and has just connected - Reason: [watchreason]") + SSdiscord.send2discord_simple_noadmins("**\[Watchlist]** [key_name(C)] is on the watchlist and has just connected - Reason: [watchreason]") + C.watchlisted = TRUE diff --git a/code/modules/client/login_processing/37-alts_ip.dm b/code/modules/client/login_processing/37-alts_ip.dm new file mode 100644 index 00000000000..f67255f3295 --- /dev/null +++ b/code/modules/client/login_processing/37-alts_ip.dm @@ -0,0 +1,14 @@ +/datum/client_login_processor/alts_ip + priority = 37 + +/datum/client_login_processor/alts_ip/get_query(client/C) + var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey FROM player WHERE ip=:address", list( + "address" = C.address + )) + return query + +/datum/client_login_processor/alts_ip/process_result(datum/db_query/Q, client/C) + while(Q.NextRow()) + if("[Q.item[1]]" == C.ckey) + continue + C.related_accounts_ip += "[Q.item[1]]" diff --git a/code/modules/client/login_processing/38-alts_cid.dm b/code/modules/client/login_processing/38-alts_cid.dm new file mode 100644 index 00000000000..9613e9fcc3d --- /dev/null +++ b/code/modules/client/login_processing/38-alts_cid.dm @@ -0,0 +1,14 @@ +/datum/client_login_processor/alts_cid + priority = 38 + +/datum/client_login_processor/alts_cid/get_query(client/C) + var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey FROM player WHERE computerid=:cid", list( + "cid" = C.computer_id + )) + return query + +/datum/client_login_processor/alts_cid/process_result(datum/db_query/Q, client/C) + while(Q.NextRow()) + if("[Q.item[1]]" == C.ckey) + continue + C.related_accounts_cid += "[Q.item[1]]" diff --git a/code/modules/client/login_processing/39-cid_count.dm b/code/modules/client/login_processing/39-cid_count.dm new file mode 100644 index 00000000000..c0e8248e892 --- /dev/null +++ b/code/modules/client/login_processing/39-cid_count.dm @@ -0,0 +1,71 @@ +/datum/client_login_processor/cid_count + priority = 39 + +/datum/client_login_processor/cid_count/get_query(client/C) + var/datum/db_query/query = SSdbcore.NewQuery("SELECT COUNT(DISTINCT computerID) FROM connection_log WHERE ckey=:ckey", list( + "ckey" = C.ckey + )) + return query + +/datum/client_login_processor/cid_count/process_result(datum/db_query/Q, client/C) + // If the config is 0, disable this + if(GLOB.configuration.general.max_client_cid_history == 0) + return + + // Now query how many cids they have + var/cidcount = 0 + if(Q.NextRow()) + cidcount = Q.item[1] + + if(cidcount > GLOB.configuration.general.max_client_cid_history) + // Check their notes for CID tracking in the past + var/has_note = FALSE + var/note_text = "" + var/datum/db_query/query_find_track_note = SSdbcore.NewQuery("SELECT notetext FROM notes WHERE ckey=:ckey AND adminckey=:ackey", list( + "ckey" = C.ckey, + "ackey" = CIDTRACKING_PSUEDO_CKEY + )) + if(!query_find_track_note.warn_execute()) + qdel(query_find_track_note) + return + if(query_find_track_note.NextRow()) + note_text = query_find_track_note.item[1] // Grab existing note text + has_note = TRUE + qdel(query_find_track_note) + + + if(has_note) // They have a note. Update it. + var/new_text = "Connected on the date of this note with unique CID #[cidcount]" + // Only update the note if the text is different. Otherwise it bumps the timestamp when it shouldnt + if(note_text != new_text) + var/datum/db_query/query_update_track_note = SSdbcore.NewQuery("UPDATE notes SET notetext=:notetext, timestamp=NOW(), round_id=:rid WHERE ckey=:ckey AND adminckey=:ackey", list( + "notetext" = new_text, + "ckey" = C.ckey, + "ackey" = CIDTRACKING_PSUEDO_CKEY, + "rid" = GLOB.round_id + )) + if(!query_update_track_note.warn_execute()) + qdel(query_update_track_note) + return + qdel(query_update_track_note) + + else // They dont have a note. Make one. + // NOT logged because its automatic and will spam logs otherwise + // Also right checking must be disabled because its a psuedockey, not a real one + add_note(C.ckey, "Connected on the date of this note with unique CID #[cidcount]", adminckey = CIDTRACKING_PSUEDO_CKEY, logged = FALSE, checkrights = FALSE, automated = TRUE) + + var/show_warning = TRUE + // Check if they have a note that matches the warning suppressor + var/datum/db_query/query_find_note = SSdbcore.NewQuery("SELECT id FROM notes WHERE ckey=:ckey AND notetext=:notetext", list( + "ckey" = C.ckey, + "notetext" = CIDWARNING_SUPPRESSED_NOTETEXT + )) + if(!query_find_note.warn_execute()) + qdel(query_find_note) + return + if(query_find_note.NextRow()) + show_warning = FALSE + qdel(query_find_note) + + if(show_warning) + message_admins("[C.ckey] has just connected and has a history of [cidcount] different CIDs. (WebInfo) (Suppress Warning)") diff --git a/code/modules/client/login_processing/__client_login_processor.dm b/code/modules/client/login_processing/__client_login_processor.dm new file mode 100644 index 00000000000..242e797f680 --- /dev/null +++ b/code/modules/client/login_processing/__client_login_processor.dm @@ -0,0 +1,51 @@ +/** + * # Client Login Processor Framework + * + * The holder class for all client data processing + * + * This framework is designed for loading in client data from the database. + * Login processors have their own queries, which will be put into one async batch and + * executed at the same time, to reduce the time it takes for a client to login. + * Login processors can also be given priorities to have things fire in specific orders + * EG: Load their preferences before their job bans, etc etc + * + * When creating these, please name the files with the priority at the start, and the typepath after + * EG: 10-load_preferences.dm + * This makes it easier to track stuff down -AA07 + * + * Also if you have used other languages before with "interface" types (Java, C# (Microsoft Java), etc), + * treat this class as one of those. [get_query(client/C)] and [process_result(datum/db_query/Q, client/C)] MUST be overriden + */ +/datum/client_login_processor + /// The login priority. A lower priority will fire first + var/priority = 0 + +/** + * Query Getter + * + * Gets the DB query for this login processor + * + * Takes the client as an arg instead of just the ckey incase we need more data (IP, CID, etc). + * Returns a DB query datum. + * + * Arguments: + * * C - The client to use to generate the query + */ +/datum/client_login_processor/proc/get_query(client/C) + RETURN_TYPE(/datum/db_query) + CRASH("get_query() not overriden for [type]!") + + + +/** + * Result Processor + * + * Takes the (now executed) query and the client and parses the required data out + * Note: This can be a no-op if you want to just update the DB, just return on the override + * + * Arguments: + * * Q - The DB query to process data from + * * C - The client to store stuff on + */ +/datum/client_login_processor/proc/process_result(datum/db_query/Q, client/C) + CRASH("process_result() not overriden for [type]!") diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/client/preference/character.dm similarity index 51% rename from code/modules/mob/new_player/preferences_setup.dm rename to code/modules/client/preference/character.dm index ec5ae76c33d..32de91e9866 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/client/preference/character.dm @@ -1,6 +1,533 @@ -/datum/preferences - //The mob should have a gender you want before running this proc. Will run fine without H -/datum/preferences/proc/random_character(gender_override) +// PSA To anyone who opens this: +// Good fucking luck. You will need this: https://www.youtube.com/watch?v=W9GaIbECisQ + + +/datum/character_save + var/real_name //our character's name + var/be_random_name = FALSE //whether we are a random name every round + var/gender = MALE //gender of character (well duh) + var/age = 30 //age of character + var/spawnpoint = "Arrivals Shuttle" //where this character will spawn (0-2). + var/b_type = "A+" //blood type (not-chooseable) + var/underwear = "Nude" //underwear type + var/undershirt = "Nude" //undershirt type + var/socks = "Nude" //socks type + var/backbag = GBACKPACK //backpack type + var/ha_style = "None" //Head accessory style + var/hacc_colour = "#000000" //Head accessory colour. If this line looks badly indented in vscode, its because of the shitty colour square + var/list/m_styles = list( + "head" = "None", + "body" = "None", + "tail" = "None" + ) //Marking styles. + var/list/m_colours = list( + "head" = "#000000", + "body" = "#000000", + "tail" = "#000000" + ) //Marking colours. + var/h_style = "Bald" //Hair type + var/h_colour = "#000000" //Hair color + var/h_sec_colour = "#000000" //Secondary hair color + var/f_style = "Shaved" //Facial hair type + var/f_colour = "#000000" //Facial hair color + var/f_sec_colour = "#000000" //Secondary facial hair color + var/s_tone = 0 //Skin tone + var/s_colour = "#000000" //Skin color + var/e_colour = "#000000" //Eye color + var/alt_head = "None" //Alt head style. + var/species = "Human" + var/language = "None" //Secondary language + var/autohiss_mode = AUTOHISS_OFF //Species autohiss level. OFF, BASIC, FULL. + + var/body_accessory = null + + var/speciesprefs = 0 //I hate having to do this, I really do (Using this for oldvox code, making names universal I guess + + //Mob preview + var/icon/preview_icon = null + var/icon/preview_icon_front = null + var/icon/preview_icon_side = null + + //Jobs, uses bitflags + var/job_support_high = 0 + var/job_support_med = 0 + var/job_support_low = 0 + + var/job_medsci_high = 0 + var/job_medsci_med = 0 + var/job_medsci_low = 0 + + var/job_engsec_high = 0 + var/job_engsec_med = 0 + var/job_engsec_low = 0 + + var/job_karma_high = 0 + var/job_karma_med = 0 + var/job_karma_low = 0 + + //Keeps track of preferrence for not getting any wanted jobs + 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 ;) + var/list/organ_data = list() + var/list/rlimb_data = list() + + var/list/player_alt_titles = new() // the default name of a job like "Medical Doctor" + var/flavor_text = "" + var/med_record = "" + var/sec_record = "" + var/gen_record = "" + var/disabilities = 0 + + var/nanotrasen_relation = "Neutral" + + // OOC Metadata: + var/metadata = "" + + //Gear stuff + var/list/loadout_gear = list() + + /// Is this character from the DB? + var/from_db = FALSE + /// Is this character valid to be picked? This is necessary to avoid someone getting a bald human called "Character 30" + var/valid_save = FALSE + /// Character slot number, used for saves and stuff. + var/slot_number = 0 + +// Fuckery to prevent null characters +/datum/character_save/New() + randomise() + real_name = random_name(gender, species) + +/datum/character_save/proc/save(client/C) + var/organlist + var/rlimblist + var/playertitlelist + var/gearlist + + var/markingcolourslist = list2params(m_colours) + var/markingstyleslist = list2params(m_styles) + if(!isemptylist(organ_data)) + organlist = list2params(organ_data) + if(!isemptylist(rlimb_data)) + rlimblist = list2params(rlimb_data) + if(!isemptylist(player_alt_titles)) + playertitlelist = list2params(player_alt_titles) + if(!isemptylist(loadout_gear)) + gearlist = list2params(loadout_gear) + + var/datum/db_query/firstquery = SSdbcore.NewQuery("SELECT slot FROM characters WHERE ckey=:ckey ORDER BY slot", list( + "ckey" = C.ckey + )) + if(!firstquery.warn_execute()) + qdel(firstquery) + return + while(firstquery.NextRow()) + if(text2num(firstquery.item[1]) == slot_number) // Check if the character exists + var/datum/db_query/query = SSdbcore.NewQuery({"UPDATE characters + SET + OOC_Notes=:metadata, + real_name=:real_name, + name_is_always_random=:be_random_name, + gender=:gender, + age=:age, + species=:species, + language=:language, + hair_colour=:h_colour, + secondary_hair_colour=:h_sec_colour, + facial_hair_colour=:f_colour, + secondary_facial_hair_colour=:f_sec_colour, + skin_tone=:s_tone, + skin_colour=:s_colour, + marking_colours=:markingcolourslist, + head_accessory_colour=:hacc_colour, + hair_style_name=:h_style, + facial_style_name=:f_style, + marking_styles=:markingstyleslist, + head_accessory_style_name=:ha_style, + alt_head_name=:alt_head, + eye_colour=:e_colour, + underwear=:underwear, + undershirt=:undershirt, + backbag=:backbag, + b_type=:b_type, + alternate_option=:alternate_option, + job_support_high=:job_support_high, + job_support_med=:job_support_med, + job_support_low=:job_support_low, + job_medsci_high=:job_medsci_high, + job_medsci_med=:job_medsci_med, + job_medsci_low=:job_medsci_low, + job_engsec_high=:job_engsec_high, + job_engsec_med=:job_engsec_med, + job_engsec_low=:job_engsec_low, + job_karma_high=:job_karma_high, + job_karma_med=:job_karma_med, + job_karma_low=:job_karma_low, + flavor_text=:flavor_text, + med_record=:med_record, + sec_record=:sec_record, + gen_record=:gen_record, + player_alt_titles=:playertitlelist, + disabilities=:disabilities, + organ_data=:organlist, + rlimb_data=:rlimblist, + nanotrasen_relation=:nanotrasen_relation, + speciesprefs=:speciesprefs, + socks=:socks, + body_accessory=:body_accessory, + gear=:gearlist, + autohiss=:autohiss_mode + WHERE ckey=:ckey + AND slot=:slot"}, list( + // OH GOD SO MANY PARAMETERS + "metadata" = metadata, + "real_name" = real_name, + "be_random_name" = be_random_name, + "gender" = gender, + "age" = age, + "species" = species, + "language" = language, + "h_colour" = h_colour, + "h_sec_colour" = h_sec_colour, + "f_colour" = f_colour, + "f_sec_colour" = f_sec_colour, + "s_tone" = s_tone, + "s_colour" = s_colour, + "markingcolourslist" = markingcolourslist, + "hacc_colour" = hacc_colour, + "h_style" = h_style, + "f_style" = f_style, + "markingstyleslist" = markingstyleslist, + "ha_style" = ha_style, + "alt_head" = (alt_head ? alt_head : ""), // This it intentional. It wont work without it! + "e_colour" = e_colour, + "underwear" = underwear, + "undershirt" = undershirt, + "backbag" = backbag, + "b_type" = b_type, + "alternate_option" = alternate_option, + "job_support_high" = job_support_high, + "job_support_med" = job_support_med, + "job_support_low" = job_support_low, + "job_medsci_high" = job_medsci_high, + "job_medsci_med" = job_medsci_med, + "job_medsci_low" = job_medsci_low, + "job_engsec_high" = job_engsec_high, + "job_engsec_med" = job_engsec_med, + "job_engsec_low" = job_engsec_low, + "job_karma_high" = job_karma_high, + "job_karma_med" = job_karma_med, + "job_karma_low" = job_karma_low, + "flavor_text" = flavor_text, + "med_record" = med_record, + "sec_record" = sec_record, + "gen_record" = gen_record, + "playertitlelist" = (playertitlelist ? playertitlelist : ""), // This it intentnional. It wont work without it! + "disabilities" = disabilities, + "organlist" = (organlist ? organlist : ""), + "rlimblist" = (rlimblist ? rlimblist : ""), + "nanotrasen_relation" = nanotrasen_relation, + "speciesprefs" = speciesprefs, + "socks" = socks, + "body_accessory" = (body_accessory ? body_accessory : ""), + "gearlist" = (gearlist ? gearlist : ""), + "autohiss_mode" = autohiss_mode, + "ckey" = C.ckey, + "slot" = slot_number + )) + + if(!query.warn_execute()) + qdel(firstquery) + qdel(query) + return + qdel(firstquery) + qdel(query) + return 1 + + qdel(firstquery) + + var/datum/db_query/query = SSdbcore.NewQuery({" + INSERT INTO characters (ckey, slot, OOC_Notes, real_name, name_is_always_random, gender, + age, species, language, + hair_colour, secondary_hair_colour, + facial_hair_colour, secondary_facial_hair_colour, + skin_tone, skin_colour, + marking_colours, + head_accessory_colour, + hair_style_name, + facial_style_name, + marking_styles, + head_accessory_style_name, + alt_head_name, + eye_colour, + underwear, undershirt, + backbag, b_type, alternate_option, + job_support_high, job_support_med, job_support_low, + job_medsci_high, job_medsci_med, job_medsci_low, + job_engsec_high, job_engsec_med, job_engsec_low, + job_karma_high, job_karma_med, job_karma_low, + flavor_text, + med_record, + sec_record, + gen_record, + player_alt_titles, + disabilities, organ_data, rlimb_data, nanotrasen_relation, speciesprefs, + socks, body_accessory, gear, autohiss) + VALUES + (:ckey, :slot, :metadata, :name, :be_random_name, :gender, + :age, :species, :language, + :h_colour, :h_sec_colour, + :f_colour, :f_sec_colour, + :s_tone, :s_colour, + :markingcolourslist, + :hacc_colour, + :h_style, + :f_style, + :markingstyleslist, + :ha_style, + :alt_head, + :e_colour, + :underwear, :undershirt, + :backbag, :b_type, :alternate_option, + :job_support_high, :job_support_med, :job_support_low, + :job_medsci_high, :job_medsci_med, :job_medsci_low, + :job_engsec_high, :job_engsec_med, :job_engsec_low, + :job_karma_high, :job_karma_med, :job_karma_low, + :flavor_text, + :med_record, + :sec_record, + :gen_record, + :playertitlelist, + :disabilities, :organlist, :rlimblist, :nanotrasen_relation, :speciesprefs, + :socks, :body_accessory, :gearlist, :autohiss_mode) + "}, list( + // This has too many params for anyone to look at this without going insae + "ckey" = C.ckey, + "slot" = slot_number, + "metadata" = metadata, + "name" = real_name, + "be_random_name" = be_random_name, + "gender" = gender, + "age" = age, + "species" = species, + "language" = language, + "h_colour" = h_colour, + "h_sec_colour" = h_sec_colour, + "f_colour" = f_colour, + "f_sec_colour" = f_sec_colour, + "s_tone" = s_tone, + "s_colour" = s_colour, + "markingcolourslist" = markingcolourslist, + "hacc_colour" = hacc_colour, + "h_style" = h_style, + "f_style" = f_style, + "markingstyleslist" = markingstyleslist, + "ha_style" = ha_style, + "alt_head" = (alt_head ? alt_head : "None"), // bane of my fucking life + "e_colour" = e_colour, + "underwear" = underwear, + "undershirt" = undershirt, + "backbag" = backbag, + "b_type" = b_type, + "alternate_option" = alternate_option, + "job_support_high" = job_support_high, + "job_support_med" = job_support_med, + "job_support_low" = job_support_low, + "job_medsci_high" = job_medsci_high, + "job_medsci_med" = job_medsci_med, + "job_medsci_low" = job_medsci_low, + "job_engsec_high" = job_engsec_high, + "job_engsec_med" = job_engsec_med, + "job_engsec_low" = job_engsec_low, + "job_karma_high" = job_karma_high, + "job_karma_med" = job_karma_med, + "job_karma_low" = job_karma_low, + "flavor_text" = flavor_text, + "med_record" = med_record, + "sec_record" = sec_record, + "gen_record" = gen_record, + "playertitlelist" = (playertitlelist ? playertitlelist : ""), // This it intentional. It wont work without it! + "disabilities" = disabilities, + "organlist" = (organlist ? organlist : ""), + "rlimblist" = (rlimblist ? rlimblist : ""), + "nanotrasen_relation" = nanotrasen_relation, + "speciesprefs" = speciesprefs, + "socks" = socks, + "body_accessory" = (body_accessory ? body_accessory : ""), + "gearlist" = (gearlist ? gearlist : ""), + "autohiss_mode" = autohiss_mode + )) + + if(!query.warn_execute()) + qdel(query) + return + + qdel(query) + from_db = TRUE + return 1 + + +/datum/character_save/proc/load(datum/db_query/query) + //Character + metadata = query.item[1] + real_name = query.item[2] + be_random_name = text2num(query.item[3]) + gender = query.item[4] + age = text2num(query.item[5]) + species = query.item[6] + language = query.item[7] + + h_colour = query.item[8] + h_sec_colour = query.item[9] + f_colour = query.item[10] + f_sec_colour = query.item[11] + s_tone = text2num(query.item[12]) + s_colour = query.item[13] + m_colours = params2list(query.item[14]) + hacc_colour = query.item[15] + h_style = query.item[16] + f_style = query.item[17] + m_styles = params2list(query.item[18]) + ha_style = query.item[19] + alt_head = query.item[20] + e_colour = query.item[21] + underwear = query.item[22] + undershirt = query.item[23] + backbag = query.item[24] + b_type = query.item[25] + + + //Jobs + alternate_option = text2num(query.item[26]) + job_support_high = text2num(query.item[27]) + job_support_med = text2num(query.item[28]) + job_support_low = text2num(query.item[29]) + job_medsci_high = text2num(query.item[30]) + job_medsci_med = text2num(query.item[31]) + job_medsci_low = text2num(query.item[32]) + job_engsec_high = text2num(query.item[33]) + job_engsec_med = text2num(query.item[34]) + job_engsec_low = text2num(query.item[35]) + job_karma_high = text2num(query.item[36]) + job_karma_med = text2num(query.item[37]) + job_karma_low = text2num(query.item[38]) + + //Miscellaneous + flavor_text = query.item[39] + med_record = query.item[40] + sec_record = query.item[41] + gen_record = query.item[42] + // Apparently, the preceding vars weren't always encoded properly... + if(findtext(flavor_text, "<")) // ... so let's clumsily check for tags! + flavor_text = html_encode(flavor_text) + if(findtext(med_record, "<")) + med_record = html_encode(med_record) + if(findtext(sec_record, "<")) + sec_record = html_encode(sec_record) + if(findtext(gen_record, "<")) + gen_record = html_encode(gen_record) + disabilities = text2num(query.item[43]) + player_alt_titles = params2list(query.item[44]) + organ_data = params2list(query.item[45]) + rlimb_data = params2list(query.item[46]) + nanotrasen_relation = query.item[47] + speciesprefs = text2num(query.item[48]) + + //socks + socks = query.item[49] + body_accessory = query.item[50] + loadout_gear = params2list(query.item[51]) + autohiss_mode = text2num(query.item[52]) + + //Sanitize + var/datum/species/SP = GLOB.all_species[species] + metadata = sanitize_text(metadata, initial(metadata)) + real_name = reject_bad_name(real_name, TRUE) + + if(isnull(species)) + species = "Human" + + if(isnull(language)) + language = "None" + + if(isnull(nanotrasen_relation)) + nanotrasen_relation = initial(nanotrasen_relation) + + if(isnull(speciesprefs)) + speciesprefs = initial(speciesprefs) + + if(!real_name) + real_name = random_name(gender, species) + + be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name)) + gender = sanitize_gender(gender, FALSE, !SP.has_gender) + age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age)) + h_colour = sanitize_hexcolor(h_colour) + h_sec_colour = sanitize_hexcolor(h_sec_colour) + f_colour = sanitize_hexcolor(f_colour) + f_sec_colour = sanitize_hexcolor(f_sec_colour) + s_tone = sanitize_integer(s_tone, -185, 34, initial(s_tone)) + s_colour = sanitize_hexcolor(s_colour) + + for(var/marking_location in m_colours) + m_colours[marking_location] = sanitize_hexcolor(m_colours[marking_location], DEFAULT_MARKING_COLOURS[marking_location]) + + hacc_colour = sanitize_hexcolor(hacc_colour) + h_style = sanitize_inlist(h_style, GLOB.hair_styles_public_list, initial(h_style)) + f_style = sanitize_inlist(f_style, GLOB.facial_hair_styles_list, initial(f_style)) + + for(var/marking_location in m_styles) + m_styles[marking_location] = sanitize_inlist(m_styles[marking_location], GLOB.marking_styles_list, DEFAULT_MARKING_STYLES[marking_location]) + + ha_style = sanitize_inlist(ha_style, GLOB.head_accessory_styles_list, initial(ha_style)) + alt_head = sanitize_inlist(alt_head, GLOB.alt_heads_list, initial(alt_head)) + e_colour = sanitize_hexcolor(e_colour) + underwear = sanitize_text(underwear, initial(underwear)) + undershirt = sanitize_text(undershirt, initial(undershirt)) + backbag = sanitize_text(backbag, initial(backbag)) + b_type = sanitize_text(b_type, initial(b_type)) + autohiss_mode = sanitize_integer(autohiss_mode, 0, 2, initial(autohiss_mode)) + + alternate_option = sanitize_integer(alternate_option, 0, 2, initial(alternate_option)) + job_support_high = sanitize_integer(job_support_high, 0, 65535, initial(job_support_high)) + job_support_med = sanitize_integer(job_support_med, 0, 65535, initial(job_support_med)) + job_support_low = sanitize_integer(job_support_low, 0, 65535, initial(job_support_low)) + job_medsci_high = sanitize_integer(job_medsci_high, 0, 65535, initial(job_medsci_high)) + job_medsci_med = sanitize_integer(job_medsci_med, 0, 65535, initial(job_medsci_med)) + job_medsci_low = sanitize_integer(job_medsci_low, 0, 65535, initial(job_medsci_low)) + job_engsec_high = sanitize_integer(job_engsec_high, 0, 65535, initial(job_engsec_high)) + job_engsec_med = sanitize_integer(job_engsec_med, 0, 65535, initial(job_engsec_med)) + job_engsec_low = sanitize_integer(job_engsec_low, 0, 65535, initial(job_engsec_low)) + job_karma_high = sanitize_integer(job_karma_high, 0, 65535, initial(job_karma_high)) + job_karma_med = sanitize_integer(job_karma_med, 0, 65535, initial(job_karma_med)) + job_karma_low = sanitize_integer(job_karma_low, 0, 65535, initial(job_karma_low)) + disabilities = sanitize_integer(disabilities, 0, 65535, initial(disabilities)) + + socks = sanitize_text(socks, initial(socks)) + body_accessory = sanitize_text(body_accessory, initial(body_accessory)) + + if(!player_alt_titles) + player_alt_titles = new() + if(!organ_data) + src.organ_data = list() + if(!rlimb_data) + src.rlimb_data = list() + if(!loadout_gear) + loadout_gear = list() + + // Check if the current body accessory exists + if(!GLOB.body_accessory_by_name[body_accessory]) + body_accessory = null + + from_db = TRUE + valid_save = TRUE + + return TRUE + +/datum/character_save/proc/randomise(gender_override) + b_type = pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+") var/datum/species/S = GLOB.all_species[species] if(!istype(S)) //The species was invalid. Set the species to the default, fetch the datum for that species and generate a random character. species = initial(species) @@ -48,7 +575,7 @@ age = rand(AGE_MIN, AGE_MAX) -/datum/preferences/proc/randomize_hair_color(target = "hair") +/datum/character_save/proc/randomize_hair_color(target = "hair") if(prob (75) && target == "facial") // Chance to inherit hair color f_colour = h_colour return @@ -102,7 +629,7 @@ if("facial") f_colour = rgb(red, green, blue) -/datum/preferences/proc/randomize_eyes_color() +/datum/character_save/proc/randomize_eyes_color() var/red var/green var/blue @@ -148,7 +675,7 @@ e_colour = rgb(red, green, blue) -/datum/preferences/proc/randomize_skin_color(pass_on) +/datum/character_save/proc/randomize_skin_color(pass_on) var/red var/green var/blue @@ -197,7 +724,7 @@ else s_colour = rgb(red, green, blue) -/datum/preferences/proc/blend_backpack(icon/clothes_s, backbag, satchel, backpack="backpack") +/datum/character_save/proc/blend_backpack(icon/clothes_s, backbag, satchel, backpack="backpack") switch(backbag) if(2) clothes_s.Blend(new /icon('icons/mob/clothing/back.dmi', backpack), ICON_OVERLAY) @@ -207,7 +734,7 @@ clothes_s.Blend(new /icon('icons/mob/clothing/back.dmi', "satchel"), ICON_OVERLAY) return clothes_s -/datum/preferences/proc/update_preview_icon(for_observer=0) //seriously. This is horrendous. +/datum/character_save/proc/update_preview_icon(for_observer=0) //seriously. This is horrendous. qdel(preview_icon_front) qdel(preview_icon_side) qdel(preview_icon) @@ -950,3 +1477,653 @@ qdel(undershirt_s) qdel(socks_s) qdel(clothes_s) + + + +/datum/character_save/proc/get_gear_metadata(datum/gear/G) + . = loadout_gear[G.display_name] + if(!.) + . = list() + loadout_gear[G.display_name] = . + +/datum/character_save/proc/get_tweak_metadata(datum/gear/G, datum/gear_tweak/tweak) + var/list/metadata = get_gear_metadata(G) + . = metadata["[tweak]"] + if(!.) + . = tweak.get_default() + metadata["[tweak]"] = . + +/datum/character_save/proc/set_tweak_metadata(datum/gear/G, datum/gear_tweak/tweak, new_metadata) + var/list/metadata = get_gear_metadata(G) + metadata["[tweak]"] = new_metadata + + +/datum/character_save/proc/SetJobPreferenceLevel(datum/job/job, level) + if(!job) + return 0 + + if(level == 1) // to high + // remove any other job(s) set to high + job_support_med |= job_support_high + job_engsec_med |= job_engsec_high + job_medsci_med |= job_medsci_high + job_karma_med |= job_karma_high + job_support_high = 0 + job_engsec_high = 0 + job_medsci_high = 0 + job_karma_high = 0 + + if(job.department_flag == JOBCAT_SUPPORT) + job_support_low &= ~job.flag + job_support_med &= ~job.flag + job_support_high &= ~job.flag + + switch(level) + if(1) + job_support_high |= job.flag + if(2) + job_support_med |= job.flag + if(3) + job_support_low |= job.flag + + return 1 + else if(job.department_flag == JOBCAT_ENGSEC) + job_engsec_low &= ~job.flag + job_engsec_med &= ~job.flag + job_engsec_high &= ~job.flag + + switch(level) + if(1) + job_engsec_high |= job.flag + if(2) + job_engsec_med |= job.flag + if(3) + job_engsec_low |= job.flag + + return 1 + else if(job.department_flag == JOBCAT_MEDSCI) + job_medsci_low &= ~job.flag + job_medsci_med &= ~job.flag + job_medsci_high &= ~job.flag + + switch(level) + if(1) + job_medsci_high |= job.flag + if(2) + job_medsci_med |= job.flag + if(3) + job_medsci_low |= job.flag + + return 1 + else if(job.department_flag == JOBCAT_KARMA) + job_karma_low &= ~job.flag + job_karma_med &= ~job.flag + job_karma_high &= ~job.flag + + switch(level) + if(1) + job_karma_high |= job.flag + if(2) + job_karma_med |= job.flag + if(3) + job_karma_low |= job.flag + + return 1 + + return 0 + +/datum/character_save/proc/ShowDisabilityState(mob/user, flag, label) + return "
  • [label]: [disabilities & flag ? "Yes" : "No"]
  • " + +/datum/character_save/proc/SetDisabilities(mob/user) + var/datum/species/S = GLOB.all_species[species] + var/HTML = "" + HTML += "
    " + + if(CAN_WINGDINGS in S.species_traits) + HTML += ShowDisabilityState(user, DISABILITY_FLAG_WINGDINGS, "Speak in Wingdings") + HTML += ShowDisabilityState(user, DISABILITY_FLAG_NEARSIGHTED, "Nearsighted") + HTML += ShowDisabilityState(user, DISABILITY_FLAG_COLOURBLIND, "Colourblind") + HTML += ShowDisabilityState(user, DISABILITY_FLAG_BLIND, "Blind") + HTML += ShowDisabilityState(user, DISABILITY_FLAG_DEAF, "Deaf") + HTML += ShowDisabilityState(user, DISABILITY_FLAG_MUTE, "Mute") + if(!(TRAIT_NOFAT in S.inherent_traits)) + HTML += ShowDisabilityState(user, DISABILITY_FLAG_FAT, "Obese") + HTML += ShowDisabilityState(user, DISABILITY_FLAG_NERVOUS, "Stutter") + HTML += ShowDisabilityState(user, DISABILITY_FLAG_SWEDISH, "Swedish accent") + HTML += ShowDisabilityState(user, DISABILITY_FLAG_CHAV, "Chav accent") + HTML += ShowDisabilityState(user, DISABILITY_FLAG_LISP, "Lisp") + HTML += ShowDisabilityState(user, DISABILITY_FLAG_DIZZY, "Dizziness") + + + HTML += {" + \[Done\] + \[Reset\] +
    "} + + var/datum/browser/popup = new(user, "disabil", "
    Choose Disabilities
    ", 350, 380) + popup.set_content(HTML) + popup.open(0) + +/datum/character_save/proc/SetRecords(mob/user) + var/HTML = "" + HTML += "
    " + + HTML += "Medical Records
    " + + if(length(med_record) <= 40) + HTML += "[med_record]" + else + HTML += "[copytext(med_record, 1, 37)]..." + + HTML += "
    Employment Records
    " + + if(length(gen_record) <= 40) + HTML += "[gen_record]" + else + HTML += "[copytext(gen_record, 1, 37)]..." + + HTML += "
    Security Records
    " + + if(length(sec_record) <= 40) + HTML += "[sec_record]
    " + else + HTML += "[copytext(sec_record, 1, 37)]...
    " + + HTML += "\[Done\]" + HTML += "
    " + + var/datum/browser/popup = new(user, "records", "
    Character Records
    ", 350, 300) + popup.set_content(HTML) + popup.open(0) + +/datum/character_save/proc/GetPlayerAltTitle(datum/job/job) + return player_alt_titles.Find(job.title) > 0 \ + ? player_alt_titles[job.title] \ + : job.title + +/datum/character_save/proc/SetPlayerAltTitle(datum/job/job, new_title) + // remove existing entry + if(player_alt_titles.Find(job.title)) + player_alt_titles -= job.title + // add one if it's not default + if(job.title != new_title) + player_alt_titles[job.title] = new_title + +/datum/character_save/proc/ResetJobs() + job_support_high = 0 + job_support_med = 0 + job_support_low = 0 + + job_medsci_high = 0 + job_medsci_med = 0 + job_medsci_low = 0 + + job_engsec_high = 0 + job_engsec_med = 0 + job_engsec_low = 0 + + job_karma_high = 0 + job_karma_med = 0 + job_karma_low = 0 + + +/datum/character_save/proc/GetJobDepartment(datum/job/job, level) + if(!job || !level) return 0 + switch(job.department_flag) + if(JOBCAT_SUPPORT) + switch(level) + if(1) + return job_support_high + if(2) + return job_support_med + if(3) + return job_support_low + if(JOBCAT_MEDSCI) + switch(level) + if(1) + return job_medsci_high + if(2) + return job_medsci_med + if(3) + return job_medsci_low + if(JOBCAT_ENGSEC) + switch(level) + if(1) + return job_engsec_high + if(2) + return job_engsec_med + if(3) + return job_engsec_low + if(JOBCAT_KARMA) + switch(level) + if(1) + return job_karma_high + if(2) + return job_karma_med + if(3) + return job_karma_low + return 0 + +/datum/character_save/proc/SetJobDepartment(datum/job/job, level) + if(!job || !level) return 0 + switch(level) + if(1)//Only one of these should ever be active at once so clear them all here + job_support_high = 0 + job_medsci_high = 0 + job_engsec_high = 0 + job_karma_high = 0 + return 1 + if(2)//Set current highs to med, then reset them + job_support_med |= job_support_high + job_medsci_med |= job_medsci_high + job_engsec_med |= job_engsec_high + job_karma_med |= job_karma_high + job_support_high = 0 + job_medsci_high = 0 + job_engsec_high = 0 + job_karma_high = 0 + + switch(job.department_flag) + if(JOBCAT_SUPPORT) + switch(level) + if(2) + job_support_high = job.flag + job_support_med &= ~job.flag + if(3) + job_support_med |= job.flag + job_support_low &= ~job.flag + else + job_support_low |= job.flag + if(JOBCAT_MEDSCI) + switch(level) + if(2) + job_medsci_high = job.flag + job_medsci_med &= ~job.flag + if(3) + job_medsci_med |= job.flag + job_medsci_low &= ~job.flag + else + job_medsci_low |= job.flag + if(JOBCAT_ENGSEC) + switch(level) + if(2) + job_engsec_high = job.flag + job_engsec_med &= ~job.flag + if(3) + job_engsec_med |= job.flag + job_engsec_low &= ~job.flag + else + job_engsec_low |= job.flag + if(JOBCAT_KARMA) + switch(level) + if(2) + job_karma_high = job.flag + job_karma_med &= ~job.flag + if(3) + job_karma_med |= job.flag + job_karma_low &= ~job.flag + else + job_karma_low |= job.flag + return 1 + +/datum/character_save/proc/copy_to(mob/living/carbon/human/character) + var/datum/species/S = GLOB.all_species[species] + character.set_species(S.type) // Yell at me if this causes everything to melt + if(be_random_name) + real_name = random_name(gender, species) + + character.add_language(language) + + + character.real_name = real_name + character.dna.real_name = real_name + character.name = character.real_name + + character.flavor_text = flavor_text + character.med_record = med_record + character.sec_record = sec_record + character.gen_record = gen_record + + character.change_gender(gender) + character.age = age + + //Head-specific + var/obj/item/organ/external/head/H = character.get_organ("head") + + H.hair_colour = h_colour + + H.sec_hair_colour = h_sec_colour + + H.facial_colour = f_colour + + H.sec_facial_colour = f_sec_colour + + H.h_style = h_style + H.f_style = f_style + + H.alt_head = alt_head + //End of head-specific. + + character.skin_colour = s_colour + + character.s_tone = s_tone + + // Destroy/cyborgize organs + for(var/name in organ_data) + + var/status = organ_data[name] + var/obj/item/organ/external/O = character.bodyparts_by_name[name] + if(O) + if(status == "amputated") + qdel(O.remove(character)) + + else if(status == "cyborg") + if(rlimb_data[name]) + O.robotize(rlimb_data[name], convert_all = 0) + else + O.robotize() + else + var/obj/item/organ/internal/I = character.get_int_organ_tag(name) + if(I) + if(status == "cybernetic") + I.robotize() + + character.dna.blood_type = b_type + + // Wheelchair necessary? + var/obj/item/organ/external/l_foot = character.get_organ("l_foot") + var/obj/item/organ/external/r_foot = character.get_organ("r_foot") + if(!l_foot && !r_foot) + var/obj/structure/chair/wheelchair/W = new /obj/structure/chair/wheelchair(character.loc) + W.buckle_mob(character, TRUE) + + character.underwear = underwear + character.undershirt = undershirt + character.socks = socks + + if(character.dna.species.bodyflags & HAS_HEAD_ACCESSORY) + H.headacc_colour = hacc_colour + H.ha_style = ha_style + if(character.dna.species.bodyflags & HAS_MARKINGS) + character.m_colours = m_colours + character.m_styles = m_styles + + if(body_accessory) + character.body_accessory = GLOB.body_accessory_by_name[body_accessory] + + character.backbag = backbag + + //Debugging report to track down a bug, which randomly assigned the plural gender to people. + if(character.dna.species.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) + + character.change_eye_color(e_colour) + character.original_eye_color = e_colour + + if(disabilities & DISABILITY_FLAG_FAT) + character.dna.SetSEState(GLOB.fatblock, TRUE, TRUE) + character.overeatduration = 600 + character.dna.default_blocks.Add(GLOB.fatblock) + + if(disabilities & DISABILITY_FLAG_NEARSIGHTED) + character.dna.SetSEState(GLOB.glassesblock, TRUE, TRUE) + character.dna.default_blocks.Add(GLOB.glassesblock) + + if(disabilities & DISABILITY_FLAG_BLIND) + character.dna.SetSEState(GLOB.blindblock, TRUE, TRUE) + character.dna.default_blocks.Add(GLOB.blindblock) + + if(disabilities & DISABILITY_FLAG_DEAF) + character.dna.SetSEState(GLOB.deafblock, TRUE, TRUE) + character.dna.default_blocks.Add(GLOB.deafblock) + + if(disabilities & DISABILITY_FLAG_COLOURBLIND) + character.dna.SetSEState(GLOB.colourblindblock, TRUE, TRUE) + character.dna.default_blocks.Add(GLOB.colourblindblock) + + if(disabilities & DISABILITY_FLAG_MUTE) + character.dna.SetSEState(GLOB.muteblock, TRUE, TRUE) + character.dna.default_blocks.Add(GLOB.muteblock) + + if(disabilities & DISABILITY_FLAG_NERVOUS) + character.dna.SetSEState(GLOB.nervousblock, TRUE, TRUE) + character.dna.default_blocks.Add(GLOB.nervousblock) + + if(disabilities & DISABILITY_FLAG_SWEDISH) + character.dna.SetSEState(GLOB.swedeblock, TRUE, TRUE) + character.dna.default_blocks.Add(GLOB.swedeblock) + + if(disabilities & DISABILITY_FLAG_CHAV) + character.dna.SetSEState(GLOB.chavblock, TRUE, TRUE) + character.dna.default_blocks.Add(GLOB.chavblock) + + if(disabilities & DISABILITY_FLAG_LISP) + character.dna.SetSEState(GLOB.lispblock, TRUE, TRUE) + character.dna.default_blocks.Add(GLOB.lispblock) + + if(disabilities & DISABILITY_FLAG_DIZZY) + character.dna.SetSEState(GLOB.dizzyblock, TRUE, TRUE) + character.dna.default_blocks.Add(GLOB.dizzyblock) + + if(disabilities & DISABILITY_FLAG_WINGDINGS && (CAN_WINGDINGS in character.dna.species.species_traits)) + character.dna.SetSEState(GLOB.wingdingsblock, TRUE, TRUE) + character.dna.default_blocks.Add(GLOB.wingdingsblock) + + character.dna.species.handle_dna(character) + + if(character.dna.dirtySE) + character.dna.UpdateSE() + domutcheck(character, MUTCHK_FORCED) //'Activates' all the above disabilities. + + character.dna.ready_dna(character, flatten_SE = FALSE) + character.sync_organ_dna(assimilate = TRUE) + character.UpdateAppearance() + + // Do the initial caching of the player's body icons. + character.force_update_limbs() + character.update_eyes() + character.regenerate_icons() + +//Check if the user has ANY job selected. +/datum/character_save/proc/check_any_job() + return(job_support_high || job_support_med || job_support_low || job_medsci_high || job_medsci_med || job_medsci_low || job_engsec_high || job_engsec_med || job_engsec_low || job_karma_high || job_karma_med || job_karma_low) + + +/datum/character_save/proc/SetChoices(mob/user, limit = 17, list/splitJobs = list("Head of Security", "Bartender"), widthPerColumn = 400, height = 700) + if(!SSjobs) + return + + //limit - The amount of jobs allowed per column. Defaults to 17 to make it look nice. + //splitJobs - Allows you split the table by job. You can make different tables for each department by including their heads. Defaults to CE to make it look nice. + //widthPerColumn - Screen's width for every column. + //height - Screen's height. + var/width = widthPerColumn + + + var/list/html = list() + html += "" + if(!length(SSjobs.occupations)) + html += "The Jobs subsystem is not yet finished creating jobs, please try again later" + html += "
    Done

    " // Easier to press up here. + else + html += "
    " + html += "Choose occupation chances
    Unavailable occupations are crossed out.

    " + html += "
    Save

    " // Easier to press up here. + html += "
    Left-click to raise an occupation preference, right-click to lower it.
    " + html += "" + html += "
    " // Table within a table for alignment, also allows you to easily add more colomns. + html += "" + var/index = -1 + + //The job before the current job. I only use this to get the previous jobs color when I'm filling in blank rows. + var/datum/job/lastJob + if(!SSjobs) + return + for(var/J in SSjobs.occupations) + var/datum/job/job = J + + if(job.admin_only) + continue + + if(job.hidden_from_job_prefs) + continue + + index += 1 + if((index >= limit) || (job.title in splitJobs)) + if((index < limit) && (lastJob != null)) + // Dynamic window width + width += widthPerColumn + //If the cells were broken up by a job in the splitJob list then it will fill in the rest of the cells with + //the last job's selection color. Creating a rather nice effect. + for(var/i in 1 to limit - index) + html += "" + html += "
      
    " + index = 0 + + html += "" + continue + if(jobban_isbanned(user, job.title)) + html += "[rank]" + continue + var/available_in_playtime = job.available_in_playtime(user.client) + if(available_in_playtime) + html += "[rank]" + continue + if(job.barred_by_disability(user.client)) + html += "[rank]" + continue + if(!job.player_old_enough(user.client)) + var/available_in_days = job.available_in_days(user.client) + html += "[rank]" + continue + if((job_support_low & JOB_CIVILIAN) && (job.title != "Civilian")) + html += "[rank]" + continue + if((job.title in GLOB.command_positions) || (job.title == "AI"))//Bold head jobs + html += "[rank]" + else + html += "[rank]" + + html += "" + continue + /* + if(GetJobDepartment(job, 1) & job.flag) + HTML += " \[High]" + else if(GetJobDepartment(job, 2) & job.flag) + HTML += " \[Medium]" + else if(GetJobDepartment(job, 3) & job.flag) + HTML += " \[Low]" + else + HTML += " \[NEVER]" + */ + html += "[prefLevelLabel]" + + html += "" + + for(var/i in 1 to limit - index) // Finish the column so it is even + html += "" + + html += "
    " + var/rank + if(job.alt_titles) + rank = "[GetPlayerAltTitle(job)]" + else + rank = job.title + lastJob = job + if(!is_job_whitelisted(user, job.title)) + html += "[rank] \[KARMA]
    \[BANNED]
    \[[get_exp_format(available_in_playtime)] as [job.get_exp_req_type()]\]
    \[DISABILITY\]
    \[IN [(available_in_days)] DAYS]
    " + + var/prefLevelLabel = "ERROR" + var/prefLevelColor = "pink" + var/prefUpperLevel = -1 // level to assign on left click + var/prefLowerLevel = -1 // level to assign on right click + + if(GetJobDepartment(job, 1) & job.flag) + prefLevelLabel = "High" + prefLevelColor = "slateblue" + prefUpperLevel = 4 + prefLowerLevel = 2 + else if(GetJobDepartment(job, 2) & job.flag) + prefLevelLabel = "Medium" + prefLevelColor = "green" + prefUpperLevel = 1 + prefLowerLevel = 3 + else if(GetJobDepartment(job, 3) & job.flag) + prefLevelLabel = "Low" + prefLevelColor = "orange" + prefUpperLevel = 2 + prefLowerLevel = 4 + else + prefLevelLabel = "NEVER" + prefLevelColor = "red" + prefUpperLevel = 3 + prefLowerLevel = 1 + + + html += "" + + // HTML += "" + + if(job.title == "Civilian")//Civilian is special + if(job_support_low & JOB_CIVILIAN) + html += " Yes" + else + html += " No" + html += "
      
    " + html += "
    " + + switch(alternate_option) + if(GET_RANDOM_JOB) + html += "

    Get random job if preferences unavailable

    " + if(BE_ASSISTANT) + html += "

    Be a civilian if preferences unavailable

    " + if(RETURN_TO_LOBBY) + html += "

    Return to lobby if preferences unavailable

    " + + html += "
    Reset
    " + html += "

    Learn About Job Selection
    " + html += "
    " + + user << browse(null, "window=preferences") +// user << browse(HTML, "window=mob_occupation;size=[width]x[height]") + var/datum/browser/popup = new(user, "mob_occupation", "
    Occupation Preferences
    ", width, height) + popup.set_window_options("can_close=0") + var/html_string = html.Join() + popup.set_content(html_string) + popup.open(FALSE) + + +/datum/character_save/proc/clear_character_slot(client/C) + . = FALSE + // Is there a character in that slot? + var/datum/db_query/query = SSdbcore.NewQuery("SELECT slot FROM characters WHERE ckey=:ckey AND slot=:slot", list( + "ckey" = C.ckey, + "slot" = slot_number + )) + + if(!query.warn_execute()) + qdel(query) + return + + if(!query.NextRow()) + qdel(query) + return + + qdel(query) + + var/datum/db_query/delete_query = SSdbcore.NewQuery("DELETE FROM characters WHERE ckey=:ckey AND slot=:slot", list( + "ckey" = C.ckey, + "slot" = slot_number + )) + + if(!delete_query.warn_execute()) + qdel(delete_query) + return + + qdel(delete_query) + + from_db = FALSE + return TRUE diff --git a/code/modules/client/preference/link_processing.dm b/code/modules/client/preference/link_processing.dm new file mode 100644 index 00000000000..6a7e5144718 --- /dev/null +++ b/code/modules/client/preference/link_processing.dm @@ -0,0 +1,1046 @@ +/datum/preferences/proc/process_link(mob/user, list/href_list) + if(!user) + return + + var/datum/species/S = GLOB.all_species[active_character.species] + if(href_list["preference"] == "job") + switch(href_list["task"]) + if("close") + user << browse(null, "window=mob_occupation") + ShowChoices(user) + if("reset") + active_character.ResetJobs() + active_character.SetChoices(user) + if("learnaboutselection") + if(GLOB.configuration.url.wiki_url) + if(alert("Would you like to open the Job selection info in your browser?", "Open Job Selection", "Yes", "No") == "Yes") + user << link("[GLOB.configuration.url.wiki_url]/index.php/Job_Selection_and_Assignment") + else + to_chat(user, "The Wiki URL is not set in the server configuration.") + if("random") + if(active_character.alternate_option == GET_RANDOM_JOB || active_character.alternate_option == BE_ASSISTANT) + active_character.alternate_option += 1 + else if(active_character.alternate_option == RETURN_TO_LOBBY) + active_character.alternate_option = 0 + else + return 0 + active_character.SetChoices(user) + if("alt_title") + var/datum/job/job = locate(href_list["job"]) + if(job) + var/choices = list(job.title) + job.alt_titles + var/choice = input("Pick a title for [job.title].", "Character Generation", active_character.GetPlayerAltTitle(job)) as anything in choices | null + if(choice) + active_character.SetPlayerAltTitle(job, choice) + active_character.SetChoices(user) + if("input") + SetJob(user, href_list["text"]) + if("setJobLevel") + UpdateJobPreference(user, href_list["text"], text2num(href_list["level"])) + else + active_character.SetChoices(user) + return 1 + else if(href_list["preference"] == "disabilities") + switch(href_list["task"]) + if("close") + user << browse(null, "window=disabil") + ShowChoices(user) + if("reset") + active_character.disabilities = 0 + active_character.SetDisabilities(user) + if("input") + var/dflag=text2num(href_list["disability"]) + if(dflag >= 0) // Toggle it. + active_character.disabilities ^= text2num(href_list["disability"]) //MAGIC + active_character.SetDisabilities(user) + else + active_character.SetDisabilities(user) + return 1 + + else if(href_list["preference"] == "records") + if(text2num(href_list["record"]) >= 1) + active_character.SetRecords(user) + return + else + user << browse(null, "window=records") + + if(href_list["task"] == "med_record") + var/medmsg = input(usr,"Set your medical notes here.","Medical Records",html_decode(active_character.med_record)) as message + + if(medmsg != null) + medmsg = copytext(medmsg, 1, MAX_PAPER_MESSAGE_LEN) + medmsg = html_encode(medmsg) + + active_character.med_record = medmsg + active_character.SetRecords(user) + + if(href_list["task"] == "sec_record") + var/secmsg = input(usr,"Set your security notes here.","Security Records",html_decode(active_character.sec_record)) as message + + if(secmsg != null) + secmsg = copytext(secmsg, 1, MAX_PAPER_MESSAGE_LEN) + secmsg = html_encode(secmsg) + + active_character.sec_record = secmsg + active_character.SetRecords(user) + + if(href_list["task"] == "gen_record") + var/genmsg = input(usr,"Set your employment notes here.","Employment Records",html_decode(active_character.gen_record)) as message + + if(genmsg != null) + genmsg = copytext(genmsg, 1, MAX_PAPER_MESSAGE_LEN) + genmsg = html_encode(genmsg) + + active_character.gen_record = genmsg + active_character.SetRecords(user) + + if(href_list["preference"] == "gear") + if(href_list["toggle_gear"]) + var/datum/gear/TG = GLOB.gear_datums[href_list["toggle_gear"]] + if(TG.display_name in active_character.loadout_gear) + active_character.loadout_gear -= TG.display_name + else + if(TG.donator_tier && user.client.donator_level < TG.donator_tier) + to_chat(user, "That gear is only available at a higher donation tier than you are on.") + return + var/total_cost = 0 + var/list/type_blacklist = list() + for(var/gear_name in active_character.loadout_gear) + var/datum/gear/G = GLOB.gear_datums[gear_name] + if(istype(G)) + if(!G.subtype_cost_overlap) + if(G.subtype_path in type_blacklist) + continue + type_blacklist += G.subtype_path + total_cost += G.cost + + if((total_cost + TG.cost) <= max_gear_slots) + active_character.loadout_gear += TG.display_name + + else if(href_list["gear"] && href_list["tweak"]) + var/datum/gear/gear = GLOB.gear_datums[href_list["gear"]] + var/datum/gear_tweak/tweak = locate(href_list["tweak"]) + if(!tweak || !istype(gear) || !(tweak in gear.gear_tweaks)) + return + var/metadata = tweak.get_metadata(user, active_character.get_tweak_metadata(gear, tweak)) + if(!metadata) + return + active_character.set_tweak_metadata(gear, tweak, metadata) + else if(href_list["select_category"]) + gear_tab = href_list["select_category"] + else if(href_list["clear_loadout"]) + active_character.loadout_gear.Cut() + + ShowChoices(user) + return + + switch(href_list["task"]) + if("random") + var/datum/robolimb/robohead + if(S.bodyflags & ALL_RPARTS) + var/head_model = "[!active_character.rlimb_data["head"] ? "Morpheus Cyberkinetics" : active_character.rlimb_data["head"]]" + robohead = GLOB.all_robolimbs[head_model] + switch(href_list["preference"]) + if("name") + active_character.real_name = random_name(active_character.gender, active_character.species) + if(isnewplayer(user)) + var/mob/new_player/N = user + N.new_player_panel_proc() + if("age") + active_character.age = rand(AGE_MIN, AGE_MAX) + if("hair") + if(active_character.species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Wryn", "Vulpkanin", "Vox")) + active_character.h_colour = rand_hex_color() + if("secondary_hair") + if(active_character.species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Wryn", "Vulpkanin", "Vox")) + active_character.h_sec_colour = rand_hex_color() + if("h_style") + active_character.h_style = random_hair_style(active_character.gender, active_character.species, robohead) + if("facial") + if(active_character.species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Wryn", "Vulpkanin", "Vox")) + active_character.f_colour = rand_hex_color() + if("secondary_facial") + if(active_character.species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Wryn", "Vulpkanin", "Vox")) + active_character.f_sec_colour = rand_hex_color() + if("f_style") + active_character.f_style = random_facial_hair_style(active_character.gender, active_character.species, robohead) + if("headaccessory") + if(S.bodyflags & HAS_HEAD_ACCESSORY) //Species that have head accessories. + active_character.hacc_colour = rand_hex_color() + if("ha_style") + if(S.bodyflags & HAS_HEAD_ACCESSORY) //Species that have head accessories. + active_character.ha_style = random_head_accessory(active_character.species) + if("m_style_head") + if(S.bodyflags & HAS_HEAD_MARKINGS) //Species with head markings. + active_character.m_styles["head"] = random_marking_style("head", active_character.species, robohead, null, active_character.alt_head) + if("m_head_colour") + if(S.bodyflags & HAS_HEAD_MARKINGS) //Species with head markings. + active_character.m_colours["head"] = rand_hex_color() + if("m_style_body") + if(S.bodyflags & HAS_BODY_MARKINGS) //Species with body markings. + active_character.m_styles["body"] = random_marking_style("body", active_character.species) + if("m_body_colour") + if(S.bodyflags & HAS_BODY_MARKINGS) //Species with body markings. + active_character.m_colours["body"] = rand_hex_color() + if("m_style_tail") + if(S.bodyflags & HAS_TAIL_MARKINGS) //Species with tail markings. + active_character.m_styles["tail"] = random_marking_style("tail", active_character.species, null, active_character.body_accessory) + if("m_tail_colour") + if(S.bodyflags & HAS_TAIL_MARKINGS) //Species with tail markings. + active_character.m_colours["tail"] = rand_hex_color() + if("underwear") + active_character.underwear = random_underwear(active_character.gender, active_character.species) + ShowChoices(user) + if("undershirt") + active_character.undershirt = random_undershirt(active_character.gender, active_character.species) + ShowChoices(user) + if("socks") + active_character.socks = random_socks(active_character.gender, active_character.species) + ShowChoices(user) + if("eyes") + active_character.e_colour = rand_hex_color() + if("s_tone") + if(S.bodyflags & (HAS_SKIN_TONE|HAS_ICON_SKIN_TONE)) + active_character.s_tone = random_skin_tone() + if("s_color") + if(S.bodyflags & HAS_SKIN_COLOR) + active_character.s_colour = rand_hex_color() + if("bag") + active_character.backbag = pick(GLOB.backbaglist) + if("all") + active_character.randomise() + if("input") + switch(href_list["preference"]) + if("name") + var/raw_name = clean_input("Choose your character's name:", "Character Preference", , user) + if(!isnull(raw_name)) // Check to ensure that the user entered text (rather than cancel.) + var/new_name = reject_bad_name(raw_name, 1) + if(new_name) + active_character.real_name = new_name + if(isnewplayer(user)) + var/mob/new_player/N = user + N.new_player_panel_proc() + else + to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .") + + if("age") + var/new_age = input(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX])", "Character Preference") as num|null + if(new_age) + active_character.age = max(min(round(text2num(new_age)), AGE_MAX),AGE_MIN) + if("species") + var/list/new_species = list("Human", "Tajaran", "Skrell", "Unathi", "Diona", "Vulpkanin") + var/prev_species = active_character.species + + for(var/_species in GLOB.whitelisted_species) + if(is_alien_whitelisted(user, _species)) + new_species += _species + + active_character.species = input("Please select a species", "Character Generation", null) in sortTim(new_species, /proc/cmp_text_asc) + var/datum/species/NS = GLOB.all_species[active_character.species] + if(!istype(NS)) //The species was invalid. Notify the user and fail out. + active_character.species = prev_species + to_chat(user, "Invalid species, please pick something else.") + return + if(prev_species != active_character.species) + if(NS.has_gender && active_character.gender == PLURAL) + active_character.gender = pick(MALE,FEMALE) + var/datum/robolimb/robohead + if(NS.bodyflags & ALL_RPARTS) + var/head_model = "[!active_character.rlimb_data["head"] ? "Morpheus Cyberkinetics" : active_character.rlimb_data["head"]]" + robohead = GLOB.all_robolimbs[head_model] + //grab one of the valid hair styles for the newly chosen species + active_character.h_style = random_hair_style(active_character.gender, active_character.species, robohead) + + //grab one of the valid facial hair styles for the newly chosen species + active_character.f_style = random_facial_hair_style(active_character.gender, active_character.species, robohead) + + if(NS.bodyflags & HAS_HEAD_ACCESSORY) //Species that have head accessories. + active_character.ha_style = random_head_accessory(active_character.species) + else + active_character.ha_style = "None" // No Vulp ears on Unathi + active_character.hacc_colour = rand_hex_color() + + if(NS.bodyflags & HAS_HEAD_MARKINGS) //Species with head markings. + active_character.m_styles["head"] = random_marking_style("head", active_character.species, robohead, null, active_character.alt_head) + else + active_character.m_styles["head"] = "None" + active_character.m_colours["head"] = "#000000" + + if(NS.bodyflags & HAS_BODY_MARKINGS) //Species with body markings/tattoos. + active_character.m_styles["body"] = random_marking_style("body", active_character.species) + else + active_character.m_styles["body"] = "None" + active_character.m_colours["body"] = "#000000" + + if(NS.bodyflags & HAS_TAIL_MARKINGS) //Species with tail markings. + active_character.m_styles["tail"] = random_marking_style("tail", active_character.species, null, active_character.body_accessory) + else + active_character.m_styles["tail"] = "None" + active_character.m_colours["tail"] = "#000000" + + // Don't wear another species' underwear! + var/datum/sprite_accessory/SA = GLOB.underwear_list[active_character.underwear] + if(!SA || !(active_character.species in SA.species_allowed)) + active_character.underwear = random_underwear(active_character.gender, active_character.species) + + SA = GLOB.undershirt_list[active_character.undershirt] + if(!SA || !(active_character.species in SA.species_allowed)) + active_character.undershirt = random_undershirt(active_character.gender, active_character.species) + + SA = GLOB.socks_list[active_character.socks] + if(!SA || !(active_character.species in SA.species_allowed)) + active_character.socks = random_socks(active_character.gender, active_character.species) + + //reset skin tone and colour + if(NS.bodyflags & (HAS_SKIN_TONE|HAS_ICON_SKIN_TONE)) + random_skin_tone(active_character.species) + else + active_character.s_tone = 0 + + if(!(NS.bodyflags & HAS_SKIN_COLOR)) + active_character.s_colour = "#000000" + + active_character.alt_head = "None" //No alt heads on species that don't have them. + active_character.speciesprefs = 0 //My Vox tank shouldn't change how my future Grey talks. + + active_character.body_accessory = null //no vulptail on humans damnit + + //Reset prosthetics. + active_character.organ_data = list() + active_character.rlimb_data = list() + + if(!(NS.autohiss_basic_map)) + active_character.autohiss_mode = AUTOHISS_OFF + if("speciesprefs") + active_character.speciesprefs = !active_character.speciesprefs //Starts 0, so if someone clicks the button up top there, this won't be 0 anymore. If they click it again, it'll go back to 0. + if("language") +// var/languages_available + var/list/new_languages = list("None") + for(var/L in GLOB.all_languages) + var/datum/language/lang = GLOB.all_languages[L] + if(!(lang.flags & RESTRICTED)) + new_languages += lang.name + + active_character.language = input("Please select a secondary language", "Character Generation", null) in sortTim(new_languages, /proc/cmp_text_asc) + + if("autohiss_mode") + if(S.autohiss_basic_map) + var/list/autohiss_choice = list("Off" = AUTOHISS_OFF, "Basic" = AUTOHISS_BASIC, "Full" = AUTOHISS_FULL) + var/new_autohiss_pref = input(user, "Choose your character's auto-accent level:", "Character Preference") as null|anything in autohiss_choice + if(new_autohiss_pref) + active_character.autohiss_mode = autohiss_choice[new_autohiss_pref] + + if("metadata") + var/new_metadata = input(user, "Enter any information you'd like others to see, such as Roleplay-preferences:", "Game Preference" , active_character.metadata) as message|null + if(new_metadata) + active_character.metadata = sanitize(copytext(new_metadata,1,MAX_MESSAGE_LEN)) + + if("b_type") + var/new_b_type = input(user, "Choose your character's blood-type:", "Character Preference") as null|anything in list( "A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-" ) + if(new_b_type) + active_character.b_type = new_b_type + + if("hair") + if(active_character.species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox")) //Species that have hair. (No HAS_HAIR flag) + var/input = "Choose your character's hair colour:" + var/new_hair = input(user, input, "Character Preference", active_character.h_colour) as color|null + if(new_hair) + active_character.h_colour = new_hair + + if("secondary_hair") + if(active_character.species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox")) + var/datum/sprite_accessory/hair_style = GLOB.hair_styles_public_list[active_character.h_style] + if(hair_style.secondary_theme && !hair_style.no_sec_colour) + var/new_hair = input(user, "Choose your character's secondary hair colour:", "Character Preference", active_character.h_sec_colour) as color|null + if(new_hair) + active_character.h_sec_colour = new_hair + + if("h_style") + var/list/valid_hairstyles = list() + for(var/hairstyle in GLOB.hair_styles_public_list) + var/datum/sprite_accessory/SA = GLOB.hair_styles_public_list[hairstyle] + + if(hairstyle == "Bald") //Just in case. + valid_hairstyles += hairstyle + continue + if(S.bodyflags & ALL_RPARTS) //Species that can use prosthetic heads. + var/head_model + if(!active_character.rlimb_data["head"]) //Handle situations where the head is default. + head_model = "Morpheus Cyberkinetics" + else + head_model = active_character.rlimb_data["head"] + var/datum/robolimb/robohead = GLOB.all_robolimbs[head_model] + if((active_character.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 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(active_character.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 + + sortTim(valid_hairstyles, /proc/cmp_text_asc) //this alphabetizes the list + var/new_h_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in valid_hairstyles + if(new_h_style) + active_character.h_style = new_h_style + + if("headaccessory") + if(S.bodyflags & HAS_HEAD_ACCESSORY) //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", active_character.hacc_colour) as color|null + if(new_head_accessory) + active_character.hacc_colour = new_head_accessory + + if("ha_style") + if(S.bodyflags & HAS_HEAD_ACCESSORY) //Species with head accessories. + var/list/valid_head_accessory_styles = list() + for(var/head_accessory_style in GLOB.head_accessory_styles_list) + var/datum/sprite_accessory/H = GLOB.head_accessory_styles_list[head_accessory_style] + if(!(active_character.species in H.species_allowed)) + continue + + valid_head_accessory_styles += head_accessory_style + + sortTim(valid_head_accessory_styles, /proc/cmp_text_asc) + var/new_head_accessory_style = input(user, "Choose the style of your character's head accessory:", "Character Preference") as null|anything in valid_head_accessory_styles + if(new_head_accessory_style) + active_character.ha_style = new_head_accessory_style + + if("alt_head") + if(active_character.organ_data["head"] == "cyborg") + return + if(S.bodyflags & HAS_ALT_HEADS) //Species with alt heads. + var/list/valid_alt_heads = list() + valid_alt_heads["None"] = GLOB.alt_heads_list["None"] //The only null entry should be the "None" option + for(var/alternate_head in GLOB.alt_heads_list) + var/datum/sprite_accessory/alt_heads/head = GLOB.alt_heads_list[alternate_head] + if(!(active_character.species in head.species_allowed)) + continue + + valid_alt_heads += alternate_head + + var/new_alt_head = input(user, "Choose your character's alternate head style:", "Character Preference") as null|anything in valid_alt_heads + if(new_alt_head) + active_character.alt_head = new_alt_head + if(active_character.m_styles["head"]) + var/head_marking = active_character.m_styles["head"] + var/datum/sprite_accessory/body_markings/head/head_marking_style = GLOB.marking_styles_list[head_marking] + if(!head_marking_style.heads_allowed || (!("All" in head_marking_style.heads_allowed) && !(active_character.alt_head in head_marking_style.heads_allowed))) + active_character.m_styles["head"] = "None" + + if("m_style_head") + if(S.bodyflags & HAS_HEAD_MARKINGS) //Species with head markings. + var/list/valid_markings = list() + valid_markings["None"] = GLOB.marking_styles_list["None"] + for(var/markingstyle in GLOB.marking_styles_list) + var/datum/sprite_accessory/body_markings/head/M = GLOB.marking_styles_list[markingstyle] + if(!(active_character.species in M.species_allowed)) + continue + if(M.marking_location != "head") + continue + if(active_character.alt_head && active_character.alt_head != "None") + if(!("All" in M.heads_allowed) && !(active_character.alt_head in M.heads_allowed)) + continue + else + if(M.heads_allowed && !("All" in M.heads_allowed)) + continue + + if(S.bodyflags & ALL_RPARTS) //Species that can use prosthetic heads. + var/head_model + if(!active_character.rlimb_data["head"]) //Handle situations where the head is default. + head_model = "Morpheus Cyberkinetics" + else + head_model = active_character.rlimb_data["head"] + var/datum/robolimb/robohead = GLOB.all_robolimbs[head_model] + if(robohead.is_monitor && M.name != "None") //If the character can have prosthetic heads and they have the default Morpheus head (or another monitor-head), no optic markings. + continue + else if(!robohead.is_monitor && M.name != "None") //Otherwise, if they DON'T have the default head and the head's not a monitor but the head's not in the style's list of allowed models, skip. + if(!(robohead.company in M.models_allowed)) + continue + + valid_markings += markingstyle + sortTim(valid_markings, /proc/cmp_text_asc) + var/new_marking_style = input(user, "Choose the style of your character's head markings:", "Character Preference", active_character.m_styles["head"]) as null|anything in valid_markings + if(new_marking_style) + active_character.m_styles["head"] = new_marking_style + + if("m_head_colour") + if(S.bodyflags & HAS_HEAD_MARKINGS) //Species with head markings. + var/input = "Choose the colour of your your character's head markings:" + var/new_markings = input(user, input, "Character Preference", active_character.m_colours["head"]) as color|null + if(new_markings) + active_character.m_colours["head"] = new_markings + + if("m_style_body") + if(S.bodyflags & HAS_BODY_MARKINGS) //Species with body markings/tattoos. + var/list/valid_markings = list() + valid_markings["None"] = GLOB.marking_styles_list["None"] + for(var/markingstyle in GLOB.marking_styles_list) + var/datum/sprite_accessory/M = GLOB.marking_styles_list[markingstyle] + if(!(active_character.species in M.species_allowed)) + continue + if(M.marking_location != "body") + continue + + valid_markings += markingstyle + sortTim(valid_markings, /proc/cmp_text_asc) + var/new_marking_style = input(user, "Choose the style of your character's body markings:", "Character Preference", active_character.m_styles["body"]) as null|anything in valid_markings + if(new_marking_style) + active_character.m_styles["body"] = new_marking_style + + if("m_body_colour") + if(S.bodyflags & HAS_BODY_MARKINGS) //Species with body markings/tattoos. + var/input = "Choose the colour of your your character's body markings:" + var/new_markings = input(user, input, "Character Preference", active_character.m_colours["body"]) as color|null + if(new_markings) + active_character.m_colours["body"] = new_markings + + if("m_style_tail") + if(S.bodyflags & HAS_TAIL_MARKINGS) //Species with tail markings. + var/list/valid_markings = list() + valid_markings["None"] = GLOB.marking_styles_list["None"] + for(var/markingstyle in GLOB.marking_styles_list) + var/datum/sprite_accessory/body_markings/tail/M = GLOB.marking_styles_list[markingstyle] + if(M.marking_location != "tail") + continue + if(!(active_character.species in M.species_allowed)) + continue + if(!active_character.body_accessory) + if(M.tails_allowed) + continue + else + if(!M.tails_allowed || !(active_character.body_accessory in M.tails_allowed)) + continue + + valid_markings += markingstyle + sortTim(valid_markings, /proc/cmp_text_asc) + var/new_marking_style = input(user, "Choose the style of your character's tail markings:", "Character Preference", active_character.m_styles["tail"]) as null|anything in valid_markings + if(new_marking_style) + active_character.m_styles["tail"] = new_marking_style + + if("m_tail_colour") + if(S.bodyflags & HAS_TAIL_MARKINGS) //Species with tail markings. + var/input = "Choose the colour of your your character's tail markings:" + var/new_markings = input(user, input, "Character Preference", active_character.m_colours["tail"]) as color|null + if(new_markings) + active_character.m_colours["tail"] = new_markings + + if("body_accessory") + var/list/possible_body_accessories = list() + if(check_rights(R_ADMIN, 1, user)) + possible_body_accessories = GLOB.body_accessory_by_name.Copy() + else + for(var/B in GLOB.body_accessory_by_name) + var/datum/body_accessory/accessory = GLOB.body_accessory_by_name[B] + if(!istype(accessory)) + possible_body_accessories += "None" //the only null entry should be the "None" option + continue + if(active_character.species in accessory.allowed_species) + possible_body_accessories += B + sortTim(possible_body_accessories, /proc/cmp_text_asc) + var/new_body_accessory = input(user, "Choose your body accessory:", "Character Preference") as null|anything in possible_body_accessories + if(new_body_accessory) + active_character.m_styles["tail"] = "None" + active_character.body_accessory = (new_body_accessory == "None") ? null : new_body_accessory + + if("facial") + if(active_character.species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox")) //Species that have facial hair. (No HAS_HAIR_FACIAL flag) + var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference", active_character.f_colour) as color|null + if(new_facial) + active_character.f_colour = new_facial + + if("secondary_facial") + if(active_character.species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox")) + var/datum/sprite_accessory/facial_hair_style = GLOB.facial_hair_styles_list[active_character.f_style] + if(facial_hair_style.secondary_theme && !facial_hair_style.no_sec_colour) + var/new_facial = input(user, "Choose your character's secondary facial-hair colour:", "Character Preference", active_character.f_sec_colour) as color|null + if(new_facial) + active_character.f_sec_colour = new_facial + + if("f_style") + var/list/valid_facial_hairstyles = list() + for(var/facialhairstyle in GLOB.facial_hair_styles_list) + var/datum/sprite_accessory/SA = GLOB.facial_hair_styles_list[facialhairstyle] + + if(facialhairstyle == "Shaved") //Just in case. + valid_facial_hairstyles += facialhairstyle + continue + if(active_character.gender == MALE && SA.gender == FEMALE) + continue + if(active_character.gender == FEMALE && SA.gender == MALE) + continue + if(S.bodyflags & ALL_RPARTS) //Species that can use prosthetic heads. + var/head_model + if(!active_character.rlimb_data["head"]) //Handle situations where the head is default. + head_model = "Morpheus Cyberkinetics" + else + head_model = active_character.rlimb_data["head"] + var/datum/robolimb/robohead = GLOB.all_robolimbs[head_model] + if((active_character.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 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(active_character.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 + sortTim(valid_facial_hairstyles, /proc/cmp_text_asc) + var/new_f_style = input(user, "Choose your character's facial-hair style:", "Character Preference") as null|anything in valid_facial_hairstyles + if(new_f_style) + active_character.f_style = new_f_style + + if("underwear") + var/list/valid_underwear = list() + for(var/underwear in GLOB.underwear_list) + var/datum/sprite_accessory/SA = GLOB.underwear_list[underwear] + if(active_character.gender == MALE && SA.gender == FEMALE) + continue + if(active_character.gender == FEMALE && SA.gender == MALE) + continue + if(!(active_character.species in SA.species_allowed)) + continue + valid_underwear[underwear] = GLOB.underwear_list[underwear] + sortTim(valid_underwear, /proc/cmp_text_asc) + var/new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in valid_underwear + ShowChoices(user) + if(new_underwear) + active_character.underwear = new_underwear + if("undershirt") + var/list/valid_undershirts = list() + for(var/undershirt in GLOB.undershirt_list) + var/datum/sprite_accessory/SA = GLOB.undershirt_list[undershirt] + if(active_character.gender == MALE && SA.gender == FEMALE) + continue + if(active_character.gender == FEMALE && SA.gender == MALE) + continue + if(!(active_character.species in SA.species_allowed)) + continue + valid_undershirts[undershirt] = GLOB.undershirt_list[undershirt] + sortTim(valid_undershirts, /proc/cmp_text_asc) + var/new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in valid_undershirts + ShowChoices(user) + if(new_undershirt) + active_character.undershirt = new_undershirt + + if("socks") + var/list/valid_sockstyles = list() + for(var/sockstyle in GLOB.socks_list) + var/datum/sprite_accessory/SA = GLOB.socks_list[sockstyle] + if(active_character.gender == MALE && SA.gender == FEMALE) + continue + if(active_character.gender == FEMALE && SA.gender == MALE) + continue + if(!(active_character.species in SA.species_allowed)) + continue + valid_sockstyles[sockstyle] = GLOB.socks_list[sockstyle] + sortTim(valid_sockstyles, /proc/cmp_text_asc) + var/new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in valid_sockstyles + ShowChoices(user) + if(new_socks) + active_character.socks = new_socks + + if("eyes") + var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference", active_character.e_colour) as color|null + if(new_eyes) + active_character.e_colour = new_eyes + + if("s_tone") + if(S.bodyflags & HAS_SKIN_TONE) + var/new_s_tone = input(user, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Character Preference") as num|null + if(new_s_tone) + active_character.s_tone = 35 - max(min(round(new_s_tone), 220), 1) + else if(S.bodyflags & HAS_ICON_SKIN_TONE) + var/const/MAX_LINE_ENTRIES = 4 + var/prompt = "Choose your character's skin tone: 1-[S.icon_skin_tones.len]\n(" + for(var/i = 1 to S.icon_skin_tones.len) + if(i > MAX_LINE_ENTRIES && !((i - 1) % MAX_LINE_ENTRIES)) + prompt += "\n" + prompt += "[i] = [S.icon_skin_tones[i]]" + if(i != S.icon_skin_tones.len) + prompt += ", " + prompt += ")" + var/skin_c = input(user, prompt, "Character Preference") as num|null + if(isnum(skin_c)) + active_character.s_tone = max(min(round(skin_c), S.icon_skin_tones.len), 1) + + if("skin") + if((S.bodyflags & HAS_SKIN_COLOR) || GLOB.body_accessory_by_species[active_character.species] || check_rights(R_ADMIN, 0, user)) + var/new_skin = input(user, "Choose your character's skin colour: ", "Character Preference", active_character.s_colour) as color|null + if(new_skin) + active_character.s_colour = new_skin + + if("ooccolor") + var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference", ooccolor) as color|null + if(new_ooccolor) + ooccolor = new_ooccolor + + if("bag") + var/new_backbag = input(user, "Choose your character's style of bag:", "Character Preference") as null|anything in GLOB.backbaglist + if(new_backbag) + active_character.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") + if(new_relation) + active_character.nanotrasen_relation = new_relation + + if("flavor_text") + var/msg = input(usr,"Set the flavor text in your 'examine' verb. The flavor text should be a physical descriptor of your character at a glance. SFW Drawn Art of your character is acceptable.","Flavor Text",html_decode(active_character.flavor_text)) as message + + if(msg != null) + msg = copytext(msg, 1, MAX_MESSAGE_LEN) + msg = html_encode(msg) + + active_character.flavor_text = msg + + if("limbs") + var/valid_limbs = list("Left Leg", "Right Leg", "Left Arm", "Right Arm", "Left Foot", "Right Foot", "Left Hand", "Right Hand") + if(S.bodyflags & ALL_RPARTS) + valid_limbs = list("Torso", "Lower Body", "Head", "Left Leg", "Right Leg", "Left Arm", "Right Arm", "Left Foot", "Right Foot", "Left Hand", "Right Hand") + var/limb_name = input(user, "Which limb do you want to change?") as null|anything in valid_limbs + if(!limb_name) return + + var/limb = null + var/second_limb = null // if you try to change the arm, the hand should also change + var/third_limb = null // if you try to unchange the hand, the arm should also change + var/valid_limb_states = list("Normal", "Amputated", "Prosthesis") + var/no_amputate = 0 + + switch(limb_name) + if("Torso") + limb = "chest" + second_limb = "groin" + no_amputate = 1 + if("Lower Body") + limb = "groin" + no_amputate = 1 + if("Head") + limb = "head" + no_amputate = 1 + if("Left Leg") + limb = "l_leg" + second_limb = "l_foot" + if("Right Leg") + limb = "r_leg" + second_limb = "r_foot" + if("Left Arm") + limb = "l_arm" + second_limb = "l_hand" + if("Right Arm") + limb = "r_arm" + second_limb = "r_hand" + if("Left Foot") + limb = "l_foot" + if(!(S.bodyflags & ALL_RPARTS)) + third_limb = "l_leg" + if("Right Foot") + limb = "r_foot" + if(!(S.bodyflags & ALL_RPARTS)) + third_limb = "r_leg" + if("Left Hand") + limb = "l_hand" + if(!(S.bodyflags & ALL_RPARTS)) + third_limb = "l_arm" + if("Right Hand") + limb = "r_hand" + if(!(S.bodyflags & ALL_RPARTS)) + third_limb = "r_arm" + + var/new_state = input(user, "What state do you wish the limb to be in?") as null|anything in valid_limb_states + if(!new_state) return + + switch(new_state) + if("Normal") + if(limb == "head") + active_character.m_styles["head"] = "None" + active_character.h_style = GLOB.hair_styles_public_list["Bald"] + active_character.f_style = GLOB.facial_hair_styles_list["Shaved"] + active_character.organ_data[limb] = null + active_character.rlimb_data[limb] = null + if(third_limb) + active_character.organ_data[third_limb] = null + active_character.rlimb_data[third_limb] = null + if("Amputated") + if(!no_amputate) + active_character.organ_data[limb] = "amputated" + active_character.rlimb_data[limb] = null + if(second_limb) + active_character.organ_data[second_limb] = "amputated" + active_character.rlimb_data[second_limb] = null + if("Prosthesis") + var/choice + var/subchoice + var/datum/robolimb/R = new() + var/in_model + var/robolimb_companies = list() + for(var/limb_type in typesof(/datum/robolimb)) //This loop populates a list of companies that offer the limb the user selected previously as one of their cybernetic products. + R = new limb_type() + if(!R.unavailable_at_chargen && (limb in R.parts) && R.has_subtypes) //Ensures users can only choose companies that offer the parts they want, that singular models get added to the list as well companies that offer more than one model, and... + robolimb_companies[R.company] = R //List only main brands that have the parts we're looking for. + R = new() //Re-initialize R. + + choice = input(user, "Which manufacturer do you wish to use for this limb?") as null|anything in robolimb_companies //Choose from a list of companies that offer the part the user wants. + if(!choice) + return + R.company = choice + R = GLOB.all_robolimbs[R.company] + if(R.has_subtypes == 1) //If the company the user selected provides more than just one base model, lets handle it. + var/list/robolimb_models = list() + for(var/limb_type in typesof(R)) //Handling the different models of parts that manufacturers can provide. + var/datum/robolimb/L = new limb_type() + if(limb in L.parts) //Make sure that only models that provide the parts the user needs populate the list. + robolimb_models[L.company] = L + if(robolimb_models.len == 1) //If there's only one model available in the list, autoselect it to avoid having to bother the user with a dialog that provides only one option. + subchoice = L.company //If there ends up being more than one model populating the list, subchoice will be overwritten later anyway, so this isn't a problem. + if(second_limb in L.parts) //If the child limb of the limb the user selected is also present in the model's parts list, state it's been found so the second limb can be set later. + in_model = 1 + if(robolimb_models.len > 1) //If there's more than one model in the list that can provide the part the user wants, let them choose. + subchoice = input(user, "Which model of [choice] [limb_name] do you wish to use?") as null|anything in robolimb_models + if(subchoice) + choice = subchoice + if(limb in list("head", "chest", "groin")) + if(!(S.bodyflags & ALL_RPARTS)) + return + if(limb == "head") + active_character.ha_style = "None" + active_character.alt_head = null + active_character.h_style = GLOB.hair_styles_public_list["Bald"] + active_character.f_style = GLOB.facial_hair_styles_list["Shaved"] + active_character.m_styles["head"] = "None" + active_character.rlimb_data[limb] = choice + active_character.organ_data[limb] = "cyborg" + if(second_limb) + if(subchoice) + if(in_model) + active_character.rlimb_data[second_limb] = choice + active_character.organ_data[second_limb] = "cyborg" + else + active_character.rlimb_data[second_limb] = choice + active_character.organ_data[second_limb] = "cyborg" + if("organs") + var/organ_name = input(user, "Which internal function do you want to change?") as null|anything in list("Eyes", "Ears", "Heart", "Lungs", "Liver", "Kidneys") + if(!organ_name) + return + + var/organ = null + switch(organ_name) + if("Eyes") + organ = "eyes" + if("Ears") + organ = "ears" + if("Heart") + organ = "heart" + if("Lungs") + organ = "lungs" + if("Liver") + organ = "liver" + if("Kidneys") + organ = "kidneys" + + var/new_state = input(user, "What state do you wish the organ to be in?") as null|anything in list("Normal", "Cybernetic") + if(!new_state) return + + switch(new_state) + if("Normal") + active_character.organ_data[organ] = null + if("Cybernetic") + active_character.organ_data[organ] = "cybernetic" + + if("clientfps") + var/version_message + if(user.client && user.client.byond_version < 511) + version_message = "\nYou need to be using byond version 511 or later to take advantage of this feature, your version of [user.client.byond_version] is too low" + if(world.byond_version < 511) + version_message += "\nThis server does not currently support client side fps. You can set now for when it does." + var/desiredfps = input(user, "Choose your desired fps.[version_message]\n(0 = synced with server tick rate (currently:[world.fps]))", "Character Preference", clientfps) as null|num + if(!isnull(desiredfps)) + clientfps = desiredfps + if(world.byond_version >= 511 && user.client && user.client.byond_version >= 511) + parent.fps = clientfps + + else + switch(href_list["preference"]) + if("publicity") + if(unlock_content) + toggles ^= PREFTOGGLE_MEMBER_PUBLIC + + if("donor_public") + if(user.client.donator_level > 0) + toggles ^= PREFTOGGLE_DONATOR_PUBLIC + + if("gender") + if(!S.has_gender) + var/newgender = input(user, "Choose Gender:") as null|anything in list("Male", "Female", "Genderless") + switch(newgender) + if("Male") + active_character.gender = MALE + if("Female") + active_character.gender = FEMALE + if("Genderless") + active_character.gender = PLURAL + else + if(active_character.gender == MALE) + active_character.gender = FEMALE + else + active_character.gender = MALE + active_character.underwear = random_underwear(active_character.gender) + + if("hear_adminhelps") + sound ^= SOUND_ADMINHELP + if("ui") + switch(UI_style) + if("Midnight") + UI_style = "Plasmafire" + if("Plasmafire") + UI_style = "Retro" + if("Retro") + UI_style = "Slimecore" + if("Slimecore") + UI_style = "Operative" + if("Operative") + UI_style = "White" + else + UI_style = "Midnight" + + if(ishuman(usr)) //mid-round preference changes, for aesthetics + var/mob/living/carbon/human/H = usr + H.remake_hud() + + if("tgui") + toggles2 ^= PREFTOGGLE_2_FANCYUI + + if("ghost_att_anim") + toggles2 ^= PREFTOGGLE_2_ITEMATTACK + + if("winflash") + toggles2 ^= PREFTOGGLE_2_WINDOWFLASHING + + if("afk_watch") + if(!(toggles2 & PREFTOGGLE_2_AFKWATCH)) + to_chat(user, "You will now get put into cryo dorms after [GLOB.configuration.afk.auto_cryo_minutes] minutes. \ + Then after [GLOB.configuration.afk.auto_despawn_minutes] minutes you will be fully despawned. You will receive a visual and auditory warning before you will be put into cryodorms.") + else + to_chat(user, "Automatic cryoing turned off.") + toggles2 ^= PREFTOGGLE_2_AFKWATCH + + if("UIcolor") + var/UI_style_color_new = input(user, "Choose your UI color, dark colors are not recommended!", UI_style_color) as color|null + if(!UI_style_color_new) return + UI_style_color = UI_style_color_new + + if(ishuman(usr)) //mid-round preference changes, for aesthetics + var/mob/living/carbon/human/H = usr + H.remake_hud() + + if("UIalpha") + var/UI_style_alpha_new = input(user, "Select a new alpha(transparence) parameter for UI, between 50 and 255", UI_style_alpha) as num + if(!UI_style_alpha_new || !(UI_style_alpha_new <= 255 && UI_style_alpha_new >= 50)) + return + UI_style_alpha = UI_style_alpha_new + + if(ishuman(usr)) //mid-round preference changes, for aesthetics + var/mob/living/carbon/human/H = usr + H.remake_hud() + + if("be_special") + var/r = href_list["role"] + if(r in GLOB.special_roles) + be_special ^= r + + if("name") + active_character.be_random_name = !active_character.be_random_name + + if("randomslot") + toggles2 ^= PREFTOGGLE_2_RANDOMSLOT + if(isnewplayer(usr)) + var/mob/new_player/N = usr + N.new_player_panel_proc() + + if("hear_midis") + sound ^= SOUND_MIDI + + if("lobby_music") + sound ^= SOUND_LOBBY + if((sound & SOUND_LOBBY) && user.client) + user.client.playtitlemusic() + else + user.stop_sound_channel(CHANNEL_LOBBYMUSIC) + + if("ghost_ears") + toggles ^= PREFTOGGLE_CHAT_GHOSTEARS + + if("ghost_sight") + toggles ^= PREFTOGGLE_CHAT_GHOSTSIGHT + + if("ghost_radio") + toggles ^= PREFTOGGLE_CHAT_GHOSTRADIO + + if("ghost_pda") + toggles ^= PREFTOGGLE_CHAT_GHOSTPDA + + if("ghost_anonsay") + toggles2 ^= PREFTOGGLE_2_ANONDCHAT + + if("save") + save_preferences(user) + active_character.save(user) + + if("clear") + if(!active_character.from_db || active_character.real_name != input("This will clear the current slot permanently. Please enter the character's full name to confirm.")) + return FALSE + active_character.clear_character_slot(user) + // Gimmie a freshie + var/datum/character_save/CS = new + character_saves[active_character.slot_number] = CS + CS.slot_number = active_character.slot_number // Dont lose this + active_character = CS + + if("open_load_dialog") + if(!IsGuestKey(user.key)) + open_load_dialog(user) + return 1 + + if("close_load_dialog") + close_load_dialog(user) + + if("changeslot") + active_character = character_saves[text2num(href_list["num"])] + default_slot = text2num(href_list["num"]) + close_load_dialog(user) + if(isnewplayer(user)) + var/mob/new_player/N = user + N.new_player_panel_proc() + + if("tab") + if(href_list["tab"]) + current_tab = text2num(href_list["tab"]) + + + if("ambientocclusion") + toggles ^= PREFTOGGLE_AMBIENT_OCCLUSION + if(length(parent?.screen)) + var/obj/screen/plane_master/game_world/PM = locate(/obj/screen/plane_master/game_world) in parent.screen + PM.backdrop(parent.mob) + + if("parallax") + var/parallax_styles = list( + "Off" = PARALLAX_DISABLE, + "Low" = PARALLAX_LOW, + "Medium" = PARALLAX_MED, + "High" = PARALLAX_HIGH, + "Insane" = PARALLAX_INSANE + ) + parallax = parallax_styles[input(user, "Pick a parallax style", "Parallax Style") as null|anything in parallax_styles] + if(parent && parent.mob && parent.mob.hud_used) + parent.mob.hud_used.update_parallax_pref() + + if("edit_2fa") + // Do this async so we arent holding up a topic() call + INVOKE_ASYNC(user.client, /client.proc/edit_2fa) + return // We return here to avoid focus being lost + + + ShowChoices(user) + return 1 diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index b4688cb73b4..e88dfae2e32 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -1,6 +1,3 @@ -GLOBAL_LIST_EMPTY(preferences_datums) -GLOBAL_PROTECT(preferences_datums) // These feel like something that shouldnt be fucked with - GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts to play these roles ROLE_PAI = 0, ROLE_POSIBRAIN = 0, @@ -54,19 +51,10 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts else return max(0, days - C.player_age) -#define MAX_SAVE_SLOTS 30 // Save slots for regular players -#define MAX_SAVE_SLOTS_MEMBER 30 // Save slots for BYOND members - -#define TAB_CHAR 0 -#define TAB_GAME 1 -#define TAB_GEAR 2 - /datum/preferences var/client/parent //doohickeys for savefiles -// var/path var/default_slot = 1 //Holder so it doesn't default to slot 1, rather the last one used -// var/savefile_version = 0 var/max_save_slots = MAX_SAVE_SLOTS var/max_gear_slots = 0 @@ -89,98 +77,6 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts var/atklog = ATKLOG_ALL var/fuid // forum userid - //character preferences - var/real_name //our character's name - var/be_random_name = 0 //whether we are a random name every round - var/gender = MALE //gender of character (well duh) - var/age = 30 //age of character - var/spawnpoint = "Arrivals Shuttle" //where this character will spawn (0-2). - var/b_type = "A+" //blood type (not-chooseable) - var/underwear = "Nude" //underwear type - var/undershirt = "Nude" //undershirt type - var/socks = "Nude" //socks type - var/backbag = GBACKPACK //backpack type - var/ha_style = "None" //Head accessory style - var/hacc_colour = "#000000" //Head accessory colour - var/list/m_styles = list( - "head" = "None", - "body" = "None", - "tail" = "None" - ) //Marking styles. - var/list/m_colours = list( - "head" = "#000000", - "body" = "#000000", - "tail" = "#000000" - ) //Marking colours. - var/h_style = "Bald" //Hair type - var/h_colour = "#000000" //Hair color - var/h_sec_colour = "#000000" //Secondary hair color - var/f_style = "Shaved" //Facial hair type - var/f_colour = "#000000" //Facial hair color - var/f_sec_colour = "#000000" //Secondary facial hair color - var/s_tone = 0 //Skin tone - var/s_colour = "#000000" //Skin color - var/e_colour = "#000000" //Eye color - var/alt_head = "None" //Alt head style. - var/species = "Human" - var/language = "None" //Secondary language - var/autohiss_mode = AUTOHISS_OFF //Species autohiss level. OFF, BASIC, FULL. - - var/body_accessory = null - - var/speciesprefs = 0//I hate having to do this, I really do (Using this for oldvox code, making names universal I guess - - //Mob preview - var/icon/preview_icon = null - var/icon/preview_icon_front = null - var/icon/preview_icon_side = null - - //Jobs, uses bitflags - var/job_support_high = 0 - var/job_support_med = 0 - var/job_support_low = 0 - - var/job_medsci_high = 0 - var/job_medsci_med = 0 - var/job_medsci_low = 0 - - var/job_engsec_high = 0 - var/job_engsec_med = 0 - var/job_engsec_low = 0 - - var/job_karma_high = 0 - var/job_karma_med = 0 - var/job_karma_low = 0 - - //Keeps track of preferrence for not getting any wanted jobs - 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 ;) - var/list/organ_data = list() - var/list/rlimb_data = list() - - var/list/player_alt_titles = new() // the default name of a job like "Medical Doctor" -// var/accent = "en-us" -// var/voice = "m1" -// var/pitch = 50 -// var/talkspeed = 175 - var/flavor_text = "" - var/med_record = "" - var/sec_record = "" - var/gen_record = "" - var/disabilities = 0 - - var/nanotrasen_relation = "Neutral" - - // 0 = character settings, 1 = game preferences - var/current_tab = TAB_CHAR - - // OOC Metadata: - var/metadata = "" - var/slot_name = "" - var/saved = FALSE // Indicates whether the character comes from the database or not - /// Volume mixer, indexed by channel as TEXT (numerical indexes will not work). Volume goes from 0 to 100. var/list/volume_mixer = list( "1024" = 100, // CHANNEL_LOBBYMUSIC @@ -198,39 +94,41 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts // BYOND membership var/unlock_content = 0 - //Gear stuff - var/list/loadout_gear = list() var/gear_tab = "General" // Parallax var/parallax = PARALLAX_HIGH /// 2FA status var/_2fa_status = _2FA_DISABLED - /// Do we want to force our runechat colour to be white? - var/force_white_runechat = FALSE + /// Did we load successfully? + var/successful_load = FALSE + /// Have we loaded characters already? + var/characters_loaded = FALSE -/datum/preferences/New(client/C) + // 0 = character settings, 1 = game preferences, 2 = loadout + var/current_tab = TAB_CHAR + + /// List of all character saves we have. This is indexed based on the slot number + var/list/datum/character_save/character_saves = list() + /// The current active character + var/datum/character_save/active_character + +/datum/preferences/New(client/C, datum/db_query/Q) // Process our query parent = C - b_type = pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+") max_gear_slots = GLOB.configuration.general.base_loadout_points - var/loaded_preferences_successfully = FALSE + + if(!SSdbcore.IsConnected()) + return // Bail + if(istype(C)) if(!IsGuestKey(C.key)) unlock_content = C.IsByondMember() if(unlock_content) max_save_slots = MAX_SAVE_SLOTS_MEMBER - loaded_preferences_successfully = load_preferences(C) // Do not call this with no client/C, it generates a runtime / SQL error - if(loaded_preferences_successfully) - if(load_character(C)) - return - //we couldn't load character data so just randomize the character appearance + name - random_character() //let's create a random character then - rather than a fat, bald and naked man. - real_name = random_name(gender) - if(istype(C)) - if(!loaded_preferences_successfully) - save_preferences(C) // Do not call this with no client/C, it generates a runtime / SQL error - save_character(C) // Do not call this with no client/C, it generates a runtime / SQL error + successful_load = load_preferences(Q) + if(!successful_load) + to_chat(C, "Your preferences failed to load. Please inform the server host immediately.") /datum/preferences/proc/color_square(colour) return "___" @@ -239,9 +137,9 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts /datum/preferences/proc/ShowChoices(mob/user) if(!user || !user.client) return - update_preview_icon() - user << browse_rsc(preview_icon_front, "previewicon.png") - user << browse_rsc(preview_icon_side, "previewicon2.png") + active_character.update_preview_icon() + user << browse_rsc(active_character.preview_icon_front, "previewicon.png") + user << browse_rsc(active_character.preview_icon_side, "previewicon2.png") var/dat = "" dat += "
    " @@ -253,26 +151,25 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts switch(current_tab) if(TAB_CHAR) // Character Settings - var/datum/species/S = GLOB.all_species[species] + var/datum/species/S = GLOB.all_species[active_character.species] if(!istype(S)) //The species was invalid. Set the species to the default, fetch the datum for that species and generate a random character. - species = initial(species) - S = GLOB.all_species[species] - random_character() + active_character.species = initial(active_character.species) + S = GLOB.all_species[active_character.species] + active_character.randomise() dat += "
    " dat += "
    " dat += "Name: " - dat += "[real_name]" + dat += "[active_character.real_name]" dat += "(Randomize)" - dat += "(Always Randomize)
    " + dat += "(Always Randomize)
    " dat += "
    " dat += "
    " - dat += "Slot [default_slot][saved ? "" : " (empty)"]
    " + dat += "Slot [default_slot][active_character.from_db ? "" : " (empty)"]
    " dat += "Load slot - " - dat += "Save slot - " - dat += "Reload slot" - if(saved) - dat += " - Clear slot" + dat += "Save slot" + if(active_character.from_db) + dat += "- Clear slot" dat += "
    " dat += "
    " dat += "
    " @@ -281,81 +178,83 @@ GLOBAL_LIST_INIT(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" : (gender == FEMALE ? "Female" : "Genderless")]" + dat += "Gender: [active_character.gender == MALE ? "Male" : (active_character.gender == FEMALE ? "Female" : "Genderless")]" dat += "
    " - dat += "Age: [age]
    " + dat += "Age: [active_character.age]
    " dat += "Body: (®)
    " - dat += "Species: [species]
    " - if(species == "Vox") - dat += "N2 Tank: [speciesprefs ? "Large N2 Tank" : "Specialized N2 Tank"]
    " - if(species == "Grey") + dat += "Species: [active_character.species]
    " + if(active_character.species == "Vox") // Purge these bastards + dat += "N2 Tank: [active_character.speciesprefs ? "Large N2 Tank" : "Specialized N2 Tank"]
    " + if(active_character.species == "Grey") dat += "Wingdings: Set in disabilities
    " - dat += "Voice Translator: [speciesprefs ? "Yes" : "No"]
    " - dat += "Secondary Language: [language]
    " + dat += "Voice Translator: [active_character.speciesprefs ? "Yes" : "No"]
    " + dat += "Secondary Language: [active_character.language]
    " if(S.autohiss_basic_map) - dat += "Auto-accent: [autohiss_mode == AUTOHISS_FULL ? "Full" : (autohiss_mode == AUTOHISS_BASIC ? "Basic" : "Off")]
    " - dat += "Blood Type: [b_type]
    " + dat += "Auto-accent: [active_character.autohiss_mode == AUTOHISS_FULL ? "Full" : (active_character.autohiss_mode == AUTOHISS_BASIC ? "Basic" : "Off")]
    " + dat += "Blood Type: [active_character.b_type]
    " if(S.bodyflags & (HAS_SKIN_TONE|HAS_ICON_SKIN_TONE)) - dat += "Skin Tone: [S.bodyflags & HAS_ICON_SKIN_TONE ? "[s_tone]" : "[-s_tone + 35]/220"]
    " + dat += "Skin Tone: [S.bodyflags & HAS_ICON_SKIN_TONE ? "[active_character.s_tone]" : "[-active_character.s_tone + 35]/220"]
    " dat += "Disabilities: \[Set\]
    " - dat += "Nanotrasen Relation: [nanotrasen_relation]
    " + dat += "Nanotrasen Relation: [active_character.nanotrasen_relation]
    " dat += "Set Flavor Text
    " - if(length(flavor_text) <= 40) - if(!length(flavor_text)) dat += "\[...\]
    " - else dat += "[flavor_text]
    " - else dat += "[TextPreview(flavor_text)]...
    " + if(length(active_character.flavor_text) <= 40) + if(!length(active_character.flavor_text)) + dat += "\[...\]
    " + else + dat += "[active_character.flavor_text]
    " + else dat += "[TextPreview(active_character.flavor_text)]...
    " dat += "

    Hair & Accessories

    " if(S.bodyflags & HAS_HEAD_ACCESSORY) //Species that have head accessories. var/headaccessoryname = "Head Accessory: " - if(species == "Unathi") + if(active_character.species == "Unathi") headaccessoryname = "Horns: " dat += "[headaccessoryname]" - dat += "[ha_style] " - dat += "Color [color_square(hacc_colour)]
    " + dat += "[active_character.ha_style] " + dat += "Color [color_square(active_character.hacc_colour)]
    " if(S.bodyflags & HAS_HEAD_MARKINGS) //Species with head markings. dat += "Head Markings: " - dat += "[m_styles["head"]]" - dat += "Color [color_square(m_colours["head"])]
    " + dat += "[active_character.m_styles["head"]]" + dat += "Color [color_square(active_character.m_colours["head"])]
    " if(S.bodyflags & HAS_BODY_MARKINGS) //Species with body markings/tattoos. dat += "Body Markings: " - dat += "[m_styles["body"]]" - dat += "Color [color_square(m_colours["body"])]
    " + dat += "[active_character.m_styles["body"]]" + dat += "Color [color_square(active_character.m_colours["body"])]
    " if(S.bodyflags & HAS_TAIL_MARKINGS) //Species with tail markings. dat += "Tail Markings: " - dat += "[m_styles["tail"]]" - dat += "Color [color_square(m_colours["tail"])]
    " + dat += "[active_character.m_styles["tail"]]" + dat += "Color [color_square(active_character.m_colours["tail"])]
    " dat += "Hair: " - dat += "[h_style]" - dat += "Color [color_square(h_colour)]" - var/datum/sprite_accessory/temp_hair_style = GLOB.hair_styles_public_list[h_style] + dat += "[active_character.h_style]" + dat += "Color [color_square(active_character.h_colour)]" + var/datum/sprite_accessory/temp_hair_style = GLOB.hair_styles_public_list[active_character.h_style] if(temp_hair_style && temp_hair_style.secondary_theme && !temp_hair_style.no_sec_colour) - dat += " Color #2 [color_square(h_sec_colour)]" + dat += " Color #2 [color_square(active_character.h_sec_colour)]" dat += "
    " dat += "Facial Hair: " - dat += "[f_style ? "[f_style]" : "Shaved"]" - dat += "Color [color_square(f_colour)]" - var/datum/sprite_accessory/temp_facial_hair_style = GLOB.facial_hair_styles_list[f_style] + dat += "[active_character.f_style ? "[active_character.f_style]" : "Shaved"]" + dat += "Color [color_square(active_character.f_colour)]" + var/datum/sprite_accessory/temp_facial_hair_style = GLOB.facial_hair_styles_list[active_character.f_style] if(temp_facial_hair_style && temp_facial_hair_style.secondary_theme && !temp_facial_hair_style.no_sec_colour) - dat += " Color #2 [color_square(f_sec_colour)]" + dat += " Color #2 [color_square(active_character.f_sec_colour)]" dat += "
    " if(!(S.bodyflags & ALL_RPARTS)) dat += "Eyes: " - dat += "Color [color_square(e_colour)]
    " + dat += "Color [color_square(active_character.e_colour)]
    " - if((S.bodyflags & HAS_SKIN_COLOR) || GLOB.body_accessory_by_species[species] || check_rights(R_ADMIN, 0, user)) //admins can always fuck with this, because they are admins + if((S.bodyflags & HAS_SKIN_COLOR) || GLOB.body_accessory_by_species[active_character.species] || check_rights(R_ADMIN, 0, user)) //admins can always fuck with this, because they are admins dat += "Body Color: " - dat += "Color [color_square(s_colour)]
    " + dat += "Color [color_square(active_character.s_colour)]
    " - if(GLOB.body_accessory_by_species[species] || check_rights(R_ADMIN, 0, user)) + if(GLOB.body_accessory_by_species[active_character.species] || check_rights(R_ADMIN, 0, user)) dat += "Body Accessory: " - dat += "[body_accessory ? "[body_accessory]" : "None"]
    " + dat += "[active_character.body_accessory ? "[active_character.body_accessory]" : "None"]
    " dat += "
    " dat += "

    Occupation Choices

    " @@ -368,15 +267,15 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts dat += "

    Limbs

    " if(S.bodyflags & HAS_ALT_HEADS) //Species with alt heads. dat += "Alternate Head: " - dat += "[alt_head]
    " + dat += "[active_character.alt_head]
    " dat += "Limbs and Parts: Adjust
    " - if(species != "Slime People" && species != "Machine") + if(active_character.species != "Slime People" && active_character.species != "Machine") dat += "Internal Organs: Adjust
    " //display limbs below var/ind = 0 - for(var/name in organ_data) - var/status = organ_data[name] + for(var/name in active_character.organ_data) + var/status = active_character.organ_data[name] var/organ_name = null switch(name) if("chest") @@ -421,8 +320,8 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts switch(status) if("cyborg") var/datum/robolimb/R - if(rlimb_data[name] && GLOB.all_robolimbs[rlimb_data[name]]) - R = GLOB.all_robolimbs[rlimb_data[name]] + if(active_character.rlimb_data[name] && GLOB.all_robolimbs[active_character.rlimb_data[name]]) + R = GLOB.all_robolimbs[active_character.rlimb_data[name]] else R = GLOB.basic_robolimb dat += "\t[R.company] [organ_name] prosthesis" @@ -435,12 +334,12 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts dat += "

    Clothing

    " if(S.clothing_flags & HAS_UNDERWEAR) - dat += "Underwear: [underwear]
    " + dat += "Underwear: [active_character.underwear]
    " if(S.clothing_flags & HAS_UNDERSHIRT) - dat += "Undershirt: [undershirt]
    " + dat += "Undershirt: [active_character.undershirt]
    " if(S.clothing_flags & HAS_SOCKS) - dat += "Socks: [socks]
    " - dat += "Backpack Type: [backbag]
    " + dat += "Socks: [active_character.socks]
    " + dat += "Backpack Type: [active_character.backbag]
    " dat += "
    " @@ -516,9 +415,9 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts if(TAB_GEAR) var/total_cost = 0 var/list/type_blacklist = list() - if(loadout_gear && loadout_gear.len) - for(var/i = 1, i <= loadout_gear.len, i++) - var/datum/gear/G = GLOB.gear_datums[loadout_gear[i]] + if(length(active_character.loadout_gear)) + for(var/i in 1 to length(active_character.loadout_gear)) + var/datum/gear/G = GLOB.gear_datums[active_character.loadout_gear[i]] if(G) if(!G.subtype_cost_overlap) if(G.subtype_path in type_blacklist) @@ -551,7 +450,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts dat += "
    " for(var/gear_name in LC.gear) var/datum/gear/G = LC.gear[gear_name] - var/ticked = (G.display_name in loadout_gear) + var/ticked = (G.display_name in active_character.loadout_gear) if(G.donator_tier > user.client.donator_level) dat += "[G.display_name]" else @@ -566,7 +465,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts if(ticked) . += "" for(var/datum/gear_tweak/tweak in G.gear_tweaks) - . += " [tweak.get_contents(get_tweak_metadata(G, tweak))]" + . += " [tweak.get_contents(active_character.get_tweak_metadata(G, tweak))]" . += "" dat += "" @@ -582,262 +481,33 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts popup.set_content(dat) popup.open(0) +/datum/preferences/proc/open_load_dialog(mob/user) + var/dat = "" + dat += "
    " + dat += "Select a character slot to load
    " + var/name -/datum/preferences/proc/get_gear_metadata(datum/gear/G) - . = loadout_gear[G.display_name] - if(!.) - . = list() - loadout_gear[G.display_name] = . + for(var/i in 1 to length(character_saves)) + var/datum/character_save/CS = character_saves[i] + if(CS.from_db) + name = CS.real_name + else + name = "Character [i]" + if(i == default_slot) + name = "[name]" + dat += "[name]
    " -/datum/preferences/proc/get_tweak_metadata(datum/gear/G, datum/gear_tweak/tweak) - var/list/metadata = get_gear_metadata(G) - . = metadata["[tweak]"] - if(!.) - . = tweak.get_default() - metadata["[tweak]"] = . + dat += "
    " + dat += "Close
    " + dat += "
    " -/datum/preferences/proc/set_tweak_metadata(datum/gear/G, datum/gear_tweak/tweak, new_metadata) - var/list/metadata = get_gear_metadata(G) - metadata["[tweak]"] = new_metadata - - -/datum/preferences/proc/SetChoices(mob/user, limit = 17, list/splitJobs = list("Head of Security", "Bartender"), widthPerColumn = 400, height = 700) - if(!SSjobs) - return - - //limit - The amount of jobs allowed per column. Defaults to 17 to make it look nice. - //splitJobs - Allows you split the table by job. You can make different tables for each department by including their heads. Defaults to CE to make it look nice. - //widthPerColumn - Screen's width for every column. - //height - Screen's height. - var/width = widthPerColumn - - - var/list/html = list() - html += "" - if(!length(SSjobs.occupations)) - html += "The Jobs subsystem is not yet finished creating jobs, please try again later" - html += "
    Done

    " // Easier to press up here. - else - html += "
    " - html += "Choose occupation chances
    Unavailable occupations are crossed out.

    " - html += "
    Save

    " // Easier to press up here. - html += "
    Left-click to raise an occupation preference, right-click to lower it.
    " - html += "" - html += "
    " // Table within a table for alignment, also allows you to easily add more colomns. - html += "" - var/index = -1 - - //The job before the current job. I only use this to get the previous jobs color when I'm filling in blank rows. - var/datum/job/lastJob - if(!SSjobs) - return - for(var/J in SSjobs.occupations) - var/datum/job/job = J - - if(job.admin_only) - continue - - if(job.hidden_from_job_prefs) - continue - - index += 1 - if((index >= limit) || (job.title in splitJobs)) - if((index < limit) && (lastJob != null)) - // Dynamic window width - width += widthPerColumn - //If the cells were broken up by a job in the splitJob list then it will fill in the rest of the cells with - //the last job's selection color. Creating a rather nice effect. - for(var/i in 1 to limit - index) - html += "" - html += "
      
    " - index = 0 - - html += "" - continue - if(jobban_isbanned(user, job.title)) - html += "[rank]" - continue - var/available_in_playtime = job.available_in_playtime(user.client) - if(available_in_playtime) - html += "[rank]" - continue - if(job.barred_by_disability(user.client)) - html += "[rank]" - continue - if(!job.player_old_enough(user.client)) - var/available_in_days = job.available_in_days(user.client) - html += "[rank]" - continue - if((job_support_low & JOB_CIVILIAN) && (job.title != "Civilian")) - html += "[rank]" - continue - if((job.title in GLOB.command_positions) || (job.title == "AI"))//Bold head jobs - html += "[rank]" - else - html += "[rank]" - - html += "" - continue - /* - if(GetJobDepartment(job, 1) & job.flag) - HTML += " \[High]" - else if(GetJobDepartment(job, 2) & job.flag) - HTML += " \[Medium]" - else if(GetJobDepartment(job, 3) & job.flag) - HTML += " \[Low]" - else - HTML += " \[NEVER]" - */ - html += "[prefLevelLabel]" - - html += "" - - for(var/i in 1 to limit - index) // Finish the column so it is even - html += "" - - html += "
    " - var/rank - if(job.alt_titles) - rank = "[GetPlayerAltTitle(job)]" - else - rank = job.title - lastJob = job - if(!is_job_whitelisted(user, job.title)) - html += "[rank] \[KARMA]
    \[BANNED]
    \[" + get_exp_format(available_in_playtime) + " as " + job.get_exp_req_type() + "\]
    \[DISABILITY\]
    \[IN [(available_in_days)] DAYS]
    " - - var/prefLevelLabel = "ERROR" - var/prefLevelColor = "pink" - var/prefUpperLevel = -1 // level to assign on left click - var/prefLowerLevel = -1 // level to assign on right click - - if(GetJobDepartment(job, 1) & job.flag) - prefLevelLabel = "High" - prefLevelColor = "slateblue" - prefUpperLevel = 4 - prefLowerLevel = 2 - else if(GetJobDepartment(job, 2) & job.flag) - prefLevelLabel = "Medium" - prefLevelColor = "green" - prefUpperLevel = 1 - prefLowerLevel = 3 - else if(GetJobDepartment(job, 3) & job.flag) - prefLevelLabel = "Low" - prefLevelColor = "orange" - prefUpperLevel = 2 - prefLowerLevel = 4 - else - prefLevelLabel = "NEVER" - prefLevelColor = "red" - prefUpperLevel = 3 - prefLowerLevel = 1 - - - html += "" - - // HTML += "" - - if(job.title == "Civilian")//Civilian is special - if(job_support_low & JOB_CIVILIAN) - html += " Yes" - else - html += " No" - html += "
      
    " - html += "
    " - - switch(alternate_option) - if(GET_RANDOM_JOB) - html += "

    Get random job if preferences unavailable

    " - if(BE_ASSISTANT) - html += "

    Be a civilian if preferences unavailable

    " - if(RETURN_TO_LOBBY) - html += "

    Return to lobby if preferences unavailable

    " - - html += "
    Reset
    " - html += "

    Learn About Job Selection
    " - html += "
    " - - user << browse(null, "window=preferences") -// user << browse(HTML, "window=mob_occupation;size=[width]x[height]") - var/datum/browser/popup = new(user, "mob_occupation", "
    Occupation Preferences
    ", width, height) - popup.set_window_options("can_close=0") - var/html_string = html.Join() - popup.set_content(html_string) + var/datum/browser/popup = new(user, "saves", "
    Character Saves
    ", 300, 390) + popup.set_content(dat) popup.open(0) - return -/datum/preferences/proc/SetJobPreferenceLevel(datum/job/job, level) - if(!job) - return 0 +/datum/preferences/proc/close_load_dialog(mob/user) + user << browse(null, "window=saves") - if(level == 1) // to high - // remove any other job(s) set to high - job_support_med |= job_support_high - job_engsec_med |= job_engsec_high - job_medsci_med |= job_medsci_high - job_karma_med |= job_karma_high - job_support_high = 0 - job_engsec_high = 0 - job_medsci_high = 0 - job_karma_high = 0 - - if(job.department_flag == JOBCAT_SUPPORT) - job_support_low &= ~job.flag - job_support_med &= ~job.flag - job_support_high &= ~job.flag - - switch(level) - if(1) - job_support_high |= job.flag - if(2) - job_support_med |= job.flag - if(3) - job_support_low |= job.flag - - return 1 - else if(job.department_flag == JOBCAT_ENGSEC) - job_engsec_low &= ~job.flag - job_engsec_med &= ~job.flag - job_engsec_high &= ~job.flag - - switch(level) - if(1) - job_engsec_high |= job.flag - if(2) - job_engsec_med |= job.flag - if(3) - job_engsec_low |= job.flag - - return 1 - else if(job.department_flag == JOBCAT_MEDSCI) - job_medsci_low &= ~job.flag - job_medsci_med &= ~job.flag - job_medsci_high &= ~job.flag - - switch(level) - if(1) - job_medsci_high |= job.flag - if(2) - job_medsci_med |= job.flag - if(3) - job_medsci_low |= job.flag - - return 1 - else if(job.department_flag == JOBCAT_KARMA) - job_karma_low &= ~job.flag - job_karma_med &= ~job.flag - job_karma_high &= ~job.flag - - switch(level) - if(1) - job_karma_high |= job.flag - if(2) - job_karma_med |= job.flag - if(3) - job_karma_low |= job.flag - - return 1 - - return 0 /datum/preferences/proc/UpdateJobPreference(mob/user, role, desiredLvl) var/datum/job/job = SSjobs.GetJob(role) @@ -853,96 +523,19 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts return if(role == "Civilian") - if(job_support_low & job.flag) - job_support_low &= ~job.flag + if(active_character.job_support_low & job.flag) + active_character.job_support_low &= ~job.flag else - job_support_low |= job.flag - SetChoices(user) + active_character.job_support_low |= job.flag + active_character.SetChoices(user) return 1 - SetJobPreferenceLevel(job, desiredLvl) - SetChoices(user) + active_character.SetJobPreferenceLevel(job, desiredLvl) + active_character.SetChoices(user) return 1 -/datum/preferences/proc/ShowDisabilityState(mob/user, flag, label) - return "
  • [label]: [disabilities & flag ? "Yes" : "No"]
  • " - -/datum/preferences/proc/SetDisabilities(mob/user) - var/datum/species/S = GLOB.all_species[species] - var/HTML = "" - HTML += "
    " - - if(CAN_WINGDINGS in S.species_traits) - HTML += ShowDisabilityState(user, DISABILITY_FLAG_WINGDINGS, "Speak in Wingdings") - HTML += ShowDisabilityState(user, DISABILITY_FLAG_NEARSIGHTED, "Nearsighted") - HTML += ShowDisabilityState(user, DISABILITY_FLAG_COLOURBLIND, "Colourblind") - HTML += ShowDisabilityState(user, DISABILITY_FLAG_BLIND, "Blind") - HTML += ShowDisabilityState(user, DISABILITY_FLAG_DEAF, "Deaf") - HTML += ShowDisabilityState(user, DISABILITY_FLAG_MUTE, "Mute") - if(!(TRAIT_NOFAT in S.inherent_traits)) - HTML += ShowDisabilityState(user, DISABILITY_FLAG_FAT, "Obese") - HTML += ShowDisabilityState(user, DISABILITY_FLAG_NERVOUS, "Stutter") - HTML += ShowDisabilityState(user, DISABILITY_FLAG_SWEDISH, "Swedish accent") - HTML += ShowDisabilityState(user, DISABILITY_FLAG_CHAV, "Chav accent") - HTML += ShowDisabilityState(user, DISABILITY_FLAG_LISP, "Lisp") - HTML += ShowDisabilityState(user, DISABILITY_FLAG_DIZZY, "Dizziness") - - - HTML += {" - \[Done\] - \[Reset\] -
    "} - - var/datum/browser/popup = new(user, "disabil", "
    Choose Disabilities
    ", 350, 380) - popup.set_content(HTML) - popup.open(0) - -/datum/preferences/proc/SetRecords(mob/user) - var/HTML = "" - HTML += "
    " - - HTML += "Medical Records
    " - - if(length(med_record) <= 40) - HTML += "[med_record]" - else - HTML += "[copytext(med_record, 1, 37)]..." - - HTML += "
    Employment Records
    " - - if(length(gen_record) <= 40) - HTML += "[gen_record]" - else - HTML += "[copytext(gen_record, 1, 37)]..." - - HTML += "
    Security Records
    " - - if(length(sec_record) <= 40) - HTML += "[sec_record]
    " - else - HTML += "[copytext(sec_record, 1, 37)]...
    " - - HTML += "\[Done\]" - HTML += "
    " - - 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 \ - ? player_alt_titles[job.title] \ - : job.title - -/datum/preferences/proc/SetPlayerAltTitle(datum/job/job, new_title) - // remove existing entry - if(player_alt_titles.Find(job.title)) - player_alt_titles -= job.title - // add one if it's not default - if(job.title != new_title) - player_alt_titles[job.title] = new_title - +// This is scoped here instead of /datum/character_save just because of ShowChoices() /datum/preferences/proc/SetJob(mob/user, role) var/datum/job/job = SSjobs.GetJob(role) if(!job) @@ -951,1387 +544,21 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts return if(role == "Civilian") - if(job_support_low & job.flag) - job_support_low &= ~job.flag + if(active_character.job_support_low & job.flag) + active_character.job_support_low &= ~job.flag else - job_support_low |= job.flag - SetChoices(user) + active_character.job_support_low |= job.flag + active_character.SetChoices(user) return 1 - if(GetJobDepartment(job, 1) & job.flag) - SetJobDepartment(job, 1) - else if(GetJobDepartment(job, 2) & job.flag) - SetJobDepartment(job, 2) - else if(GetJobDepartment(job, 3) & job.flag) - SetJobDepartment(job, 3) + if(active_character.GetJobDepartment(job, 1) & job.flag) + active_character.SetJobDepartment(job, 1) + else if(active_character.GetJobDepartment(job, 2) & job.flag) + active_character.SetJobDepartment(job, 2) + else if(active_character.GetJobDepartment(job, 3) & job.flag) + active_character.SetJobDepartment(job, 3) else//job = Never - SetJobDepartment(job, 4) + active_character.SetJobDepartment(job, 4) - SetChoices(user) + active_character.SetChoices(user) return 1 - -/datum/preferences/proc/ResetJobs() - job_support_high = 0 - job_support_med = 0 - job_support_low = 0 - - job_medsci_high = 0 - job_medsci_med = 0 - job_medsci_low = 0 - - job_engsec_high = 0 - job_engsec_med = 0 - job_engsec_low = 0 - - job_karma_high = 0 - job_karma_med = 0 - job_karma_low = 0 - - -/datum/preferences/proc/GetJobDepartment(datum/job/job, level) - if(!job || !level) return 0 - switch(job.department_flag) - if(JOBCAT_SUPPORT) - switch(level) - if(1) - return job_support_high - if(2) - return job_support_med - if(3) - return job_support_low - if(JOBCAT_MEDSCI) - switch(level) - if(1) - return job_medsci_high - if(2) - return job_medsci_med - if(3) - return job_medsci_low - if(JOBCAT_ENGSEC) - switch(level) - if(1) - return job_engsec_high - if(2) - return job_engsec_med - if(3) - return job_engsec_low - if(JOBCAT_KARMA) - switch(level) - if(1) - return job_karma_high - if(2) - return job_karma_med - if(3) - return job_karma_low - return 0 - -/datum/preferences/proc/SetJobDepartment(datum/job/job, level) - if(!job || !level) return 0 - switch(level) - if(1)//Only one of these should ever be active at once so clear them all here - job_support_high = 0 - job_medsci_high = 0 - job_engsec_high = 0 - job_karma_high = 0 - return 1 - if(2)//Set current highs to med, then reset them - job_support_med |= job_support_high - job_medsci_med |= job_medsci_high - job_engsec_med |= job_engsec_high - job_karma_med |= job_karma_high - job_support_high = 0 - job_medsci_high = 0 - job_engsec_high = 0 - job_karma_high = 0 - - switch(job.department_flag) - if(JOBCAT_SUPPORT) - switch(level) - if(2) - job_support_high = job.flag - job_support_med &= ~job.flag - if(3) - job_support_med |= job.flag - job_support_low &= ~job.flag - else - job_support_low |= job.flag - if(JOBCAT_MEDSCI) - switch(level) - if(2) - job_medsci_high = job.flag - job_medsci_med &= ~job.flag - if(3) - job_medsci_med |= job.flag - job_medsci_low &= ~job.flag - else - job_medsci_low |= job.flag - if(JOBCAT_ENGSEC) - switch(level) - if(2) - job_engsec_high = job.flag - job_engsec_med &= ~job.flag - if(3) - job_engsec_med |= job.flag - job_engsec_low &= ~job.flag - else - job_engsec_low |= job.flag - if(JOBCAT_KARMA) - switch(level) - if(2) - job_karma_high = job.flag - job_karma_med &= ~job.flag - if(3) - job_karma_med |= job.flag - job_karma_low &= ~job.flag - else - job_karma_low |= job.flag - return 1 - -/datum/preferences/proc/process_link(mob/user, list/href_list) - if(!user) return - - var/datum/species/S = GLOB.all_species[species] - if(href_list["preference"] == "job") - switch(href_list["task"]) - if("close") - user << browse(null, "window=mob_occupation") - ShowChoices(user) - if("reset") - ResetJobs() - SetChoices(user) - if("learnaboutselection") - if(GLOB.configuration.url.wiki_url) - if(alert("Would you like to open the Job selection info in your browser?", "Open Job Selection", "Yes", "No") == "Yes") - user << link("[GLOB.configuration.url.wiki_url]/index.php/Job_Selection_and_Assignment") - else - to_chat(user, "The Wiki URL is not set in the server configuration.") - if("random") - if(alternate_option == GET_RANDOM_JOB || alternate_option == BE_ASSISTANT) - alternate_option += 1 - else if(alternate_option == RETURN_TO_LOBBY) - alternate_option = 0 - else - return 0 - SetChoices(user) - if("alt_title") - var/datum/job/job = locate(href_list["job"]) - if(job) - var/choices = list(job.title) + job.alt_titles - var/choice = input("Pick a title for [job.title].", "Character Generation", GetPlayerAltTitle(job)) as anything in choices | null - if(choice) - SetPlayerAltTitle(job, choice) - SetChoices(user) - if("input") - SetJob(user, href_list["text"]) - if("setJobLevel") - UpdateJobPreference(user, href_list["text"], text2num(href_list["level"])) - else - SetChoices(user) - return 1 - else if(href_list["preference"] == "disabilities") - - switch(href_list["task"]) - if("close") - user << browse(null, "window=disabil") - ShowChoices(user) - if("reset") - disabilities=0 - SetDisabilities(user) - if("input") - var/dflag=text2num(href_list["disability"]) - if(dflag >= 0) // Toggle it. - disabilities ^= text2num(href_list["disability"]) //MAGIC - SetDisabilities(user) - else - SetDisabilities(user) - return 1 - - else if(href_list["preference"] == "records") - if(text2num(href_list["record"]) >= 1) - SetRecords(user) - return - else - user << browse(null, "window=records") - if(href_list["task"] == "med_record") - var/medmsg = input(usr,"Set your medical notes here.","Medical Records",html_decode(med_record)) as message - - if(medmsg != null) - medmsg = copytext(medmsg, 1, MAX_PAPER_MESSAGE_LEN) - medmsg = html_encode(medmsg) - - med_record = medmsg - SetRecords(user) - - if(href_list["task"] == "sec_record") - var/secmsg = input(usr,"Set your security notes here.","Security Records",html_decode(sec_record)) as message - - if(secmsg != null) - secmsg = copytext(secmsg, 1, MAX_PAPER_MESSAGE_LEN) - secmsg = html_encode(secmsg) - - sec_record = secmsg - SetRecords(user) - if(href_list["task"] == "gen_record") - var/genmsg = input(usr,"Set your employment notes here.","Employment Records",html_decode(gen_record)) as message - - if(genmsg != null) - genmsg = copytext(genmsg, 1, MAX_PAPER_MESSAGE_LEN) - genmsg = html_encode(genmsg) - - gen_record = genmsg - SetRecords(user) - - if(href_list["preference"] == "gear") - if(href_list["toggle_gear"]) - var/datum/gear/TG = GLOB.gear_datums[href_list["toggle_gear"]] - if(TG.display_name in loadout_gear) - loadout_gear -= TG.display_name - else - if(TG.donator_tier && user.client.donator_level < TG.donator_tier) - to_chat(user, "That gear is only available at a higher donation tier than you are on.") - return - var/total_cost = 0 - var/list/type_blacklist = list() - for(var/gear_name in loadout_gear) - var/datum/gear/G = GLOB.gear_datums[gear_name] - if(istype(G)) - if(!G.subtype_cost_overlap) - if(G.subtype_path in type_blacklist) - continue - type_blacklist += G.subtype_path - total_cost += G.cost - - if((total_cost + TG.cost) <= max_gear_slots) - loadout_gear += TG.display_name - - else if(href_list["gear"] && href_list["tweak"]) - var/datum/gear/gear = GLOB.gear_datums[href_list["gear"]] - var/datum/gear_tweak/tweak = locate(href_list["tweak"]) - if(!tweak || !istype(gear) || !(tweak in gear.gear_tweaks)) - return - var/metadata = tweak.get_metadata(user, get_tweak_metadata(gear, tweak)) - if(!metadata) - return - set_tweak_metadata(gear, tweak, metadata) - else if(href_list["select_category"]) - gear_tab = href_list["select_category"] - else if(href_list["clear_loadout"]) - loadout_gear.Cut() - - ShowChoices(user) - return - - switch(href_list["task"]) - if("random") - var/datum/robolimb/robohead - if(S.bodyflags & ALL_RPARTS) - var/head_model = "[!rlimb_data["head"] ? "Morpheus Cyberkinetics" : rlimb_data["head"]]" - robohead = GLOB.all_robolimbs[head_model] - switch(href_list["preference"]) - if("name") - real_name = random_name(gender,species) - if(isnewplayer(user)) - var/mob/new_player/N = user - N.new_player_panel_proc() - if("age") - age = rand(AGE_MIN, AGE_MAX) - if("hair") - if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Wryn", "Vulpkanin", "Vox")) - h_colour = rand_hex_color() - if("secondary_hair") - if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Wryn", "Vulpkanin", "Vox")) - h_sec_colour = rand_hex_color() - if("h_style") - h_style = random_hair_style(gender, species, robohead) - if("facial") - if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Wryn", "Vulpkanin", "Vox")) - f_colour = rand_hex_color() - if("secondary_facial") - if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Wryn", "Vulpkanin", "Vox")) - f_sec_colour = rand_hex_color() - if("f_style") - f_style = random_facial_hair_style(gender, species, robohead) - if("headaccessory") - if(S.bodyflags & HAS_HEAD_ACCESSORY) //Species that have head accessories. - hacc_colour = rand_hex_color() - if("ha_style") - if(S.bodyflags & HAS_HEAD_ACCESSORY) //Species that have head accessories. - ha_style = random_head_accessory(species) - if("m_style_head") - if(S.bodyflags & HAS_HEAD_MARKINGS) //Species with head markings. - m_styles["head"] = random_marking_style("head", species, robohead, null, alt_head) - if("m_head_colour") - if(S.bodyflags & HAS_HEAD_MARKINGS) //Species with head markings. - m_colours["head"] = rand_hex_color() - if("m_style_body") - if(S.bodyflags & HAS_BODY_MARKINGS) //Species with body markings. - m_styles["body"] = random_marking_style("body", species) - if("m_body_colour") - if(S.bodyflags & HAS_BODY_MARKINGS) //Species with body markings. - m_colours["body"] = rand_hex_color() - if("m_style_tail") - if(S.bodyflags & HAS_TAIL_MARKINGS) //Species with tail markings. - m_styles["tail"] = random_marking_style("tail", species, null, body_accessory) - if("m_tail_colour") - if(S.bodyflags & HAS_TAIL_MARKINGS) //Species with tail markings. - m_colours["tail"] = rand_hex_color() - if("underwear") - underwear = random_underwear(gender, species) - ShowChoices(user) - if("undershirt") - undershirt = random_undershirt(gender, species) - ShowChoices(user) - if("socks") - socks = random_socks(gender, species) - ShowChoices(user) - if("eyes") - e_colour = rand_hex_color() - if("s_tone") - if(S.bodyflags & (HAS_SKIN_TONE|HAS_ICON_SKIN_TONE)) - s_tone = random_skin_tone() - if("s_color") - if(S.bodyflags & HAS_SKIN_COLOR) - s_colour = rand_hex_color() - if("bag") - backbag = pick(GLOB.backbaglist) - /*if("skin_style") - h_style = random_skin_style(gender)*/ - if("all") - random_character() - if("input") - switch(href_list["preference"]) - if("name") - var/raw_name = clean_input("Choose your character's name:", "Character Preference", , user) - if(!isnull(raw_name)) // Check to ensure that the user entered text (rather than cancel.) - var/new_name = reject_bad_name(raw_name, 1) - if(new_name) - real_name = new_name - if(isnewplayer(user)) - var/mob/new_player/N = user - N.new_player_panel_proc() - else - to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .") - - if("age") - var/new_age = input(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX])", "Character Preference") as num|null - if(new_age) - age = max(min(round(text2num(new_age)), AGE_MAX),AGE_MIN) - if("species") - var/list/new_species = list("Human", "Tajaran", "Skrell", "Unathi", "Diona", "Vulpkanin") - var/prev_species = species - - for(var/species in GLOB.whitelisted_species) - if(is_alien_whitelisted(user, species)) - new_species += species - - species = input("Please select a species", "Character Generation", null) in sortTim(new_species, /proc/cmp_text_asc) - var/datum/species/NS = GLOB.all_species[species] - if(!istype(NS)) //The species was invalid. Notify the user and fail out. - species = prev_species - to_chat(user, "Invalid species, please pick something else.") - return - if(prev_species != species) - if(NS.has_gender && gender == PLURAL) - gender = pick(MALE,FEMALE) - var/datum/robolimb/robohead - if(NS.bodyflags & ALL_RPARTS) - var/head_model = "[!rlimb_data["head"] ? "Morpheus Cyberkinetics" : rlimb_data["head"]]" - robohead = GLOB.all_robolimbs[head_model] - //grab one of the valid hair styles for the newly chosen species - h_style = random_hair_style(gender, species, robohead) - - //grab one of the valid facial hair styles for the newly chosen species - f_style = random_facial_hair_style(gender, species, robohead) - - if(NS.bodyflags & HAS_HEAD_ACCESSORY) //Species that have head accessories. - ha_style = random_head_accessory(species) - else - ha_style = "None" // No Vulp ears on Unathi - hacc_colour = rand_hex_color() - - if(NS.bodyflags & HAS_HEAD_MARKINGS) //Species with head markings. - m_styles["head"] = random_marking_style("head", species, robohead, null, alt_head) - else - m_styles["head"] = "None" - m_colours["head"] = "#000000" - - if(NS.bodyflags & HAS_BODY_MARKINGS) //Species with body markings/tattoos. - m_styles["body"] = random_marking_style("body", species) - else - m_styles["body"] = "None" - m_colours["body"] = "#000000" - - if(NS.bodyflags & HAS_TAIL_MARKINGS) //Species with tail markings. - m_styles["tail"] = random_marking_style("tail", species, null, body_accessory) - else - m_styles["tail"] = "None" - m_colours["tail"] = "#000000" - - // Don't wear another species' underwear! - var/datum/sprite_accessory/SA = GLOB.underwear_list[underwear] - if(!SA || !(species in SA.species_allowed)) - underwear = random_underwear(gender, species) - - SA = GLOB.undershirt_list[undershirt] - if(!SA || !(species in SA.species_allowed)) - undershirt = random_undershirt(gender, species) - - SA = GLOB.socks_list[socks] - if(!SA || !(species in SA.species_allowed)) - socks = random_socks(gender, species) - - //reset skin tone and colour - if(NS.bodyflags & (HAS_SKIN_TONE|HAS_ICON_SKIN_TONE)) - random_skin_tone(species) - else - s_tone = 0 - - if(!(NS.bodyflags & HAS_SKIN_COLOR)) - s_colour = "#000000" - - alt_head = "None" //No alt heads on species that don't have them. - speciesprefs = 0 //My Vox tank shouldn't change how my future Grey talks. - - body_accessory = null //no vulptail on humans damnit - - //Reset prosthetics. - organ_data = list() - rlimb_data = list() - - if(!(NS.autohiss_basic_map)) - autohiss_mode = AUTOHISS_OFF - if("speciesprefs") - speciesprefs = !speciesprefs //Starts 0, so if someone clicks the button up top there, this won't be 0 anymore. If they click it again, it'll go back to 0. - if("language") -// var/languages_available - var/list/new_languages = list("None") - for(var/L in GLOB.all_languages) - var/datum/language/lang = GLOB.all_languages[L] - if(!(lang.flags & RESTRICTED)) - new_languages += lang.name - - language = input("Please select a secondary language", "Character Generation", null) in sortTim(new_languages, /proc/cmp_text_asc) - - if("autohiss_mode") - if(S.autohiss_basic_map) - var/list/autohiss_choice = list("Off" = AUTOHISS_OFF, "Basic" = AUTOHISS_BASIC, "Full" = AUTOHISS_FULL) - var/new_autohiss_pref = input(user, "Choose your character's auto-accent level:", "Character Preference") as null|anything in autohiss_choice - if(new_autohiss_pref) - autohiss_mode = autohiss_choice[new_autohiss_pref] - - if("metadata") - var/new_metadata = input(user, "Enter any information you'd like others to see, such as Roleplay-preferences:", "Game Preference" , metadata) as message|null - if(new_metadata) - metadata = sanitize(copytext(new_metadata,1,MAX_MESSAGE_LEN)) - - if("b_type") - var/new_b_type = input(user, "Choose your character's blood-type:", "Character Preference") as null|anything in list( "A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-" ) - if(new_b_type) - b_type = new_b_type - - if("hair") - if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox")) //Species that have hair. (No HAS_HAIR flag) - var/input = "Choose your character's hair colour:" - var/new_hair = input(user, input, "Character Preference", h_colour) as color|null - if(new_hair) - h_colour = new_hair - - if("secondary_hair") - if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox")) - var/datum/sprite_accessory/hair_style = GLOB.hair_styles_public_list[h_style] - if(hair_style.secondary_theme && !hair_style.no_sec_colour) - var/new_hair = input(user, "Choose your character's secondary hair colour:", "Character Preference", h_sec_colour) as color|null - if(new_hair) - h_sec_colour = new_hair - - if("h_style") - var/list/valid_hairstyles = list() - for(var/hairstyle in GLOB.hair_styles_public_list) - var/datum/sprite_accessory/SA = GLOB.hair_styles_public_list[hairstyle] - - if(hairstyle == "Bald") //Just in case. - valid_hairstyles += hairstyle - continue - if(S.bodyflags & ALL_RPARTS) //Species that can use prosthetic heads. - var/head_model - if(!rlimb_data["head"]) //Handle situations where the head is default. - head_model = "Morpheus Cyberkinetics" - else - head_model = rlimb_data["head"] - var/datum/robolimb/robohead = GLOB.all_robolimbs[head_model] - 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 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 SA.species_allowed) //If the user's head is of a species the hairstyle allows, add it to the list. - valid_hairstyles += hairstyle - - sortTim(valid_hairstyles, /proc/cmp_text_asc) //this alphabetizes the list - var/new_h_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in valid_hairstyles - if(new_h_style) - h_style = new_h_style - - if("headaccessory") - if(S.bodyflags & HAS_HEAD_ACCESSORY) //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", hacc_colour) as color|null - if(new_head_accessory) - hacc_colour = new_head_accessory - - if("ha_style") - if(S.bodyflags & HAS_HEAD_ACCESSORY) //Species with head accessories. - var/list/valid_head_accessory_styles = list() - for(var/head_accessory_style in GLOB.head_accessory_styles_list) - var/datum/sprite_accessory/H = GLOB.head_accessory_styles_list[head_accessory_style] - if(!(species in H.species_allowed)) - continue - - valid_head_accessory_styles += head_accessory_style - - sortTim(valid_head_accessory_styles, /proc/cmp_text_asc) - var/new_head_accessory_style = input(user, "Choose the style of your character's head accessory:", "Character Preference") as null|anything in valid_head_accessory_styles - if(new_head_accessory_style) - ha_style = new_head_accessory_style - - if("alt_head") - if(organ_data["head"] == "cyborg") - return - if(S.bodyflags & HAS_ALT_HEADS) //Species with alt heads. - var/list/valid_alt_heads = list() - valid_alt_heads["None"] = GLOB.alt_heads_list["None"] //The only null entry should be the "None" option - for(var/alternate_head in GLOB.alt_heads_list) - var/datum/sprite_accessory/alt_heads/head = GLOB.alt_heads_list[alternate_head] - if(!(species in head.species_allowed)) - continue - - valid_alt_heads += alternate_head - - var/new_alt_head = input(user, "Choose your character's alternate head style:", "Character Preference") as null|anything in valid_alt_heads - if(new_alt_head) - alt_head = new_alt_head - if(m_styles["head"]) - var/head_marking = m_styles["head"] - var/datum/sprite_accessory/body_markings/head/head_marking_style = GLOB.marking_styles_list[head_marking] - if(!head_marking_style.heads_allowed || (!("All" in head_marking_style.heads_allowed) && !(alt_head in head_marking_style.heads_allowed))) - m_styles["head"] = "None" - - if("m_style_head") - if(S.bodyflags & HAS_HEAD_MARKINGS) //Species with head markings. - var/list/valid_markings = list() - valid_markings["None"] = GLOB.marking_styles_list["None"] - for(var/markingstyle in GLOB.marking_styles_list) - var/datum/sprite_accessory/body_markings/head/M = GLOB.marking_styles_list[markingstyle] - if(!(species in M.species_allowed)) - continue - if(M.marking_location != "head") - continue - if(alt_head && alt_head != "None") - if(!("All" in M.heads_allowed) && !(alt_head in M.heads_allowed)) - continue - else - if(M.heads_allowed && !("All" in M.heads_allowed)) - continue - - if(S.bodyflags & ALL_RPARTS) //Species that can use prosthetic heads. - var/head_model - if(!rlimb_data["head"]) //Handle situations where the head is default. - head_model = "Morpheus Cyberkinetics" - else - head_model = rlimb_data["head"] - var/datum/robolimb/robohead = GLOB.all_robolimbs[head_model] - if(robohead.is_monitor && M.name != "None") //If the character can have prosthetic heads and they have the default Morpheus head (or another monitor-head), no optic markings. - continue - else if(!robohead.is_monitor && M.name != "None") //Otherwise, if they DON'T have the default head and the head's not a monitor but the head's not in the style's list of allowed models, skip. - if(!(robohead.company in M.models_allowed)) - continue - - valid_markings += markingstyle - sortTim(valid_markings, /proc/cmp_text_asc) - var/new_marking_style = input(user, "Choose the style of your character's head markings:", "Character Preference", m_styles["head"]) as null|anything in valid_markings - if(new_marking_style) - m_styles["head"] = new_marking_style - - if("m_head_colour") - if(S.bodyflags & HAS_HEAD_MARKINGS) //Species with head markings. - var/input = "Choose the colour of your your character's head markings:" - var/new_markings = input(user, input, "Character Preference", m_colours["head"]) as color|null - if(new_markings) - m_colours["head"] = new_markings - - if("m_style_body") - if(S.bodyflags & HAS_BODY_MARKINGS) //Species with body markings/tattoos. - var/list/valid_markings = list() - valid_markings["None"] = GLOB.marking_styles_list["None"] - for(var/markingstyle in GLOB.marking_styles_list) - var/datum/sprite_accessory/M = GLOB.marking_styles_list[markingstyle] - if(!(species in M.species_allowed)) - continue - if(M.marking_location != "body") - continue - - valid_markings += markingstyle - sortTim(valid_markings, /proc/cmp_text_asc) - var/new_marking_style = input(user, "Choose the style of your character's body markings:", "Character Preference", m_styles["body"]) as null|anything in valid_markings - if(new_marking_style) - m_styles["body"] = new_marking_style - - if("m_body_colour") - if(S.bodyflags & HAS_BODY_MARKINGS) //Species with body markings/tattoos. - var/input = "Choose the colour of your your character's body markings:" - var/new_markings = input(user, input, "Character Preference", m_colours["body"]) as color|null - if(new_markings) - m_colours["body"] = new_markings - - if("m_style_tail") - if(S.bodyflags & HAS_TAIL_MARKINGS) //Species with tail markings. - var/list/valid_markings = list() - valid_markings["None"] = GLOB.marking_styles_list["None"] - for(var/markingstyle in GLOB.marking_styles_list) - var/datum/sprite_accessory/body_markings/tail/M = GLOB.marking_styles_list[markingstyle] - if(M.marking_location != "tail") - continue - if(!(species in M.species_allowed)) - continue - if(!body_accessory) - if(M.tails_allowed) - continue - else - if(!M.tails_allowed || !(body_accessory in M.tails_allowed)) - continue - - valid_markings += markingstyle - sortTim(valid_markings, /proc/cmp_text_asc) - var/new_marking_style = input(user, "Choose the style of your character's tail markings:", "Character Preference", m_styles["tail"]) as null|anything in valid_markings - if(new_marking_style) - m_styles["tail"] = new_marking_style - - if("m_tail_colour") - if(S.bodyflags & HAS_TAIL_MARKINGS) //Species with tail markings. - var/input = "Choose the colour of your your character's tail markings:" - var/new_markings = input(user, input, "Character Preference", m_colours["tail"]) as color|null - if(new_markings) - m_colours["tail"] = new_markings - - if("body_accessory") - var/list/possible_body_accessories = list() - if(check_rights(R_ADMIN, 1, user)) - possible_body_accessories = GLOB.body_accessory_by_name.Copy() - else - for(var/B in GLOB.body_accessory_by_name) - var/datum/body_accessory/accessory = GLOB.body_accessory_by_name[B] - if(!istype(accessory)) - possible_body_accessories += "None" //the only null entry should be the "None" option - continue - if(species in accessory.allowed_species) - possible_body_accessories += B - sortTim(possible_body_accessories, /proc/cmp_text_asc) - var/new_body_accessory = input(user, "Choose your body accessory:", "Character Preference") as null|anything in possible_body_accessories - if(new_body_accessory) - m_styles["tail"] = "None" - body_accessory = (new_body_accessory == "None") ? null : new_body_accessory - - if("facial") - if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox")) //Species that have facial hair. (No HAS_HAIR_FACIAL flag) - var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference", f_colour) as color|null - if(new_facial) - f_colour = new_facial - - if("secondary_facial") - if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox")) - var/datum/sprite_accessory/facial_hair_style = GLOB.facial_hair_styles_list[f_style] - if(facial_hair_style.secondary_theme && !facial_hair_style.no_sec_colour) - var/new_facial = input(user, "Choose your character's secondary facial-hair colour:", "Character Preference", f_sec_colour) as color|null - if(new_facial) - f_sec_colour = new_facial - - if("f_style") - var/list/valid_facial_hairstyles = list() - for(var/facialhairstyle in GLOB.facial_hair_styles_list) - var/datum/sprite_accessory/SA = GLOB.facial_hair_styles_list[facialhairstyle] - - if(facialhairstyle == "Shaved") //Just in case. - valid_facial_hairstyles += facialhairstyle - continue - if(gender == MALE && SA.gender == FEMALE) - continue - if(gender == FEMALE && SA.gender == MALE) - continue - if(S.bodyflags & ALL_RPARTS) //Species that can use prosthetic heads. - var/head_model - if(!rlimb_data["head"]) //Handle situations where the head is default. - head_model = "Morpheus Cyberkinetics" - else - head_model = rlimb_data["head"] - var/datum/robolimb/robohead = GLOB.all_robolimbs[head_model] - 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 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 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 - sortTim(valid_facial_hairstyles, /proc/cmp_text_asc) - var/new_f_style = input(user, "Choose your character's facial-hair style:", "Character Preference") as null|anything in valid_facial_hairstyles - if(new_f_style) - f_style = new_f_style - - if("underwear") - var/list/valid_underwear = list() - for(var/underwear in GLOB.underwear_list) - var/datum/sprite_accessory/SA = GLOB.underwear_list[underwear] - if(gender == MALE && SA.gender == FEMALE) - continue - if(gender == FEMALE && SA.gender == MALE) - continue - if(!(species in SA.species_allowed)) - continue - valid_underwear[underwear] = GLOB.underwear_list[underwear] - sortTim(valid_underwear, /proc/cmp_text_asc) - var/new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in valid_underwear - ShowChoices(user) - if(new_underwear) - underwear = new_underwear - if("undershirt") - var/list/valid_undershirts = list() - for(var/undershirt in GLOB.undershirt_list) - var/datum/sprite_accessory/SA = GLOB.undershirt_list[undershirt] - if(gender == MALE && SA.gender == FEMALE) - continue - if(gender == FEMALE && SA.gender == MALE) - continue - if(!(species in SA.species_allowed)) - continue - valid_undershirts[undershirt] = GLOB.undershirt_list[undershirt] - sortTim(valid_undershirts, /proc/cmp_text_asc) - var/new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in valid_undershirts - ShowChoices(user) - if(new_undershirt) - undershirt = new_undershirt - - if("socks") - var/list/valid_sockstyles = list() - for(var/sockstyle in GLOB.socks_list) - var/datum/sprite_accessory/SA = GLOB.socks_list[sockstyle] - if(gender == MALE && SA.gender == FEMALE) - continue - if(gender == FEMALE && SA.gender == MALE) - continue - if(!(species in SA.species_allowed)) - continue - valid_sockstyles[sockstyle] = GLOB.socks_list[sockstyle] - sortTim(valid_sockstyles, /proc/cmp_text_asc) - var/new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in valid_sockstyles - ShowChoices(user) - if(new_socks) - socks = new_socks - - if("eyes") - var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference", e_colour) as color|null - if(new_eyes) - e_colour = new_eyes - - if("s_tone") - if(S.bodyflags & HAS_SKIN_TONE) - var/new_s_tone = input(user, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Character Preference") as num|null - if(new_s_tone) - s_tone = 35 - max(min(round(new_s_tone), 220), 1) - else if(S.bodyflags & HAS_ICON_SKIN_TONE) - var/const/MAX_LINE_ENTRIES = 4 - var/prompt = "Choose your character's skin tone: 1-[S.icon_skin_tones.len]\n(" - for(var/i = 1 to S.icon_skin_tones.len) - if(i > MAX_LINE_ENTRIES && !((i - 1) % MAX_LINE_ENTRIES)) - prompt += "\n" - prompt += "[i] = [S.icon_skin_tones[i]]" - if(i != S.icon_skin_tones.len) - prompt += ", " - prompt += ")" - var/skin_c = input(user, prompt, "Character Preference") as num|null - if(isnum(skin_c)) - s_tone = max(min(round(skin_c), S.icon_skin_tones.len), 1) - - if("skin") - if((S.bodyflags & HAS_SKIN_COLOR) || GLOB.body_accessory_by_species[species] || check_rights(R_ADMIN, 0, user)) - var/new_skin = input(user, "Choose your character's skin colour: ", "Character Preference", s_colour) as color|null - if(new_skin) - s_colour = new_skin - - if("ooccolor") - var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference", ooccolor) as color|null - if(new_ooccolor) - ooccolor = new_ooccolor - - if("bag") - var/new_backbag = input(user, "Choose your character's style of bag:", "Character Preference") as null|anything in GLOB.backbaglist - if(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") - if(new_relation) - nanotrasen_relation = new_relation - - if("flavor_text") - var/msg = input(usr,"Set the flavor text in your 'examine' verb. The flavor text should be a physical descriptor of your character at a glance. SFW Drawn Art of your character is acceptable.","Flavor Text",html_decode(flavor_text)) as message - - if(msg != null) - msg = copytext(msg, 1, MAX_MESSAGE_LEN) - msg = html_encode(msg) - - flavor_text = msg - - if("limbs") - var/valid_limbs = list("Left Leg", "Right Leg", "Left Arm", "Right Arm", "Left Foot", "Right Foot", "Left Hand", "Right Hand") - if(S.bodyflags & ALL_RPARTS) - valid_limbs = list("Torso", "Lower Body", "Head", "Left Leg", "Right Leg", "Left Arm", "Right Arm", "Left Foot", "Right Foot", "Left Hand", "Right Hand") - var/limb_name = input(user, "Which limb do you want to change?") as null|anything in valid_limbs - if(!limb_name) return - - var/limb = null - var/second_limb = null // if you try to change the arm, the hand should also change - var/third_limb = null // if you try to unchange the hand, the arm should also change - var/valid_limb_states = list("Normal", "Amputated", "Prosthesis") - var/no_amputate = 0 - - switch(limb_name) - if("Torso") - limb = "chest" - second_limb = "groin" - no_amputate = 1 - if("Lower Body") - limb = "groin" - no_amputate = 1 - if("Head") - limb = "head" - no_amputate = 1 - if("Left Leg") - limb = "l_leg" - second_limb = "l_foot" - if("Right Leg") - limb = "r_leg" - second_limb = "r_foot" - if("Left Arm") - limb = "l_arm" - second_limb = "l_hand" - if("Right Arm") - limb = "r_arm" - second_limb = "r_hand" - if("Left Foot") - limb = "l_foot" - if(!(S.bodyflags & ALL_RPARTS)) - third_limb = "l_leg" - if("Right Foot") - limb = "r_foot" - if(!(S.bodyflags & ALL_RPARTS)) - third_limb = "r_leg" - if("Left Hand") - limb = "l_hand" - if(!(S.bodyflags & ALL_RPARTS)) - third_limb = "l_arm" - if("Right Hand") - limb = "r_hand" - if(!(S.bodyflags & ALL_RPARTS)) - third_limb = "r_arm" - - var/new_state = input(user, "What state do you wish the limb to be in?") as null|anything in valid_limb_states - if(!new_state) return - - switch(new_state) - if("Normal") - if(limb == "head") - m_styles["head"] = "None" - h_style = GLOB.hair_styles_public_list["Bald"] - f_style = GLOB.facial_hair_styles_list["Shaved"] - organ_data[limb] = null - rlimb_data[limb] = null - if(third_limb) - organ_data[third_limb] = null - rlimb_data[third_limb] = null - if("Amputated") - if(!no_amputate) - organ_data[limb] = "amputated" - rlimb_data[limb] = null - if(second_limb) - organ_data[second_limb] = "amputated" - rlimb_data[second_limb] = null - if("Prosthesis") - var/choice - var/subchoice - var/datum/robolimb/R = new() - var/in_model - var/robolimb_companies = list() - for(var/limb_type in typesof(/datum/robolimb)) //This loop populates a list of companies that offer the limb the user selected previously as one of their cybernetic products. - R = new limb_type() - if(!R.unavailable_at_chargen && (limb in R.parts) && R.has_subtypes) //Ensures users can only choose companies that offer the parts they want, that singular models get added to the list as well companies that offer more than one model, and... - robolimb_companies[R.company] = R //List only main brands that have the parts we're looking for. - R = new() //Re-initialize R. - - choice = input(user, "Which manufacturer do you wish to use for this limb?") as null|anything in robolimb_companies //Choose from a list of companies that offer the part the user wants. - if(!choice) - return - R.company = choice - R = GLOB.all_robolimbs[R.company] - if(R.has_subtypes == 1) //If the company the user selected provides more than just one base model, lets handle it. - var/list/robolimb_models = list() - for(var/limb_type in typesof(R)) //Handling the different models of parts that manufacturers can provide. - var/datum/robolimb/L = new limb_type() - if(limb in L.parts) //Make sure that only models that provide the parts the user needs populate the list. - robolimb_models[L.company] = L - if(robolimb_models.len == 1) //If there's only one model available in the list, autoselect it to avoid having to bother the user with a dialog that provides only one option. - subchoice = L.company //If there ends up being more than one model populating the list, subchoice will be overwritten later anyway, so this isn't a problem. - if(second_limb in L.parts) //If the child limb of the limb the user selected is also present in the model's parts list, state it's been found so the second limb can be set later. - in_model = 1 - if(robolimb_models.len > 1) //If there's more than one model in the list that can provide the part the user wants, let them choose. - subchoice = input(user, "Which model of [choice] [limb_name] do you wish to use?") as null|anything in robolimb_models - if(subchoice) - choice = subchoice - if(limb in list("head", "chest", "groin")) - if(!(S.bodyflags & ALL_RPARTS)) - return - if(limb == "head") - ha_style = "None" - alt_head = null - h_style = GLOB.hair_styles_public_list["Bald"] - f_style = GLOB.facial_hair_styles_list["Shaved"] - m_styles["head"] = "None" - rlimb_data[limb] = choice - organ_data[limb] = "cyborg" - if(second_limb) - if(subchoice) - if(in_model) - rlimb_data[second_limb] = choice - organ_data[second_limb] = "cyborg" - else - rlimb_data[second_limb] = choice - organ_data[second_limb] = "cyborg" - if("organs") - var/organ_name = input(user, "Which internal function do you want to change?") as null|anything in list("Eyes", "Ears", "Heart", "Lungs", "Liver", "Kidneys") - if(!organ_name) - return - - var/organ = null - switch(organ_name) - if("Eyes") - organ = "eyes" - if("Ears") - organ = "ears" - if("Heart") - organ = "heart" - if("Lungs") - organ = "lungs" - if("Liver") - organ = "liver" - if("Kidneys") - organ = "kidneys" - - var/new_state = input(user, "What state do you wish the organ to be in?") as null|anything in list("Normal", "Cybernetic") - if(!new_state) return - - switch(new_state) - if("Normal") - organ_data[organ] = null - if("Cybernetic") - organ_data[organ] = "cybernetic" - - if("clientfps") - var/version_message - if(user.client && user.client.byond_version < 511) - version_message = "\nYou need to be using byond version 511 or later to take advantage of this feature, your version of [user.client.byond_version] is too low" - if(world.byond_version < 511) - version_message += "\nThis server does not currently support client side fps. You can set now for when it does." - var/desiredfps = input(user, "Choose your desired fps.[version_message]\n(0 = synced with server tick rate (currently:[world.fps]))", "Character Preference", clientfps) as null|num - if(!isnull(desiredfps)) - clientfps = desiredfps - if(world.byond_version >= 511 && user.client && user.client.byond_version >= 511) - parent.fps = clientfps - - else - switch(href_list["preference"]) - if("publicity") - if(unlock_content) - toggles ^= PREFTOGGLE_MEMBER_PUBLIC - - if("donor_public") - if(user.client.donator_level > 0) - toggles ^= PREFTOGGLE_DONATOR_PUBLIC - - if("gender") - 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 - if(gender == MALE) - gender = FEMALE - else - gender = MALE - underwear = random_underwear(gender) - - if("hear_adminhelps") - sound ^= SOUND_ADMINHELP - if("ui") - switch(UI_style) - if("Midnight") - UI_style = "Plasmafire" - if("Plasmafire") - UI_style = "Retro" - if("Retro") - UI_style = "Slimecore" - if("Slimecore") - UI_style = "Operative" - if("Operative") - UI_style = "White" - else - UI_style = "Midnight" - - if(ishuman(usr)) //mid-round preference changes, for aesthetics - var/mob/living/carbon/human/H = usr - H.remake_hud() - - if("tgui") - toggles2 ^= PREFTOGGLE_2_FANCYUI - - if("ghost_att_anim") - toggles2 ^= PREFTOGGLE_2_ITEMATTACK - - if("winflash") - toggles2 ^= PREFTOGGLE_2_WINDOWFLASHING - - if("afk_watch") - if(!(toggles2 & PREFTOGGLE_2_AFKWATCH)) - to_chat(user, "You will now get put into cryo dorms after [GLOB.configuration.afk.auto_cryo_minutes] minutes. \ - Then after [GLOB.configuration.afk.auto_despawn_minutes] minutes you will be fully despawned. You will receive a visual and auditory warning before you will be put into cryodorms.") - else - to_chat(user, "Automatic cryoing turned off.") - toggles2 ^= PREFTOGGLE_2_AFKWATCH - - if("UIcolor") - var/UI_style_color_new = input(user, "Choose your UI color, dark colors are not recommended!", UI_style_color) as color|null - if(!UI_style_color_new) return - UI_style_color = UI_style_color_new - - if(ishuman(usr)) //mid-round preference changes, for aesthetics - var/mob/living/carbon/human/H = usr - H.remake_hud() - - if("UIalpha") - var/UI_style_alpha_new = input(user, "Select a new alpha(transparence) parameter for UI, between 50 and 255", UI_style_alpha) as num - if(!UI_style_alpha_new || !(UI_style_alpha_new <= 255 && UI_style_alpha_new >= 50)) - return - UI_style_alpha = UI_style_alpha_new - - if(ishuman(usr)) //mid-round preference changes, for aesthetics - var/mob/living/carbon/human/H = usr - H.remake_hud() - - if("be_special") - var/r = href_list["role"] - if(r in GLOB.special_roles) - be_special ^= r - - if("name") - be_random_name = !be_random_name - - if("randomslot") - toggles2 ^= PREFTOGGLE_2_RANDOMSLOT - if(isnewplayer(usr)) - var/mob/new_player/N = usr - N.new_player_panel_proc() - - if("hear_midis") - sound ^= SOUND_MIDI - - if("lobby_music") - sound ^= SOUND_LOBBY - if((sound & SOUND_LOBBY) && user.client) - user.client.playtitlemusic() - else - user.stop_sound_channel(CHANNEL_LOBBYMUSIC) - - if("ghost_ears") - toggles ^= PREFTOGGLE_CHAT_GHOSTEARS - - if("ghost_sight") - toggles ^= PREFTOGGLE_CHAT_GHOSTSIGHT - - if("ghost_radio") - toggles ^= PREFTOGGLE_CHAT_GHOSTRADIO - - if("ghost_pda") - toggles ^= PREFTOGGLE_CHAT_GHOSTPDA - - if("ghost_anonsay") - toggles2 ^= PREFTOGGLE_2_ANONDCHAT - - if("save") - save_preferences(user) - save_character(user) - - if("reload") - load_preferences(user) - load_character(user) - - if("clear") - if(!saved || real_name != input("This will clear the current slot permanently. Please enter the character's full name to confirm.")) - return FALSE - clear_character_slot(user) - - if("open_load_dialog") - if(!IsGuestKey(user.key)) - open_load_dialog(user) - return 1 - - if("close_load_dialog") - close_load_dialog(user) - - if("changeslot") - if(!load_character(user,text2num(href_list["num"]))) - random_character() - real_name = random_name(gender) - save_character(user) - close_load_dialog(user) - if(isnewplayer(user)) - var/mob/new_player/N = user - N.new_player_panel_proc() - - if("tab") - if(href_list["tab"]) - current_tab = text2num(href_list["tab"]) - - - if("ambientocclusion") - toggles ^= PREFTOGGLE_AMBIENT_OCCLUSION - if(length(parent?.screen)) - var/obj/screen/plane_master/game_world/PM = locate(/obj/screen/plane_master/game_world) in parent.screen - PM.backdrop(parent.mob) - - if("parallax") - var/parallax_styles = list( - "Off" = PARALLAX_DISABLE, - "Low" = PARALLAX_LOW, - "Medium" = PARALLAX_MED, - "High" = PARALLAX_HIGH, - "Insane" = PARALLAX_INSANE - ) - parallax = parallax_styles[input(user, "Pick a parallax style", "Parallax Style") as null|anything in parallax_styles] - if(parent && parent.mob && parent.mob.hud_used) - parent.mob.hud_used.update_parallax_pref() - - if("edit_2fa") - // Do this async so we arent holding up a topic() call - INVOKE_ASYNC(user.client, /client.proc/edit_2fa) - return // We return here to avoid focus being lost - - - ShowChoices(user) - return 1 - -/datum/preferences/proc/copy_to(mob/living/carbon/human/character) - var/datum/species/S = GLOB.all_species[species] - character.set_species(S.type) // Yell at me if this causes everything to melt - if(be_random_name) - real_name = random_name(gender,species) - - character.add_language(language) - - - character.real_name = real_name - character.dna.real_name = real_name - character.name = character.real_name - - character.flavor_text = flavor_text - character.med_record = med_record - character.sec_record = sec_record - character.gen_record = gen_record - - character.change_gender(gender) - character.age = age - - //Head-specific - var/obj/item/organ/external/head/H = character.get_organ("head") - - H.hair_colour = h_colour - - H.sec_hair_colour = h_sec_colour - - H.facial_colour = f_colour - - H.sec_facial_colour = f_sec_colour - - H.h_style = h_style - H.f_style = f_style - - H.alt_head = alt_head - //End of head-specific. - - character.skin_colour = s_colour - - character.s_tone = s_tone - - // Destroy/cyborgize organs - for(var/name in organ_data) - - var/status = organ_data[name] - var/obj/item/organ/external/O = character.bodyparts_by_name[name] - if(O) - if(status == "amputated") - qdel(O.remove(character)) - - else if(status == "cyborg") - if(rlimb_data[name]) - O.robotize(rlimb_data[name], convert_all = 0) - else - O.robotize() - else - var/obj/item/organ/internal/I = character.get_int_organ_tag(name) - if(I) - if(status == "cybernetic") - I.robotize() - - character.dna.blood_type = b_type - - // Wheelchair necessary? - var/obj/item/organ/external/l_foot = character.get_organ("l_foot") - var/obj/item/organ/external/r_foot = character.get_organ("r_foot") - if(!l_foot && !r_foot) - var/obj/structure/chair/wheelchair/W = new /obj/structure/chair/wheelchair(character.loc) - W.buckle_mob(character, TRUE) - - character.underwear = underwear - character.undershirt = undershirt - character.socks = socks - - if(character.dna.species.bodyflags & HAS_HEAD_ACCESSORY) - H.headacc_colour = hacc_colour - H.ha_style = ha_style - if(character.dna.species.bodyflags & HAS_MARKINGS) - character.m_colours = m_colours - character.m_styles = m_styles - - if(body_accessory) - character.body_accessory = GLOB.body_accessory_by_name["[body_accessory]"] - - character.backbag = backbag - - //Debugging report to track down a bug, which randomly assigned the plural gender to people. - if(character.dna.species.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) - - character.change_eye_color(e_colour) - character.original_eye_color = e_colour - - if(disabilities & DISABILITY_FLAG_FAT) - character.dna.SetSEState(GLOB.fatblock, TRUE, TRUE) - character.overeatduration = 600 - character.dna.default_blocks.Add(GLOB.fatblock) - - if(disabilities & DISABILITY_FLAG_NEARSIGHTED) - character.dna.SetSEState(GLOB.glassesblock, TRUE, TRUE) - character.dna.default_blocks.Add(GLOB.glassesblock) - - if(disabilities & DISABILITY_FLAG_BLIND) - character.dna.SetSEState(GLOB.blindblock, TRUE, TRUE) - character.dna.default_blocks.Add(GLOB.blindblock) - - if(disabilities & DISABILITY_FLAG_DEAF) - character.dna.SetSEState(GLOB.deafblock, TRUE, TRUE) - character.dna.default_blocks.Add(GLOB.deafblock) - - if(disabilities & DISABILITY_FLAG_COLOURBLIND) - character.dna.SetSEState(GLOB.colourblindblock, TRUE, TRUE) - character.dna.default_blocks.Add(GLOB.colourblindblock) - - if(disabilities & DISABILITY_FLAG_MUTE) - character.dna.SetSEState(GLOB.muteblock, TRUE, TRUE) - character.dna.default_blocks.Add(GLOB.muteblock) - - if(disabilities & DISABILITY_FLAG_NERVOUS) - character.dna.SetSEState(GLOB.nervousblock, TRUE, TRUE) - character.dna.default_blocks.Add(GLOB.nervousblock) - - if(disabilities & DISABILITY_FLAG_SWEDISH) - character.dna.SetSEState(GLOB.swedeblock, TRUE, TRUE) - character.dna.default_blocks.Add(GLOB.swedeblock) - - if(disabilities & DISABILITY_FLAG_CHAV) - character.dna.SetSEState(GLOB.chavblock, TRUE, TRUE) - character.dna.default_blocks.Add(GLOB.chavblock) - - if(disabilities & DISABILITY_FLAG_LISP) - character.dna.SetSEState(GLOB.lispblock, TRUE, TRUE) - character.dna.default_blocks.Add(GLOB.lispblock) - - if(disabilities & DISABILITY_FLAG_DIZZY) - character.dna.SetSEState(GLOB.dizzyblock, TRUE, TRUE) - character.dna.default_blocks.Add(GLOB.dizzyblock) - - if(disabilities & DISABILITY_FLAG_WINGDINGS && (CAN_WINGDINGS in character.dna.species.species_traits)) - character.dna.SetSEState(GLOB.wingdingsblock, TRUE, TRUE) - character.dna.default_blocks.Add(GLOB.wingdingsblock) - - character.dna.species.handle_dna(character) - - if(character.dna.dirtySE) - character.dna.UpdateSE() - domutcheck(character, MUTCHK_FORCED) //'Activates' all the above disabilities. - - character.dna.ready_dna(character, flatten_SE = 0) - character.sync_organ_dna(assimilate=1) - character.UpdateAppearance() - - // Do the initial caching of the player's body icons. - character.force_update_limbs() - character.update_eyes() - character.regenerate_icons() - -/datum/preferences/proc/open_load_dialog(mob/user) - - var/datum/db_query/query = SSdbcore.NewQuery("SELECT slot, real_name FROM characters WHERE ckey=:ckey ORDER BY slot", list( - "ckey" = user.ckey - )) - var/list/slotnames[max_save_slots] - - if(!query.warn_execute()) - qdel(query) - return - - while(query.NextRow()) - slotnames[text2num(query.item[1])] = query.item[2] - qdel(query) - - var/dat = "" - dat += "
    " - dat += "Select a character slot to load
    " - var/name - - for(var/i in 1 to max_save_slots) - name = slotnames[i] || "Character [i]" - if(i == default_slot) - name = "[name]" - dat += "[name]
    " - - dat += "
    " - dat += "Close
    " - dat += "
    " -// user << browse(dat, "window=saves;size=300x390") - var/datum/browser/popup = new(user, "saves", "
    Character Saves
    ", 300, 390) - popup.set_content(dat) - popup.open(0) - -/datum/preferences/proc/close_load_dialog(mob/user) - user << browse(null, "window=saves") - -//Check if the user has ANY job selected. -/datum/preferences/proc/check_any_job() - return(job_support_high || job_support_med || job_support_low || job_medsci_high || job_medsci_med || job_medsci_low || job_engsec_high || job_engsec_med || job_engsec_low || job_karma_high || job_karma_med || job_karma_low) diff --git a/code/modules/client/preference/preferences_mysql.dm b/code/modules/client/preference/preferences_mysql.dm index 0f589cabaf3..8d8b16ead1e 100644 --- a/code/modules/client/preference/preferences_mysql.dm +++ b/code/modules/client/preference/preferences_mysql.dm @@ -1,32 +1,6 @@ -/datum/preferences/proc/load_preferences(client/C) - - var/datum/db_query/query = SSdbcore.NewQuery({"SELECT - ooccolor, - UI_style, - UI_style_color, - UI_style_alpha, - be_role, - default_slot, - toggles, - toggles_2, - sound, - volume_mixer, - lastchangelog, - exp, - clientfps, - atklog, - fuid, - parallax, - 2fa_status - FROM player - WHERE ckey=:ckey"}, list( - "ckey" = C.ckey - )) - - if(!query.warn_execute()) - qdel(query) - return - +/datum/preferences/proc/load_preferences(datum/db_query/query) + // Looking for the query? + // Check ../login_processing/10-load_preferences.dm //general preferences while(query.NextRow()) @@ -48,8 +22,6 @@ parallax = text2num(query.item[16]) _2fa_status = query.item[17] - qdel(query) - //Sanitize ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor)) UI_style = sanitize_inlist(UI_style, list("White", "Midnight", "Plasmafire", "Retro", "Slimecore", "Operative"), initial(UI_style)) @@ -65,7 +37,7 @@ atklog = sanitize_integer(atklog, 0, 100, initial(atklog)) fuid = sanitize_integer(fuid, 0, 10000000, initial(fuid)) parallax = sanitize_integer(parallax, 0, 16, initial(parallax)) - return 1 + return TRUE /datum/preferences/proc/save_preferences(client/C) @@ -126,550 +98,23 @@ qdel(query) return 1 -/datum/preferences/proc/load_character(client/C, slot) - saved = FALSE - - if(!slot) - slot = default_slot - slot = sanitize_integer(slot, 1, max_save_slots, initial(default_slot)) - if(slot != default_slot) - default_slot = slot - var/datum/db_query/firstquery = SSdbcore.NewQuery("UPDATE player SET default_slot=:slot WHERE ckey=:ckey", list( - "slot" = slot, - "ckey" = C.ckey - )) - if(!firstquery.warn_execute(async = FALSE)) // Dont make this async. It makes roundstart slow. - qdel(firstquery) - return - qdel(firstquery) - - if(!C) // If the client disconnected during the query, try again later. - qdel(src) - return TRUE - - // Let's not have this explode if you sneeze on the DB - var/datum/db_query/query = SSdbcore.NewQuery({"SELECT - OOC_Notes, - real_name, - name_is_always_random, - gender, - age, - species, - language, - hair_colour, - secondary_hair_colour, - facial_hair_colour, - secondary_facial_hair_colour, - skin_tone, - skin_colour, - marking_colours, - head_accessory_colour, - hair_style_name, - facial_style_name, - marking_styles, - head_accessory_style_name, - alt_head_name, - eye_colour, - underwear, - undershirt, - backbag, - b_type, - alternate_option, - job_support_high, - job_support_med, - job_support_low, - job_medsci_high, - job_medsci_med, - job_medsci_low, - job_engsec_high, - job_engsec_med, - job_engsec_low, - job_karma_high, - job_karma_med, - job_karma_low, - flavor_text, - med_record, - sec_record, - gen_record, - disabilities, - player_alt_titles, - organ_data, - rlimb_data, - nanotrasen_relation, - speciesprefs, - socks, - body_accessory, - gear, - autohiss - FROM characters WHERE ckey=:ckey AND slot=:slot"}, list( - "ckey" = C.ckey, - "slot" = slot - )) - if(!query.warn_execute(async = FALSE)) // Dont make this async. It makes roundstart slow. - qdel(query) - return - - while(query.NextRow()) - //Character - metadata = query.item[1] - real_name = query.item[2] - be_random_name = text2num(query.item[3]) - gender = query.item[4] - age = text2num(query.item[5]) - species = query.item[6] - language = query.item[7] - - h_colour = query.item[8] - h_sec_colour = query.item[9] - f_colour = query.item[10] - f_sec_colour = query.item[11] - s_tone = text2num(query.item[12]) - s_colour = query.item[13] - m_colours = params2list(query.item[14]) - hacc_colour = query.item[15] - h_style = query.item[16] - f_style = query.item[17] - m_styles = params2list(query.item[18]) - ha_style = query.item[19] - alt_head = query.item[20] - e_colour = query.item[21] - underwear = query.item[22] - undershirt = query.item[23] - backbag = query.item[24] - b_type = query.item[25] - - - //Jobs - alternate_option = text2num(query.item[26]) - job_support_high = text2num(query.item[27]) - job_support_med = text2num(query.item[28]) - job_support_low = text2num(query.item[29]) - job_medsci_high = text2num(query.item[30]) - job_medsci_med = text2num(query.item[31]) - job_medsci_low = text2num(query.item[32]) - job_engsec_high = text2num(query.item[33]) - job_engsec_med = text2num(query.item[34]) - job_engsec_low = text2num(query.item[35]) - job_karma_high = text2num(query.item[36]) - job_karma_med = text2num(query.item[37]) - job_karma_low = text2num(query.item[38]) - - //Miscellaneous - flavor_text = query.item[39] - med_record = query.item[40] - sec_record = query.item[41] - gen_record = query.item[42] - // Apparently, the preceding vars weren't always encoded properly... - if(findtext(flavor_text, "<")) // ... so let's clumsily check for tags! - flavor_text = html_encode(flavor_text) - if(findtext(med_record, "<")) - med_record = html_encode(med_record) - if(findtext(sec_record, "<")) - sec_record = html_encode(sec_record) - if(findtext(gen_record, "<")) - gen_record = html_encode(gen_record) - disabilities = text2num(query.item[43]) - player_alt_titles = params2list(query.item[44]) - organ_data = params2list(query.item[45]) - rlimb_data = params2list(query.item[46]) - nanotrasen_relation = query.item[47] - speciesprefs = text2num(query.item[48]) - - //socks - socks = query.item[49] - body_accessory = query.item[50] - loadout_gear = params2list(query.item[51]) - autohiss_mode = text2num(query.item[52]) - - saved = TRUE - - qdel(query) - //Sanitize - var/datum/species/SP = GLOB.all_species[species] - metadata = sanitize_text(metadata, initial(metadata)) - real_name = reject_bad_name(real_name, 1) - if(isnull(species)) species = "Human" - if(isnull(language)) language = "None" - if(isnull(nanotrasen_relation)) nanotrasen_relation = initial(nanotrasen_relation) - if(isnull(speciesprefs)) speciesprefs = initial(speciesprefs) - if(!real_name) real_name = random_name(gender,species) - be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name)) - gender = sanitize_gender(gender, FALSE, !SP.has_gender) - age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age)) - h_colour = sanitize_hexcolor(h_colour) - h_sec_colour = sanitize_hexcolor(h_sec_colour) - f_colour = sanitize_hexcolor(f_colour) - f_sec_colour = sanitize_hexcolor(f_sec_colour) - s_tone = sanitize_integer(s_tone, -185, 34, initial(s_tone)) - s_colour = sanitize_hexcolor(s_colour) - for(var/marking_location in m_colours) - m_colours[marking_location] = sanitize_hexcolor(m_colours[marking_location], DEFAULT_MARKING_COLOURS[marking_location]) - hacc_colour = sanitize_hexcolor(hacc_colour) - h_style = sanitize_inlist(h_style, GLOB.hair_styles_public_list, initial(h_style)) - f_style = sanitize_inlist(f_style, GLOB.facial_hair_styles_list, initial(f_style)) - for(var/marking_location in m_styles) - m_styles[marking_location] = sanitize_inlist(m_styles[marking_location], GLOB.marking_styles_list, DEFAULT_MARKING_STYLES[marking_location]) - ha_style = sanitize_inlist(ha_style, GLOB.head_accessory_styles_list, initial(ha_style)) - alt_head = sanitize_inlist(alt_head, GLOB.alt_heads_list, initial(alt_head)) - e_colour = sanitize_hexcolor(e_colour) - underwear = sanitize_text(underwear, initial(underwear)) - undershirt = sanitize_text(undershirt, initial(undershirt)) - backbag = sanitize_text(backbag, initial(backbag)) - b_type = sanitize_text(b_type, initial(b_type)) - autohiss_mode = sanitize_integer(autohiss_mode, 0, 2, initial(autohiss_mode)) - - alternate_option = sanitize_integer(alternate_option, 0, 2, initial(alternate_option)) - job_support_high = sanitize_integer(job_support_high, 0, 65535, initial(job_support_high)) - job_support_med = sanitize_integer(job_support_med, 0, 65535, initial(job_support_med)) - job_support_low = sanitize_integer(job_support_low, 0, 65535, initial(job_support_low)) - job_medsci_high = sanitize_integer(job_medsci_high, 0, 65535, initial(job_medsci_high)) - job_medsci_med = sanitize_integer(job_medsci_med, 0, 65535, initial(job_medsci_med)) - job_medsci_low = sanitize_integer(job_medsci_low, 0, 65535, initial(job_medsci_low)) - job_engsec_high = sanitize_integer(job_engsec_high, 0, 65535, initial(job_engsec_high)) - job_engsec_med = sanitize_integer(job_engsec_med, 0, 65535, initial(job_engsec_med)) - job_engsec_low = sanitize_integer(job_engsec_low, 0, 65535, initial(job_engsec_low)) - job_karma_high = sanitize_integer(job_karma_high, 0, 65535, initial(job_karma_high)) - job_karma_med = sanitize_integer(job_karma_med, 0, 65535, initial(job_karma_med)) - job_karma_low = sanitize_integer(job_karma_low, 0, 65535, initial(job_karma_low)) - disabilities = sanitize_integer(disabilities, 0, 65535, initial(disabilities)) - - socks = sanitize_text(socks, initial(socks)) - body_accessory = sanitize_text(body_accessory, initial(body_accessory)) - -// if(isnull(disabilities)) disabilities = 0 - if(!player_alt_titles) player_alt_titles = new() - if(!organ_data) src.organ_data = list() - if(!rlimb_data) src.rlimb_data = list() - if(!loadout_gear) loadout_gear = list() - - // Check if the current body accessory exists - if(!GLOB.body_accessory_by_name[body_accessory]) - body_accessory = null - - return 1 - -/datum/preferences/proc/save_character(client/C) - var/organlist - var/rlimblist - var/playertitlelist - var/gearlist - - var/markingcolourslist = list2params(m_colours) - var/markingstyleslist = list2params(m_styles) - if(!isemptylist(organ_data)) - organlist = list2params(organ_data) - if(!isemptylist(rlimb_data)) - rlimblist = list2params(rlimb_data) - if(!isemptylist(player_alt_titles)) - playertitlelist = list2params(player_alt_titles) - if(!isemptylist(loadout_gear)) - gearlist = list2params(loadout_gear) - - var/datum/db_query/firstquery = SSdbcore.NewQuery("SELECT slot FROM characters WHERE ckey=:ckey ORDER BY slot", list( - "ckey" = C.ckey - )) - if(!firstquery.warn_execute()) - qdel(firstquery) - return - while(firstquery.NextRow()) - if(text2num(firstquery.item[1]) == default_slot) - var/datum/db_query/query = SSdbcore.NewQuery({"UPDATE characters - SET - OOC_Notes=:metadata, - real_name=:real_name, - name_is_always_random=:be_random_name, - gender=:gender, - age=:age, - species=:species, - language=:language, - hair_colour=:h_colour, - secondary_hair_colour=:h_sec_colour, - facial_hair_colour=:f_colour, - secondary_facial_hair_colour=:f_sec_colour, - skin_tone=:s_tone, - skin_colour=:s_colour, - marking_colours=:markingcolourslist, - head_accessory_colour=:hacc_colour, - hair_style_name=:h_style, - facial_style_name=:f_style, - marking_styles=:markingstyleslist, - head_accessory_style_name=:ha_style, - alt_head_name=:alt_head, - eye_colour=:e_colour, - underwear=:underwear, - undershirt=:undershirt, - backbag=:backbag, - b_type=:b_type, - alternate_option=:alternate_option, - job_support_high=:job_support_high, - job_support_med=:job_support_med, - job_support_low=:job_support_low, - job_medsci_high=:job_medsci_high, - job_medsci_med=:job_medsci_med, - job_medsci_low=:job_medsci_low, - job_engsec_high=:job_engsec_high, - job_engsec_med=:job_engsec_med, - job_engsec_low=:job_engsec_low, - job_karma_high=:job_karma_high, - job_karma_med=:job_karma_med, - job_karma_low=:job_karma_low, - flavor_text=:flavor_text, - med_record=:med_record, - sec_record=:sec_record, - gen_record=:gen_record, - player_alt_titles=:playertitlelist, - disabilities=:disabilities, - organ_data=:organlist, - rlimb_data=:rlimblist, - nanotrasen_relation=:nanotrasen_relation, - speciesprefs=:speciesprefs, - socks=:socks, - body_accessory=:body_accessory, - gear=:gearlist, - autohiss=:autohiss_mode - WHERE ckey=:ckey - AND slot=:slot"}, list( - // OH GOD SO MANY PARAMETERS - "metadata" = metadata, - "real_name" = real_name, - "be_random_name" = be_random_name, - "gender" = gender, - "age" = age, - "species" = species, - "language" = language, - "h_colour" = h_colour, - "h_sec_colour" = h_sec_colour, - "f_colour" = f_colour, - "f_sec_colour" = f_sec_colour, - "s_tone" = s_tone, - "s_colour" = s_colour, - "markingcolourslist" = markingcolourslist, - "hacc_colour" = hacc_colour, - "h_style" = h_style, - "f_style" = f_style, - "markingstyleslist" = markingstyleslist, - "ha_style" = ha_style, - "alt_head" = (alt_head ? alt_head : ""), // This it intentional. It wont work without it! - "e_colour" = e_colour, - "underwear" = underwear, - "undershirt" = undershirt, - "backbag" = backbag, - "b_type" = b_type, - "alternate_option" = alternate_option, - "job_support_high" = job_support_high, - "job_support_med" = job_support_med, - "job_support_low" = job_support_low, - "job_medsci_high" = job_medsci_high, - "job_medsci_med" = job_medsci_med, - "job_medsci_low" = job_medsci_low, - "job_engsec_high" = job_engsec_high, - "job_engsec_med" = job_engsec_med, - "job_engsec_low" = job_engsec_low, - "job_karma_high" = job_karma_high, - "job_karma_med" = job_karma_med, - "job_karma_low" = job_karma_low, - "flavor_text" = flavor_text, - "med_record" = med_record, - "sec_record" = sec_record, - "gen_record" = gen_record, - "playertitlelist" = (playertitlelist ? playertitlelist : ""), // This it intentnional. It wont work without it! - "disabilities" = disabilities, - "organlist" = (organlist ? organlist : ""), - "rlimblist" = (rlimblist ? rlimblist : ""), - "nanotrasen_relation" = nanotrasen_relation, - "speciesprefs" = speciesprefs, - "socks" = socks, - "body_accessory" = (body_accessory ? body_accessory : ""), - "gearlist" = (gearlist ? gearlist : ""), - "autohiss_mode" = autohiss_mode, - "ckey" = C.ckey, - "slot" = default_slot - ) - ) - - if(!query.warn_execute()) - qdel(firstquery) - qdel(query) - return - qdel(firstquery) - qdel(query) - return 1 - - qdel(firstquery) - - var/datum/db_query/query = SSdbcore.NewQuery({" - INSERT INTO characters (ckey, slot, OOC_Notes, real_name, name_is_always_random, gender, - age, species, language, - hair_colour, secondary_hair_colour, - facial_hair_colour, secondary_facial_hair_colour, - skin_tone, skin_colour, - marking_colours, - head_accessory_colour, - hair_style_name, - facial_style_name, - marking_styles, - head_accessory_style_name, - alt_head_name, - eye_colour, - underwear, undershirt, - backbag, b_type, alternate_option, - job_support_high, job_support_med, job_support_low, - job_medsci_high, job_medsci_med, job_medsci_low, - job_engsec_high, job_engsec_med, job_engsec_low, - job_karma_high, job_karma_med, job_karma_low, - flavor_text, - med_record, - sec_record, - gen_record, - player_alt_titles, - disabilities, organ_data, rlimb_data, nanotrasen_relation, speciesprefs, - socks, body_accessory, gear, autohiss) - - VALUES - (:ckey, :slot, :metadata, :name, :be_random_name, :gender, - :age, :species, :language, - :h_colour, :h_sec_colour, - :f_colour, :f_sec_colour, - :s_tone, :s_colour, - :markingcolourslist, - :hacc_colour, - :h_style, - :f_style, - :markingstyleslist, - :ha_style, - :alt_head, - :e_colour, - :underwear, :undershirt, - :backbag, :b_type, :alternate_option, - :job_support_high, :job_support_med, :job_support_low, - :job_medsci_high, :job_medsci_med, :job_medsci_low, - :job_engsec_high, :job_engsec_med, :job_engsec_low, - :job_karma_high, :job_karma_med, :job_karma_low, - :flavor_text, - :med_record, - :sec_record, - :gen_record, - :playertitlelist, - :disabilities, :organlist, :rlimblist, :nanotrasen_relation, :speciesprefs, - :socks, :body_accessory, :gearlist, :autohiss_mode) - - "}, list( - // This has too many params for anyone to look at this without going insae - "ckey" = C.ckey, - "slot" = default_slot, - "metadata" = metadata, - "name" = real_name, - "be_random_name" = be_random_name, - "gender" = gender, - "age" = age, - "species" = species, - "language" = language, - "h_colour" = h_colour, - "h_sec_colour" = h_sec_colour, - "f_colour" = f_colour, - "f_sec_colour" = f_sec_colour, - "s_tone" = s_tone, - "s_colour" = s_colour, - "markingcolourslist" = markingcolourslist, - "hacc_colour" = hacc_colour, - "h_style" = h_style, - "f_style" = f_style, - "markingstyleslist" = markingstyleslist, - "ha_style" = ha_style, - "alt_head" = alt_head, - "e_colour" = e_colour, - "underwear" = underwear, - "undershirt" = undershirt, - "backbag" = backbag, - "b_type" = b_type, - "alternate_option" = alternate_option, - "job_support_high" = job_support_high, - "job_support_med" = job_support_med, - "job_support_low" = job_support_low, - "job_medsci_high" = job_medsci_high, - "job_medsci_med" = job_medsci_med, - "job_medsci_low" = job_medsci_low, - "job_engsec_high" = job_engsec_high, - "job_engsec_med" = job_engsec_med, - "job_engsec_low" = job_engsec_low, - "job_karma_high" = job_karma_high, - "job_karma_med" = job_karma_med, - "job_karma_low" = job_karma_low, - "flavor_text" = flavor_text, - "med_record" = med_record, - "sec_record" = sec_record, - "gen_record" = gen_record, - "playertitlelist" = (playertitlelist ? playertitlelist : ""), // This it intentnional. It wont work without it! - "disabilities" = disabilities, - "organlist" = (organlist ? organlist : ""), - "rlimblist" = (rlimblist ? rlimblist : ""), - "nanotrasen_relation" = nanotrasen_relation, - "speciesprefs" = speciesprefs, - "socks" = socks, - "body_accessory" = (body_accessory ? body_accessory : ""), - "gearlist" = (gearlist ? gearlist : ""), - "autohiss_mode" = autohiss_mode - )) - - if(!query.warn_execute()) - qdel(query) - return - - qdel(query) - saved = TRUE - return 1 /datum/preferences/proc/load_random_character_slot(client/C) - var/datum/db_query/query = SSdbcore.NewQuery("SELECT slot FROM characters WHERE ckey=:ckey ORDER BY slot", list( - "ckey" = C.ckey - )) - var/list/saves = list() + var/list/datum/character_save/valid_slots = list() + for(var/datum/character_save/CS in character_saves) + if(CS.valid_save) + valid_slots += CS - if(!query.warn_execute(async = FALSE)) // Dont async this. Youll make roundstart slow. - qdel(query) + if(!length(valid_slots)) + // They have no valid saves. Lets just randomise #1 + var/datum/character_save/CS = C.prefs.character_saves[1] // Get slot 1 + CS.randomise() + CS.real_name = random_name(CS.gender) // Pick a name + C.prefs.active_character = C.prefs.character_saves[1] // Set slot 1 as their active return - while(query.NextRow()) - saves += text2num(query.item[1]) - qdel(query) - - if(!saves.len) - load_character(C) - return 0 - load_character(C,pick(saves)) - return 1 - -/datum/preferences/proc/clear_character_slot(client/C) - . = FALSE - // Is there a character in that slot? - var/datum/db_query/query = SSdbcore.NewQuery("SELECT slot FROM characters WHERE ckey=:ckey AND slot=:slot", list( - "ckey" = C.ckey, - "slot" = default_slot - )) - - if(!query.warn_execute()) - qdel(query) - return - - if(!query.NextRow()) - qdel(query) - return - - qdel(query) - - var/datum/db_query/delete_query = SSdbcore.NewQuery("DELETE FROM characters WHERE ckey=:ckey AND slot=:slot", list( - "ckey" = C.ckey, - "slot" = default_slot - )) - - if(!delete_query.warn_execute()) - qdel(delete_query) - return - - qdel(delete_query) - - saved = FALSE - return TRUE + var/datum/character_save/CS = pick(valid_slots) + C.prefs.active_character = CS /** * Saves [/datum/preferences/proc/volume_mixer] for the current client. diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 3f79aa71727..bbcebdc519d 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -428,6 +428,10 @@ BLIND // can't see anything var/datum/action/A = X A.UpdateButtonIcon() +// Changes the speech verb when wearing a mask if a value is returned +/obj/item/clothing/mask/proc/change_speech_verb() + return + //Shoes /obj/item/clothing/shoes name = "shoes" diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index bddb5701535..cb2b402b2a2 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -313,7 +313,7 @@ flags = BLOCKHAIR flags_inv = HIDEFACE w_class = WEIGHT_CLASS_SMALL - var/voicechange = 0 + var/voicechange = FALSE var/temporaryname = " the Horse" var/originalname = "" @@ -347,6 +347,10 @@ if(user.real_name == "[originalname][temporaryname]" || user.real_name == "A Horse With No Name") //if it's somehow changed while the mask is on it doesn't revert user.real_name = originalname +/obj/item/clothing/mask/horsehead/change_speech_verb() + if(voicechange) + return pick("whinnies", "neighs", "says") + /obj/item/clothing/mask/face flags_inv = HIDEFACE flags_cover = MASKCOVERSMOUTH diff --git a/code/modules/clothing/masks/voicemodulator.dm b/code/modules/clothing/masks/voicemodulator.dm new file mode 100644 index 00000000000..c05a17aeab1 --- /dev/null +++ b/code/modules/clothing/masks/voicemodulator.dm @@ -0,0 +1,44 @@ +/obj/item/clothing/mask/gas/voice_modulator + name = "modified gas mask" + desc = "A gas mask modified with a sound modulator that disguises the user's voice when active" + icon_state = "voice_modulator" + item_state = "voice_modulator" + + var/obj/item/voice_changer/voice_modulator/voice_modulator + +/obj/item/clothing/mask/gas/voice_modulator/Initialize(mapload) + . = ..() + voice_modulator = new(src) + +/obj/item/clothing/mask/gas/voice_modulator/Destroy() + QDEL_NULL(voice_modulator) + return ..() + +/obj/item/clothing/mask/gas/voice_modulator/chameleon + name = "chameleon voice modulator mask" + desc = "A tactical mask equipped with chameleon technology and a sound modulator that disguises the user's voice when active" + icon_state = "swat" + item_state = "swat" + + var/datum/action/item_action/chameleon/change/chameleon_action + +/obj/item/clothing/mask/gas/voice_modulator/chameleon/Initialize(mapload) + . = ..() + + chameleon_action = new(src) + chameleon_action.chameleon_type = /obj/item/clothing/mask + chameleon_action.chameleon_name = "Mask" + chameleon_action.chameleon_blacklist = list() + chameleon_action.initialize_disguises() + +/obj/item/clothing/mask/gas/voice_modulator/chameleon/Destroy() + QDEL_NULL(chameleon_action) + return ..() + +/obj/item/clothing/mask/gas/voice_modulator/chameleon/emp_act(severity) + . = ..() + chameleon_action.emp_randomise() + +/obj/item/clothing/mask/gas/voice_modulator/change_speech_verb() + if(voice_modulator.active) + return pick("modulates", "drones", "hums", "buzzes") diff --git a/code/modules/crafting/tailoring.dm b/code/modules/crafting/tailoring.dm index 6a597e9e8fa..a1fc09728d0 100644 --- a/code/modules/crafting/tailoring.dm +++ b/code/modules/crafting/tailoring.dm @@ -162,3 +162,13 @@ tools = list(TOOL_WIRECUTTER) pathtools = list(/obj/item/kitchen/knife) category = CAT_CLOTHING + +/datum/crafting_recipe/voice_modulator + name = "Voice Modulator Mask" + result = list(/obj/item/clothing/mask/gas/voice_modulator) + time = 45 + tools = list(TOOL_SCREWDRIVER, TOOL_MULTITOOL) + reqs = list(/obj/item/clothing/mask/gas = 1, + /obj/item/assembly/voice = 1, + /obj/item/stack/cable_coil = 5) + category = CAT_CLOTHING diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm index 615718bb834..ca0a4df5f69 100644 --- a/code/modules/mining/equipment/survival_pod.dm +++ b/code/modules/mining/equipment/survival_pod.dm @@ -323,7 +323,7 @@ /obj/item/lava_staff, /obj/item/katana/energy, /obj/item/hierophant_club, - /obj/item/storage/toolbox/green/memetic, + /obj/item/his_grace, /obj/item/gun/projectile/automatic/l6_saw, /obj/item/gun/magic/staff/chaos, /obj/item/gun/magic/staff/spellblade, diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 80fe2db8bb2..e32efa0c05a 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -743,7 +743,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp return var/mob/living/carbon/human/new_char = new(get_turf(src)) - client.prefs.copy_to(new_char) + client.prefs.active_character.copy_to(new_char) if(mind) mind.active = TRUE mind.transfer_to(new_char) diff --git a/code/modules/mob/living/autohiss.dm b/code/modules/mob/living/autohiss.dm index 78c12148ee3..0535b3f172b 100644 --- a/code/modules/mob/living/autohiss.dm +++ b/code/modules/mob/living/autohiss.dm @@ -2,17 +2,17 @@ return message // no autohiss at this level /mob/living/carbon/human/handle_autohiss(message, datum/language/L) - if(!client || client.prefs.autohiss_mode == AUTOHISS_OFF) // no need to process if there's no client or they have autohiss off + if(!client || client.prefs.active_character.autohiss_mode == AUTOHISS_OFF) // no need to process if there's no client or they have autohiss off return message - return dna.species.handle_autohiss(message, L, client.prefs.autohiss_mode) + return dna.species.handle_autohiss(message, L, client.prefs.active_character.autohiss_mode) /client/verb/toggle_autohiss() set name = "Toggle Auto-Accent" set desc = "Toggle automatic accents for your species" set category = "OOC" - prefs.autohiss_mode = (prefs.autohiss_mode + 1) % AUTOHISS_NUM - switch(prefs.autohiss_mode) + prefs.active_character.autohiss_mode = (prefs.active_character.autohiss_mode + 1) % AUTOHISS_NUM + switch(prefs.active_character.autohiss_mode) if(AUTOHISS_OFF) to_chat(src, "Auto-hiss is now OFF.") if(AUTOHISS_BASIC) @@ -20,7 +20,7 @@ if(AUTOHISS_FULL) to_chat(src, "Auto-hiss is now FULL.") else - prefs.autohiss_mode = AUTOHISS_OFF + prefs.active_character.autohiss_mode = AUTOHISS_OFF to_chat(src, "Auto-hiss is now OFF.") /datum/species @@ -61,7 +61,7 @@ /datum/species/drask autohiss_basic_map = list( "o" = list ("oo", "ooo"), - "u" = list ("uu", "uuu") + "u" = list ("uu", "uuu") ) autohiss_extra_map = list( "m" = list ("mm", "mmm") diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 0677ca0f1d3..15ed07ecdf7 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1955,7 +1955,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X if(GLOB.configuration.general.allow_character_metadata) if(client) - to_chat(usr, "[src]'s Metainfo:
    [sanitize(client.prefs.metadata)]") + to_chat(usr, "[src]'s Metainfo:
    [sanitize(client.prefs.active_character.metadata)]") else to_chat(usr, "[src] does not have any stored infomation!") else diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index 4f857163500..76211cf3198 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -149,7 +149,6 @@ var/obj/item/clothing/mask/horsehead/hoers = wear_mask if(hoers.voicechange) S.message = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!") - verb = pick("whinnies", "neighs", "says") if(dna) for(var/mutation_type in active_mutations) @@ -167,6 +166,12 @@ if(span) S.message = "[S.message]" + + if(wear_mask) + var/speech_verb_when_masked = wear_mask.change_speech_verb() + if(speech_verb_when_masked) + verb = speech_verb_when_masked + return list("verb" = verb) /mob/living/carbon/human/handle_message_mode(message_mode, list/message_pieces, verb, used_radios) diff --git a/code/modules/mob/living/carbon/human/species/grey.dm b/code/modules/mob/living/carbon/human/species/grey.dm index 915d0072434..6959a08e38f 100644 --- a/code/modules/mob/living/carbon/human/species/grey.dm +++ b/code/modules/mob/living/carbon/human/species/grey.dm @@ -67,7 +67,7 @@ to_chat(H, "The water stings[volume < 10 ? " you, but isn't concentrated enough to harm you" : null]!") /datum/species/grey/after_equip_job(datum/job/J, mob/living/carbon/human/H) - var/translator_pref = H.client.prefs.speciesprefs + var/translator_pref = H.client.prefs.active_character.speciesprefs if(translator_pref || ((ismindshielded(H) || J.is_command || J.supervisors == "the captain") && HAS_TRAIT(H, TRAIT_WINGDINGS))) if(J.title == "Mime") return diff --git a/code/modules/mob/living/carbon/human/species/vox.dm b/code/modules/mob/living/carbon/human/species/vox.dm index 377da561e5a..a52ae7bb06d 100644 --- a/code/modules/mob/living/carbon/human/species/vox.dm +++ b/code/modules/mob/living/carbon/human/species/vox.dm @@ -81,7 +81,7 @@ H.unEquip(H.wear_mask) H.equip_or_collect(new /obj/item/clothing/mask/breath/vox(H), slot_wear_mask) - var/tank_pref = H.client && H.client.prefs ? H.client.prefs.speciesprefs : null + var/tank_pref = H.client && H.client.prefs ? H.client.prefs.active_character.speciesprefs : null var/obj/item/tank/internal_tank if(tank_pref)//Diseasel, here you go internal_tank = new /obj/item/tank/internals/nitrogen(H) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 5748775558a..8affd317c6a 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -300,7 +300,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( /mob/living/silicon/robot/proc/pick_module() if(module) return - var/list/modules = list("Generalist", "Engineering", "Medical", "Miner", "Janitor", "Service", "Security") + var/list/modules = list("Engineering", "Medical", "Miner", "Janitor", "Service") if(islist(force_modules) && force_modules.len) modules = force_modules.Copy() if(mmi != null && mmi.alien) @@ -315,14 +315,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( return switch(modtype) - if("Generalist") - module = new /obj/item/robot_module/standard(src) - module.channels = list("Engineering" = 1, "Medical" = 1, "Security" = 1, "Service" = 1, "Supply" = 1) - module_sprites["Basic"] = "robot_old" - module_sprites["Android"] = "droid" - module_sprites["Default"] = "Standard" - module_sprites["Noble-STD"] = "Noble-STD" - if("Service") module = new /obj/item/robot_module/butler(src) module.channels = list("Service" = 1) @@ -365,17 +357,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( see_reagents = TRUE if("Security") - if(!weapons_unlock) - var/count_secborgs = 0 - for(var/mob/living/silicon/robot/R in GLOB.alive_mob_list) - if(R && R.stat != DEAD && R.module && istype(R.module, /obj/item/robot_module/security)) - count_secborgs++ - var/max_secborgs = 2 - if(GLOB.security_level == SEC_LEVEL_GREEN) - max_secborgs = 1 - if(count_secborgs >= max_secborgs) - to_chat(src, "There are too many Security cyborgs active. Please choose another module.") - return module = new /obj/item/robot_module/security(src) module.channels = list("Security" = 1) module_sprites["Basic"] = "secborg" @@ -1349,7 +1330,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( scrambledcodes = 1 req_one_access = list(ACCESS_CENT_SPECOPS) ionpulse = 1 - force_modules = list("Engineering", "Medical", "Security") + force_modules = list("Engineering", "Medical") static_radio_channels = 1 allow_rename = FALSE weapons_unlock = TRUE diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 8a43a2a011e..ab7c4ff9562 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -265,47 +265,6 @@ /obj/item/robot_module/proc/handle_death(mob/living/silicon/robot/R, gibbed) return -// Standard cyborg module. -/obj/item/robot_module/standard - // if station is fine, assist with constructing station goal room, cleaning, and repairing cables chewed by rats - // if medical crisis, assist by providing basic healthcare, retrieving corpses, and monitoring crew lifesigns - // if eng crisis, assist by helping repair hull breaches - // if sec crisis, assist by opening doors for sec and providing backup zipties on patrols - name = "generalist robot module" - module_type = "Standard" - subsystems = list(/mob/living/silicon/proc/subsystem_power_monitor, /mob/living/silicon/proc/subsystem_crew_monitor) - basic_modules = list( - // sec - /obj/item/flash/cyborg, - /obj/item/restraints/handcuffs/cable/zipties/cyborg, - // janitorial - /obj/item/soap/nanotrasen, - /obj/item/lightreplacer/cyborg, - // eng - /obj/item/crowbar/cyborg, - /obj/item/wrench/cyborg, - /obj/item/extinguisher, // for firefighting, and propulsion in space - /obj/item/weldingtool/largetank/cyborg, - // mining - /obj/item/pickaxe, - /obj/item/t_scanner/adv_mining_scanner, - /obj/item/storage/bag/ore/cyborg, - // med - /obj/item/healthanalyzer, - /obj/item/reagent_containers/borghypo/basic, - /obj/item/roller_holder, // for taking the injured to medbay without worsening their injuries or leaving a blood trail the whole way - /obj/item/stack/sheet/metal/cyborg, - /obj/item/stack/cable_coil/cyborg, - /obj/item/stack/rods/cyborg, - /obj/item/stack/tile/plasteel/cyborg - ) - emag_modules = list(/obj/item/melee/energy/sword/cyborg) - special_rechargables = list( - /obj/item/extinguisher, - /obj/item/weldingtool/largetank/cyborg, - /obj/item/lightreplacer/cyborg - ) - // Medical cyborg module. /obj/item/robot_module/medical name = "medical robot module" @@ -319,6 +278,7 @@ /obj/item/borg_defib, /obj/item/handheld_defibrillator, /obj/item/roller_holder, + /obj/item/borg/cyborghug, /obj/item/reagent_containers/borghypo, /obj/item/scalpel/laser/laser1, /obj/item/hemostat, diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm index beca603f4cc..5abf3b185b5 100644 --- a/code/modules/mob/living/simple_animal/bot/construction.dm +++ b/code/modules/mob/living/simple_animal/bot/construction.dm @@ -214,7 +214,7 @@ var/list/allowed_toolbox = list(/obj/item/storage/toolbox/emergency, //which toolboxes can be made into floorbots /obj/item/storage/toolbox/electrical, /obj/item/storage/toolbox/mechanical, - /obj/item/storage/toolbox/green, + /obj/item/storage/toolbox/artistic, /obj/item/storage/toolbox/syndicate, /obj/item/storage/toolbox/fakesyndi) @@ -223,8 +223,6 @@ return if(!is_type_in_list(src, allowed_toolbox)) return - if(type == /obj/item/storage/toolbox/green/memetic) - return if(contents.len >= 1) to_chat(user, "They won't fit in, as there is already stuff inside.") return @@ -242,7 +240,7 @@ B.toolbox_color = "or" if(/obj/item/storage/toolbox/electrical) B.toolbox_color = "y" - if(/obj/item/storage/toolbox/green) + if(/obj/item/storage/toolbox/artistic) B.toolbox_color = "g" if(/obj/item/storage/toolbox/syndicate) B.toolbox_color = "s" diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm index 5be97564787..352eae47ead 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm @@ -69,7 +69,7 @@ Difficulty: Medium ranged_cooldown = world.time + ranged_cooldown_time else visible_message("[src] charges!") - SpinAnimation(speed = 20, loops = 5) + SpinAnimation(speed = 20, loops = 5, parallel = FALSE) ranged = 0 retreat_distance = 0 minimum_distance = 0 diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index fab75c91507..c7a11c933b9 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -365,9 +365,6 @@ // STUN /mob/living/Stun(amount, updating = 1, force = 0) - if(status_flags & CANSTUN || force) - if(absorb_stun(amount, force)) - return FALSE return SetStunned(max(stunned, amount), updating, force) /mob/living/SetStunned(amount, updating = 1, force = 0) //if you REALLY need to set stun to a set amount without the whole "can't go below current stunned" @@ -377,6 +374,8 @@ . = STATUS_UPDATE_NONE if(status_flags & CANSTUN || force) + if(absorb_stun(amount, force)) + return STATUS_UPDATE_NONE stunned = max(amount, 0) if(updating) update_canmove() @@ -405,9 +404,6 @@ // WEAKEN /mob/living/Weaken(amount, updating = 1, force = 0) - if(status_flags & CANWEAKEN || force) - if(absorb_stun(amount, force)) - return FALSE return SetWeakened(max(weakened, amount), updating, force) /mob/living/SetWeakened(amount, updating = 1, force = 0) @@ -416,6 +412,8 @@ updating = FALSE . = STATUS_UPDATE_NONE if(status_flags & CANWEAKEN || force) + if(absorb_stun(amount, force)) + return STATUS_UPDATE_NONE weakened = max(amount, 0) if(updating) update_canmove() //updates lying, canmove and icons diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 38669dba55f..2d103da8be5 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -684,13 +684,13 @@ GLOBAL_LIST_INIT(intents, list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM /mob/proc/has_valid_preferences() if(!client) return FALSE //Not sure how this would get run without the mob having a client, but let's just be safe. - if(client.prefs.alternate_option != RETURN_TO_LOBBY) + if(client.prefs.active_character.alternate_option != RETURN_TO_LOBBY) return TRUE // If they have antags enabled, they're potentially doing this on purpose instead of by accident. Notify admins if so. var/has_antags = FALSE if(client.prefs.be_special.len > 0) has_antags = TRUE - if(!client.prefs.check_any_job()) + if(!client.prefs.active_character.check_any_job()) to_chat(src, "You have no jobs enabled, along with return to lobby if job is unavailable. This makes you ineligible for any round start role, please update your job preferences.") if(has_antags) log_admin("[src.ckey] just got booted back to lobby with no jobs, but antags enabled.") diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index ec54e6aa9c4..04aca83e512 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -42,7 +42,7 @@ /mob/new_player/proc/new_player_panel_proc() - var/real_name = client.prefs.real_name + var/real_name = client.prefs.active_character.real_name if(client.prefs.toggles2 & PREFTOGGLE_2_RANDOMSLOT) real_name = "Random Character Slot" var/output = "

    Setup Character
    [real_name]

    " @@ -184,13 +184,13 @@ to_chat(src, "Now teleporting.") observer.forceMove(O.loc) observer.timeofdeath = world.time // Set the time of death so that the respawn timer works correctly. - client.prefs.update_preview_icon(1) - observer.icon = client.prefs.preview_icon + client.prefs.active_character.update_preview_icon(1) + observer.icon = client.prefs.active_character.preview_icon observer.alpha = 127 - if(client.prefs.be_random_name) - client.prefs.real_name = random_name(client.prefs.gender,client.prefs.species) - observer.real_name = client.prefs.real_name + if(client.prefs.active_character.be_random_name) + client.prefs.active_character.real_name = random_name(client.prefs.active_character.gender,client.prefs.active_character.species) + observer.real_name = client.prefs.active_character.real_name observer.name = observer.real_name observer.key = key QDEL_NULL(mind) @@ -212,10 +212,10 @@ if(!SSticker || SSticker.current_state != GAME_STATE_PLAYING) to_chat(usr, "The round is either not ready, or has already finished...") return - if(client.prefs.species in GLOB.whitelisted_species) + if(client.prefs.active_character.species in GLOB.whitelisted_species) - if(!is_alien_whitelisted(src, client.prefs.species)) - to_chat(src, alert("You are currently not whitelisted to play [client.prefs.species].")) + if(!is_alien_whitelisted(src, client.prefs.active_character.species)) + to_chat(src, alert("You are currently not whitelisted to play [client.prefs.active_character.species].")) return FALSE LateChoices() @@ -232,12 +232,12 @@ if(client.prefs.toggles2 & PREFTOGGLE_2_RANDOMSLOT) client.prefs.load_random_character_slot(client) - if(client.prefs.species in GLOB.whitelisted_species) - if(!is_alien_whitelisted(src, client.prefs.species)) - to_chat(src, alert("You are currently not whitelisted to play [client.prefs.species].")) + if(client.prefs.active_character.species in GLOB.whitelisted_species) + if(!is_alien_whitelisted(src, client.prefs.active_character.species)) + to_chat(src, alert("You are currently not whitelisted to play [client.prefs.active_character.species].")) return FALSE - AttemptLateSpawn(href_list["SelectedJob"],client.prefs.spawnpoint) + AttemptLateSpawn(href_list["SelectedJob"],client.prefs.active_character.spawnpoint) return if(!ready && href_list["preference"]) @@ -543,9 +543,9 @@ new_character.lastarea = get_area(loc) if(SSticker.random_players || appearance_isbanned(new_character)) - client.prefs.random_character() - client.prefs.real_name = random_name(client.prefs.gender) - client.prefs.copy_to(new_character) + client.prefs.active_character.randomise() + client.prefs.active_character.real_name = random_name(client.prefs.active_character.gender) + client.prefs.active_character.copy_to(new_character) stop_sound_channel(CHANNEL_LOBBYMUSIC) @@ -569,19 +569,19 @@ // This is to check that the player only has preferences set that they're supposed to /mob/new_player/proc/check_prefs_are_sane() var/datum/species/chosen_species - if(client.prefs.species) - chosen_species = GLOB.all_species[client.prefs.species] + if(client.prefs.active_character.species) + chosen_species = GLOB.all_species[client.prefs.active_character.species] if(!(chosen_species && (is_species_whitelisted(chosen_species) || has_admin_rights()))) // Have to recheck admin due to no usr at roundstart. Latejoins are fine though. - log_runtime(EXCEPTION("[src] had species [client.prefs.species], though they weren't supposed to. Setting to Human."), src) - client.prefs.species = "Human" + log_runtime(EXCEPTION("[src] had species [client.prefs.active_character.species], though they weren't supposed to. Setting to Human."), src) + client.prefs.active_character.species = "Human" var/datum/language/chosen_language - if(client.prefs.language) - chosen_language = GLOB.all_languages[client.prefs.language] - if((chosen_language == null && client.prefs.language != "None") || (chosen_language && chosen_language.flags & RESTRICTED)) - log_runtime(EXCEPTION("[src] had language [client.prefs.language], though they weren't supposed to. Setting to None."), src) - client.prefs.language = "None" + if(client.prefs.active_character.language) + chosen_language = GLOB.all_languages[client.prefs.active_character.language] + if((chosen_language == null && client.prefs.active_character.language != "None") || (chosen_language && chosen_language.flags & RESTRICTED)) + log_runtime(EXCEPTION("[src] had language [client.prefs.active_character.language], though they weren't supposed to. Setting to None."), src) + client.prefs.active_character.language = "None" /mob/new_player/proc/ViewManifest() GLOB.generic_crew_manifest.ui_interact(usr, state = GLOB.always_state) @@ -607,7 +607,7 @@ /mob/new_player/get_gender() if(!client || !client.prefs) ..() - return client.prefs.gender + return client.prefs.active_character.gender /mob/new_player/is_ready() return ready && ..() diff --git a/code/modules/pda/PDA.dm b/code/modules/pda/PDA.dm old mode 100644 new mode 100755 diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index 355972c8fda..e38451f6adf 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -110,7 +110,7 @@ /obj/item/ammo_box/magazine/internal/shot/com name = "combat shotgun internal magazine" - ammo_type = /obj/item/ammo_casing/shotgun/buckshot + ammo_type = /obj/item/ammo_casing/shotgun/beanbag max_ammo = 6 /obj/item/ammo_box/magazine/internal/shot/dual @@ -133,9 +133,6 @@ /obj/item/ammo_box/magazine/internal/shot/riot/short max_ammo = 3 -/obj/item/ammo_box/magazine/internal/shot/riot/buckshot - ammo_type = /obj/item/ammo_casing/shotgun/buckshot - /obj/item/ammo_box/magazine/internal/grenadelauncher name = "grenade launcher internal magazine" ammo_type = /obj/item/ammo_casing/a40mm diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index fc650f1810f..b69482fdf6c 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -403,7 +403,7 @@ return TRUE /obj/item/gun/extinguish_light() - if(gun_light.on) + if(gun_light?.on) toggle_gunlight() visible_message("[src]'s light fades and turns off.") diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index ec24553f68d..df7992a69ae 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -175,7 +175,7 @@ /obj/item/gun/projectile/automatic/m90/attackby(obj/item/A, mob/user, params) if(istype(A, /obj/item/ammo_casing)) if(istype(A, underbarrel.magazine.ammo_type)) - underbarrel.attack_self() + underbarrel.attack_self(user) underbarrel.attackby(A, user, params) else return ..() diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index 16bdfec9b2b..c32ca8cb26e 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -204,10 +204,6 @@ ..() post_sawoff() -/obj/item/gun/projectile/shotgun/riot/buckshot //comes pre-loaded with buckshot rather than rubber - mag_type = /obj/item/ammo_box/magazine/internal/shot/riot/buckshot - - /////////////////////// // BOLT ACTION RIFLE // /////////////////////// diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index 260a7c17855..0f2de1d502c 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -267,9 +267,10 @@ if("human") new_mob = new /mob/living/carbon/human(M.loc) var/mob/living/carbon/human/H = new_mob - var/datum/preferences/A = new() //Randomize appearance for the human - A.species = get_random_species(TRUE) - A.copy_to(new_mob) + var/datum/character_save/S = new //Randomize appearance for the human + S.species = get_random_species(TRUE) + S.randomise() + S.copy_to(new_mob) randomize = H.dna.species.name else return diff --git a/code/modules/reagents/chemistry/reagents/disease.dm b/code/modules/reagents/chemistry/reagents/disease.dm index 1cd1111b49e..8e386386a2b 100644 --- a/code/modules/reagents/chemistry/reagents/disease.dm +++ b/code/modules/reagents/chemistry/reagents/disease.dm @@ -1,5 +1,5 @@ /datum/reagent/spider_eggs - name = "spider eggs" + name = "Spider eggs" id = "spidereggs" description = "A fine dust containing spider eggs. Oh gosh." reagent_state = SOLID @@ -124,7 +124,7 @@ return ..() /datum/reagent/bacon_grease - name = "pure bacon grease" + name = "Pure bacon grease" id = "bacon_grease" description = "Hook me up to an IV of that sweet, sweet stuff!" reagent_state = LIQUID @@ -185,30 +185,30 @@ taste_description = "watery milk" /datum/reagent/mutagen/mutagenvirusfood - name = "mutagenic agar" + name = "Mutagenic agar" id = "mutagenvirusfood" description = "mutates blood" color = "#A3C00F" // rgb: 163,192,15 /datum/reagent/mutagen/mutagenvirusfood/sugar - name = "sucrose agar" + name = "Sucrose agar" id = "sugarvirusfood" color = "#41B0C0" // rgb: 65,176,192 taste_mult = 1.5 /datum/reagent/medicine/diphenhydramine/diphenhydraminevirusfood - name = "virus rations" + name = "Virus rations" id = "diphenhydraminevirusfood" description = "mutates blood" color = "#D18AA5" // rgb: 209,138,165 /datum/reagent/plasma_dust/plasmavirusfood - name = "virus plasma" + name = "Virus plasma" id = "plasmavirusfood" description = "mutates blood" color = "#A69DA9" // rgb: 166,157,169 /datum/reagent/plasma_dust/plasmavirusfood/weak - name = "weakened virus plasma" + name = "Weakened virus plasma" id = "weakplasmavirusfood" color = "#CEC3C6" // rgb: 206,195,198 diff --git a/code/modules/reagents/chemistry/reagents/food.dm b/code/modules/reagents/chemistry/reagents/food.dm index 38430bc3dce..c3b8e40bfd6 100644 --- a/code/modules/reagents/chemistry/reagents/food.dm +++ b/code/modules/reagents/chemistry/reagents/food.dm @@ -447,7 +447,7 @@ return ..() /datum/reagent/consumable/flour - name = "flour" + name = "Flour" id = "flour" description = "This is what you rub all over yourself to pretend to be a ghost." reagent_state = SOLID @@ -852,7 +852,7 @@ return ..() | update_flags /datum/reagent/cholesterol - name = "cholesterol" + name = "Cholesterol" id = "cholesterol" description = "Pure cholesterol. Probably not very good for you." reagent_state = LIQUID diff --git a/code/modules/reagents/chemistry/reagents/misc.dm b/code/modules/reagents/chemistry/reagents/misc.dm index e163bf5bf18..aa0fcf41a21 100644 --- a/code/modules/reagents/chemistry/reagents/misc.dm +++ b/code/modules/reagents/chemistry/reagents/misc.dm @@ -500,7 +500,7 @@ M.RemoveElement(/datum/element/waddling) /datum/reagent/royal_bee_jelly - name = "royal bee jelly" + name = "Royal bee jelly" id = "royal_bee_jelly" description = "Royal Bee Jelly, if injected into a Queen Space Bee said bee will split into two bees." color = "#00ff80" diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm index a6ce4bca815..0902782f704 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm @@ -1,5 +1,5 @@ /datum/reagent/phlogiston - name = "phlogiston" + name = "Phlogiston" id = "phlogiston" description = "It appears to be liquid fire." reagent_state = LIQUID @@ -36,7 +36,7 @@ return ..() /datum/reagent/phlogiston/firedust - name = "phlogiston dust" + name = "Phlogiston dust" id = "phlogiston_dust" description = "And this is solid fire. However that works." temp_fire = 1500 @@ -45,7 +45,7 @@ mob_burning = 3 // 15 /datum/reagent/napalm - name = "napalm" + name = "Napalm" id = "napalm" description = "A highly flammable jellied fuel." reagent_state = LIQUID diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm index 4256b27e762..b32ca3503f9 100644 --- a/code/modules/reagents/chemistry/reagents/toxins.dm +++ b/code/modules/reagents/chemistry/reagents/toxins.dm @@ -199,7 +199,7 @@ /datum/reagent/stable_mutagen name = "Stable mutagen" id = "stable_mutagen" - description = "Just the regular, boring sort of mutagenic compound. Works in a completely predictable manner." + description = "Just the regular, boring sort of mutagenic compound. Works in a completely predictable manner." reagent_state = LIQUID color = "#7DFF00" taste_description = "slime" @@ -233,7 +233,7 @@ data = B.data.Copy() /datum/reagent/uranium - name ="Uranium" + name = "Uranium" id = "uranium" description = "A silvery-white metallic chemical element in the actinide series, weakly radioactive." reagent_state = SOLID @@ -367,7 +367,7 @@ to_chat(H, "The blueish acidic substance stings[volume < 5 ? " you, but isn't concentrated enough to harm you" : null]!") /datum/reagent/acetic_acid - name = "acetic acid" + name = "Acetic acid" id = "acetic_acid" description = "A weak acid that is the main component of vinegar and bad hangovers." color = "#0080ff" diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index 7703e5594e1..bcb0395b94f 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -703,22 +703,6 @@ build_path = /obj/item/weaponcrafting/receiver category = list("hacked", "Security") -/datum/design/shotgun_slug - name = "Shotgun Slug" - id = "shotgun_slug" - build_type = AUTOLATHE - materials = list(MAT_METAL = 4000) - build_path = /obj/item/ammo_casing/shotgun - category = list("hacked", "Security") - -/datum/design/buckshot_shell - name = "Buckshot shell" - id = "buckshot_shell" - build_type = AUTOLATHE - materials = list(MAT_METAL = 4000) - build_path = /obj/item/ammo_casing/shotgun/buckshot - category = list("hacked", "Security") - /datum/design/shotgun_dart name = "Shotgun Dart" id = "shotgun_dart" diff --git a/goon/browserassets/css/browserOutput-dark.css b/goon/browserassets/css/browserOutput-dark.css index db879454cc4..bbee5d2625d 100644 --- a/goon/browserassets/css/browserOutput-dark.css +++ b/goon/browserassets/css/browserOutput-dark.css @@ -365,6 +365,7 @@ h1.alert, h2.alert {color: #FFF;} .greentext {color: #00FF00; font-size: 150%;} .redtext {color: #FF0000; font-size: 150%;} .bold {font-weight: bold;} +.his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;} .center {text-align: center;} .red {color: #FF0000;} .purple {color: #9031C4;} diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css index f2de7748945..cc6ed7fdcb8 100644 --- a/goon/browserassets/css/browserOutput.css +++ b/goon/browserassets/css/browserOutput.css @@ -362,6 +362,7 @@ h1.alert, h2.alert {color: #000000;} .greentext {color: #00FF00; font-size: 150%;} .redtext {color: #FF0000; font-size: 150%;} .bold {font-weight: bold;} +.his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;} .center {text-align: center;} .red {color: #FF0000;} .purple {color: #5e2d79;} diff --git a/icons/_nanomaps/Delta_nanomap_z1.png b/icons/_nanomaps/Delta_nanomap_z1.png index d118a027d12..5517a6f9460 100644 Binary files a/icons/_nanomaps/Delta_nanomap_z1.png and b/icons/_nanomaps/Delta_nanomap_z1.png differ diff --git a/icons/mob/clothing/mask.dmi b/icons/mob/clothing/mask.dmi index 99be80fb681..4d3568caad8 100644 Binary files a/icons/mob/clothing/mask.dmi and b/icons/mob/clothing/mask.dmi differ diff --git a/icons/mob/clothing/species/drask/mask.dmi b/icons/mob/clothing/species/drask/mask.dmi index 27fa4502ad7..0795633a7c1 100644 Binary files a/icons/mob/clothing/species/drask/mask.dmi and b/icons/mob/clothing/species/drask/mask.dmi differ diff --git a/icons/mob/clothing/species/grey/mask.dmi b/icons/mob/clothing/species/grey/mask.dmi index 348a39c0f03..ae355aa8d51 100644 Binary files a/icons/mob/clothing/species/grey/mask.dmi and b/icons/mob/clothing/species/grey/mask.dmi differ diff --git a/icons/mob/clothing/species/plasmaman/mask.dmi b/icons/mob/clothing/species/plasmaman/mask.dmi index 73ff04e9288..1923e54a745 100644 Binary files a/icons/mob/clothing/species/plasmaman/mask.dmi and b/icons/mob/clothing/species/plasmaman/mask.dmi differ diff --git a/icons/mob/clothing/species/tajaran/mask.dmi b/icons/mob/clothing/species/tajaran/mask.dmi index f189a8d950d..337953a805b 100644 Binary files a/icons/mob/clothing/species/tajaran/mask.dmi and b/icons/mob/clothing/species/tajaran/mask.dmi differ diff --git a/icons/mob/clothing/species/unathi/mask.dmi b/icons/mob/clothing/species/unathi/mask.dmi index 2e29c80faf2..163fdc75628 100644 Binary files a/icons/mob/clothing/species/unathi/mask.dmi and b/icons/mob/clothing/species/unathi/mask.dmi differ diff --git a/icons/mob/clothing/species/vox/mask.dmi b/icons/mob/clothing/species/vox/mask.dmi index a875b7205a5..5e877739fab 100644 Binary files a/icons/mob/clothing/species/vox/mask.dmi and b/icons/mob/clothing/species/vox/mask.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index 50f0045f9b7..7f59cb75a0f 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 fa6e4b84054..09cdb2e80f3 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/robot_items.dmi b/icons/mob/robot_items.dmi index d84a6c291c1..aada2e5c8b7 100644 Binary files a/icons/mob/robot_items.dmi and b/icons/mob/robot_items.dmi differ diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi index 367a42a6c79..9ef222c0bff 100644 Binary files a/icons/mob/screen_alert.dmi and b/icons/mob/screen_alert.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index 2c755f556ea..266db362dba 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index 33225545601..42e1f9fec25 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index 45adf5cc6e9..6ac7c19a6a3 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/paradise.dme b/paradise.dme index 7c5da49fd52..bf7b57fb723 100644 --- a/paradise.dme +++ b/paradise.dme @@ -851,6 +851,7 @@ #include "code\game\objects\items\documents.dm" #include "code\game\objects\items\flag.dm" #include "code\game\objects\items\hand_item.dm" +#include "code\game\objects\items\his_grace.dm" #include "code\game\objects\items\latexballoon.dm" #include "code\game\objects\items\misc.dm" #include "code\game\objects\items\mixing_bowl.dm" @@ -1023,7 +1024,6 @@ #include "code\game\objects\items\weapons\implants\implantuplink.dm" #include "code\game\objects\items\weapons\melee\energy.dm" #include "code\game\objects\items\weapons\melee\misc.dm" -#include "code\game\objects\items\weapons\storage\artistic_toolbox.dm" #include "code\game\objects\items\weapons\storage\backpack.dm" #include "code\game\objects\items\weapons\storage\bags.dm" #include "code\game\objects\items\weapons\storage\belt.dm" @@ -1377,6 +1377,17 @@ #include "code\modules\client\client_procs.dm" #include "code\modules\client\message.dm" #include "code\modules\client\view.dm" +#include "code\modules\client\login_processing\10-load_preferences.dm" +#include "code\modules\client\login_processing\20-load_characters.dm" +#include "code\modules\client\login_processing\30-tos_consent.dm" +#include "code\modules\client\login_processing\35-donator_check.dm" +#include "code\modules\client\login_processing\36-watchlist.dm" +#include "code\modules\client\login_processing\37-alts_ip.dm" +#include "code\modules\client\login_processing\38-alts_cid.dm" +#include "code\modules\client\login_processing\39-cid_count.dm" +#include "code\modules\client\login_processing\__client_login_processor.dm" +#include "code\modules\client\preference\character.dm" +#include "code\modules\client\preference\link_processing.dm" #include "code\modules\client\preference\preferences.dm" #include "code\modules\client\preference\preferences_mysql.dm" #include "code\modules\client\preference\preferences_spawnpoints.dm" @@ -1417,6 +1428,7 @@ #include "code\modules\clothing\masks\breath.dm" #include "code\modules\clothing\masks\gasmask.dm" #include "code\modules\clothing\masks\miscellaneous.dm" +#include "code\modules\clothing\masks\voicemodulator.dm" #include "code\modules\clothing\patreon\glasses.dm" #include "code\modules\clothing\patreon\hats.dm" #include "code\modules\clothing\shoes\colour.dm" @@ -2091,7 +2103,6 @@ #include "code\modules\mob\new_player\login.dm" #include "code\modules\mob\new_player\logout.dm" #include "code\modules\mob\new_player\new_player.dm" -#include "code\modules\mob\new_player\preferences_setup.dm" #include "code\modules\mob\new_player\sprite_accessories\sprite_accessories.dm" #include "code\modules\mob\new_player\sprite_accessories\diona\diona_hair.dm" #include "code\modules\mob\new_player\sprite_accessories\drask\drask_body_markings.dm" diff --git a/sound/effects/his_grace_ascend.ogg b/sound/effects/his_grace_ascend.ogg new file mode 100644 index 00000000000..61866f2afc9 Binary files /dev/null and b/sound/effects/his_grace_ascend.ogg differ diff --git a/sound/effects/pope_entry.ogg b/sound/effects/pope_entry.ogg new file mode 100644 index 00000000000..54cf14fc4fc Binary files /dev/null and b/sound/effects/pope_entry.ogg differ diff --git a/strings/chemistry_tools.json b/strings/chemistry_tools.json index 5bf45fc6e58..f7f97ab198d 100644 --- a/strings/chemistry_tools.json +++ b/strings/chemistry_tools.json @@ -373,7 +373,6 @@ "mutagen", "pancuronium", "radium", - "uranium", "polonium", "sodium_thiopental", "triplepiss",