diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index c33487d0394..9af8a0e261d 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -246,6 +246,7 @@ CREATE TABLE `player` ( `sound` mediumint(8) DEFAULT '31', `randomslot` tinyint(1) DEFAULT '0', `volume` smallint(4) DEFAULT '100', + `nanoui_fancy` smallint(4) DEFAULT '1', PRIMARY KEY (`id`), UNIQUE KEY `ckey` (`ckey`) ) ENGINE=InnoDB AUTO_INCREMENT=32446 DEFAULT CHARSET=latin1; diff --git a/SQL/paradise_schema_prefixed.sql b/SQL/paradise_schema_prefixed.sql index d4d75838020..e2ea56d7582 100644 --- a/SQL/paradise_schema_prefixed.sql +++ b/SQL/paradise_schema_prefixed.sql @@ -246,6 +246,7 @@ CREATE TABLE `SS13_player` ( `sound` mediumint(8) DEFAULT '31', `randomslot` tinyint(1) DEFAULT '0', `volume` smallint(4) DEFAULT '100', + `nanoui_fancy` smallint(4) DEFAULT '1', PRIMARY KEY (`id`), UNIQUE KEY `ckey` (`ckey`) ) ENGINE=InnoDB AUTO_INCREMENT=32446 DEFAULT CHARSET=latin1; diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index 8f81531aa5b..91274e530ec 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -268,6 +268,7 @@ "afh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/decal/warning_stripes/southeastcorner,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/securearmoury) "afi" = (/obj/structure/rack,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/rig/security,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/rig/security,/obj/item/device/radio/intercom/department/security{pixel_x = -28},/turf/simulated/floor/plasteel{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/security/securearmoury) "afj" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/effect/decal/warning_stripes/south,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/securearmoury) +"afk" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/genetics) "afl" = (/obj/structure/rack,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/rig/security,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/rig/security,/turf/simulated/floor/plasteel{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/security/securearmoury) "afm" = (/turf/simulated/wall/r_wall,/area/security/securehallway) "afn" = (/obj/effect/spawner/window/reinforced,/obj/structure/disposalpipe/segment,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/security/hos) @@ -296,6 +297,7 @@ "afK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 1},/area/security/permabrig) "afL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 4},/area/security/permabrig) "afM" = (/turf/simulated/floor/plasteel{icon_state = "red"; dir = 5},/area/security/permabrig) +"afN" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/obj/effect/landmark/start{name = "Civilian"},/turf/simulated/floor/plating,/area/maintenance/genetics) "afO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/door/window/brigdoor{dir = 2; name = "Secure Armory"; req_access_txt = "3"},/obj/machinery/door/window/brigdoor{dir = 1; name = "Secure Armory"; req_access_txt = "3"},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/securearmoury) "afP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/effect/spawner/window/reinforced,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/security/securearmoury) "afQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/spawner/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/securearmoury) @@ -2993,9 +2995,9 @@ "bfE" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/structure/table,/obj/item/weapon/storage/box/lights/mixed,/obj/item/weapon/storage/toolbox/emergency,/turf/simulated/floor/plating,/area/storage/emergency2) "bfF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/storage/emergency2) "bfG" = (/obj/machinery/portable_atmospherics/canister/air,/obj/effect/decal/warning_stripes/white/hollow,/turf/simulated/floor/plating,/area/storage/emergency2) -"bfH" = (/obj/machinery/light_switch{pixel_x = -24},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor/plasteel{icon_state = "wood"},/area/civilian/pet_store) -"bfI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plasteel{icon_state = "wood"},/area/civilian/pet_store) -"bfJ" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1},/obj/item/device/radio/intercom{frequency = 1459; name = "station intercom (General)"; pixel_x = 28},/turf/simulated/floor/plasteel{icon_state = "wood"},/area/civilian/pet_store) +"bfH" = (/obj/machinery/light_switch{pixel_x = -24},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor/wood,/area/civilian/pet_store) +"bfI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/wood,/area/civilian/pet_store) +"bfJ" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1},/obj/item/device/radio/intercom{frequency = 1459; name = "station intercom (General)"; pixel_x = 28},/turf/simulated/floor/wood,/area/civilian/pet_store) "bfK" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/machinery/camera{c_tag = "Auxiliary Tool Storage"; dir = 2},/obj/structure/cable{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plasteel,/area/storage/tools) "bfL" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor/plasteel,/area/storage/tools) "bfM" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plasteel,/area/storage/tools) @@ -3063,9 +3065,9 @@ "bgW" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/extinguisher,/obj/item/weapon/extinguisher,/obj/item/weapon/extinguisher,/turf/simulated/floor/plating,/area/storage/emergency2) "bgX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/light/small,/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/storage/emergency2) "bgY" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/storage/emergency2) -"bgZ" = (/obj/structure/table/woodentable,/obj/machinery/fishtank/bowl,/turf/simulated/floor/plasteel{icon_state = "wood"},/area/civilian/pet_store) -"bha" = (/turf/simulated/floor/plasteel{icon_state = "wood"},/area/civilian/pet_store) -"bhb" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/plasteel{icon_state = "wood"},/area/civilian/pet_store) +"bgZ" = (/obj/structure/table/woodentable,/obj/machinery/fishtank/bowl,/turf/simulated/floor/wood,/area/civilian/pet_store) +"bha" = (/turf/simulated/floor/wood,/area/civilian/pet_store) +"bhb" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/wood,/area/civilian/pet_store) "bhc" = (/obj/structure/extinguisher_cabinet{pixel_x = -24},/turf/simulated/floor/plasteel,/area/storage/tools) "bhd" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/emergency,/turf/simulated/floor/plasteel,/area/storage/tools) "bhe" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/weapon/apc_electronics,/obj/item/weapon/airlock_electronics,/turf/simulated/floor/plasteel,/area/storage/tools) @@ -3146,9 +3148,9 @@ "biB" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1},/turf/simulated/floor/plasteel,/area/crew_quarters/locker) "biC" = (/obj/structure/closet/secure_closet/personal,/turf/simulated/floor/plasteel,/area/crew_quarters/locker) "biD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/storage/emergency2) -"biE" = (/obj/structure/table/woodentable,/obj/machinery/fishtank/bowl,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel{icon_state = "wood"},/area/civilian/pet_store) -"biF" = (/obj/machinery/light,/turf/simulated/floor/plasteel{icon_state = "wood"},/area/civilian/pet_store) -"biG" = (/obj/machinery/vending/crittercare,/turf/simulated/floor/plasteel{icon_state = "wood"},/area/civilian/pet_store) +"biE" = (/obj/structure/table/woodentable,/obj/machinery/fishtank/bowl,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/wood,/area/civilian/pet_store) +"biF" = (/obj/machinery/light,/turf/simulated/floor/wood,/area/civilian/pet_store) +"biG" = (/obj/machinery/vending/crittercare,/turf/simulated/floor/wood,/area/civilian/pet_store) "biH" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/plasteel,/area/storage/tools) "biI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/storage/tools) "biJ" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/storage/tools) @@ -3346,7 +3348,7 @@ "bmt" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/central/ne) "bmu" = (/obj/item/weapon/storage/box,/obj/structure/table,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "station intercom (General)"; pixel_y = 25},/turf/simulated/floor/plasteel{icon_state = "arrival"; dir = 1},/area/quartermaster/office) "bmv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/wood,/area/crew_quarters/bar) -"bmw" = (/turf/simulated/floor/plasteel{icon_state = "wood"},/area/crew_quarters/bar) +"bmw" = (/turf/simulated/floor/wood,/area/crew_quarters/bar) "bmx" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Kitchen"; req_access_txt = "28"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) "bmy" = (/obj/machinery/door_control{id = "kitchenbar"; name = "Kitchen Bar Shutters Control"; pixel_x = -6; pixel_y = -24; req_access_txt = "28"},/obj/machinery/door_control{id = "kitchenhall"; name = "Kitchen Hallway Shutters Control"; pixel_x = 6; pixel_y = -24; req_access_txt = "28"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) "bmz" = (/obj/machinery/power/apc{dir = 2; name = "Kitchen APC"; pixel_y = -24},/obj/structure/cable,/obj/machinery/light,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) @@ -3489,7 +3491,7 @@ "bpg" = (/obj/structure/sign/directions/evac{dir = 4},/obj/structure/sign/directions/medical{dir = 4; pixel_y = 7},/obj/structure/sign/directions/science{dir = 4},/turf/simulated/wall,/area/crew_quarters/bar) "bph" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Diner"},/turf/simulated/floor/plasteel,/area/crew_quarters/bar) "bpi" = (/obj/structure/sign/barsign,/turf/simulated/wall,/area/crew_quarters/bar) -"bpj" = (/obj/machinery/atm{pixel_x = 32; pixel_y = 0},/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel{icon_state = "wood"},/area/crew_quarters/bar) +"bpj" = (/obj/machinery/atm{pixel_x = 32; pixel_y = 0},/obj/structure/flora/kirbyplants,/turf/simulated/floor/wood,/area/crew_quarters/bar) "bpk" = (/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitecorner"},/area/hallway/primary/starboard/west) "bpl" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitecorner"},/area/hallway/primary/starboard/west) "bpm" = (/obj/machinery/camera{c_tag = "Starboard Primary Hallway 2"; dir = 2; network = list("SS13")},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitecorner"},/area/hallway/primary/starboard/west) @@ -4211,7 +4213,7 @@ "bDa" = (/obj/machinery/light_switch{name = "light switch "; dir = 2; pixel_x = 0; pixel_y = -22},/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/medical/morgue) "bDb" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/medical/morgue) "bDc" = (/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/medical/morgue) -"bDd" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/maintenance{req_access_txt = "9"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/storage/emergency) +"bDd" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/genetics) "bDe" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/assembly/chargebay) "bDf" = (/obj/machinery/camera{c_tag = "Research Mech Bay"; dir = 4; network = list("Research","SS13")},/obj/item/device/radio/intercom{dir = 8; name = "station intercom (General)"; pixel_x = -28},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel,/area/assembly/chargebay) "bDg" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel,/area/assembly/chargebay) @@ -4469,10 +4471,10 @@ "bHY" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay2) "bHZ" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/medical/research_shuttle_dock) "bIa" = (/obj/machinery/door/airlock/external{id_tag = "science_home"; name = "Shuttle Airlock"; req_access_txt = "65"},/turf/simulated/floor/plating,/area/medical/research_shuttle_dock) -"bIb" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/storage/emergency) -"bIc" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/effect/spawner/lootdrop/maintenance{lootcount = 2; name = "2maintenance loot spawner"},/turf/simulated/floor/plating,/area/storage/emergency) -"bId" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/storage/emergency) -"bIe" = (/turf/simulated/floor/plating,/area/storage/emergency) +"bIb" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/sortjunction{dir = 2; icon_state = "pipe-j2s"; sortType = 12},/turf/simulated/floor/plating,/area/maintenance/genetics) +"bIc" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/sortjunction{dir = 2; icon_state = "pipe-j2s"; sortType = 13},/turf/simulated/floor/plating,/area/maintenance/genetics) +"bId" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/genetics) +"bIe" = (/turf/simulated/floor/plating,/area/maintenance/genetics) "bIf" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/assembly/chargebay) "bIg" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/assembly/chargebay) "bIh" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plasteel,/area/assembly/chargebay) @@ -4579,9 +4581,9 @@ "bKe" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/airlock/glass_research{name = "Research Shuttle Dock"; req_access_txt = "65"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitepurplecorner"},/area/medical/research_shuttle_dock) "bKf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/medical/research_shuttle_dock) "bKg" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/shuttle/plating,/area/medical/research_shuttle_dock) -"bKh" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/maintenance{req_access_txt = "5"},/turf/simulated/floor/plasteel,/area/storage/emergency) -"bKi" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating,/area/storage/emergency) -"bKj" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/storage/emergency) +"bKh" = (/obj/machinery/power/apc{dir = 1; name = "Genetics Maintenance APC"; pixel_y = 24},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating,/area/maintenance/genetics) +"bKi" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/genetics) +"bKj" = (/obj/machinery/light/small{dir = 1},/obj/structure/disposalpipe/sortjunction{dir = 2; icon_state = "pipe-j2s"; sortType = 14},/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/genetics) "bKk" = (/obj/machinery/computer/shuttle/science,/turf/simulated/shuttle/floor,/area/shuttle/research) "bKl" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "swall_f5"; dir = 2},/area/shuttle/research) "bKm" = (/obj/machinery/door/firedoor{dir = 2},/obj/machinery/door/airlock/external{id_tag = "supply_home"; name = "Cargo Docking Hatch"; req_access_txt = "31"},/turf/simulated/floor/plating,/area/quartermaster/storage) @@ -4632,7 +4634,7 @@ "bLf" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/medical/genetics_cloning) "bLg" = (/turf/simulated/wall,/area/medical/genetics) "bLh" = (/turf/simulated/wall/r_wall,/area/medical/genetics) -"bLi" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/storage/emergency) +"bLi" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/maintenance{name = "Medbay Maintenance"; req_access_txt = "5"},/turf/simulated/floor/plasteel,/area/maintenance/genetics) "bLj" = (/turf/simulated/wall,/area/assembly/chargebay) "bLk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/assembly/chargebay) "bLl" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/assembly/robotics) @@ -4651,8 +4653,8 @@ "bLy" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/medical/research{name = "Research Division"}) "bLz" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/airlock/glass_research{name = "Research Shuttle Dock"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research_shuttle_dock) "bLA" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research_shuttle_dock) -"bLB" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/storage/emergency) -"bLC" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/airlock/maintenance{req_access_txt = "29"},/turf/simulated/floor/plasteel,/area/storage/emergency) +"bLB" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/genetics) +"bLC" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/genetics) "bLD" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating/airless,/area/medical/research_shuttle_dock) "bLE" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "swall_f9"; dir = 2},/area/shuttle/research) "bLF" = (/obj/machinery/door/airlock/external{id_tag = "s_docking_airlock"; name = "Shuttle Hatch"; req_access_txt = "31"},/turf/simulated/shuttle/floor,/area/shuttle/supply) @@ -4730,9 +4732,9 @@ "bMZ" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/crew_quarters/hor) "bNa" = (/turf/simulated/wall/r_wall,/area/crew_quarters/hor) "bNb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/crew_quarters/hor) -"bNc" = (/obj/machinery/light/small{dir = 1},/obj/structure/disposalpipe/sortjunction{dir = 2; icon_state = "pipe-j2s"; sortType = 14},/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/storage/emergency) -"bNd" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/storage/emergency) -"bNe" = (/obj/machinery/power/apc{dir = 1; name = "Starboard Emergency Storage APC"; pixel_y = 24},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating,/area/storage/emergency) +"bNc" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/genetics) +"bNd" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/genetics) +"bNe" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/airlock/maintenance{name = "Mech Bay Maintenance"; req_access_txt = "29"},/turf/simulated/floor/plasteel,/area/maintenance/genetics) "bNf" = (/obj/item/device/radio/intercom{name = "station intercom (General)"; pixel_y = -28},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research_shuttle_dock) "bNg" = (/obj/machinery/computer/shuttle/science,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/medical/research_shuttle_dock) "bNh" = (/obj/machinery/door/airlock/external{id_tag = "s_docking_airlock"; name = "External Hatch"; req_access_txt = "65"},/obj/docking_port/mobile{dwidth = 3; height = 5; id = "science"; name = "research shuttle"; width = 7},/obj/docking_port/stationary{dwidth = 3; height = 5; id = "science_home"; name = "research dock"; width = 7},/turf/simulated/shuttle/floor,/area/shuttle/research) @@ -4980,7 +4982,7 @@ "bRP" = (/obj/structure/rack{dir = 1},/obj/item/weapon/pickaxe{pixel_x = 5},/obj/item/weapon/shovel{pixel_x = -5},/obj/item/weapon/storage/belt/utility,/turf/simulated/floor/plasteel,/area/quartermaster/miningdock) "bRQ" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/device/megaphone,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/quartermaster/qm) "bRR" = (/obj/structure/table,/obj/item/weapon/folder/yellow,/obj/item/weapon/pen{pixel_x = 4; pixel_y = 4},/obj/item/weapon/pen/red{pixel_x = 2; pixel_y = 6},/turf/simulated/floor/plasteel,/area/quartermaster/qm) -"bRS" = (/obj/structure/table,/obj/item/weapon/clipboard,/obj/item/weapon/stamp/granted{name = "Quartermaster's stamp"; pixel_x = 0; pixel_y = 0},/turf/simulated/floor/plasteel,/area/quartermaster/qm) +"bRS" = (/obj/structure/table,/obj/item/weapon/clipboard,/obj/item/weapon/stamp/qm,/obj/item/weapon/stamp/granted{pixel_x = -4; pixel_y = 4},/obj/item/weapon/stamp/denied{pixel_x = 4; pixel_y = -4},/turf/simulated/floor/plasteel,/area/quartermaster/qm) "bRT" = (/obj/structure/disposalpipe/segment,/obj/machinery/camera{c_tag = "Quartermaster's Office"; dir = 8},/turf/simulated/floor/plasteel,/area/quartermaster/qm) "bRU" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=AIW"; location = "QM"},/turf/simulated/floor/plasteel,/area/hallway/primary/central/sw) "bRV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/hallway/primary/central/sw) @@ -5798,7 +5800,7 @@ "chB" = (/obj/structure/closet,/obj/machinery/light/small{dir = 4},/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/asmaint) "chC" = (/obj/effect/decal/cleanable/fungus,/turf/simulated/wall,/area/maintenance/asmaint) "chD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/asmaint) -"chE" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/maintenance{name = "Medbay Maintenance Access"; req_access_txt = "5"},/turf/simulated/floor/plating,/area/maintenance/asmaint) +"chE" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/maintenance/genetics) "chF" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 8},/area/medical/sleeper) "chG" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/turf/simulated/floor/plasteel,/area/medical/sleeper) "chH" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel{dir = 4; icon_state = "blue"},/area/medical/sleeper) @@ -5892,7 +5894,7 @@ "cjr" = (/obj/structure/extinguisher_cabinet,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/wall/r_wall,/area/medical/biostorage) "cjs" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{id_tag = null; name = "Secondary Storage"; req_access_txt = "39"},/turf/simulated/floor/plasteel,/area/medical/biostorage) "cjt" = (/obj/structure/sign/biohazard,/turf/simulated/wall/r_wall,/area/medical/biostorage) -"cju" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/maintenance{name = "Medbay Maintenance Access"; req_access_txt = "5"},/turf/simulated/floor/plating,/area/maintenance/asmaint) +"cju" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/effect/spawner/lootdrop/maintenance{lootcount = 2; name = "2maintenance loot spawner"},/turf/simulated/floor/plating,/area/maintenance/genetics) "cjv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"},/turf/simulated/wall,/area/medical/medbay2) "cjw" = (/obj/machinery/light,/obj/structure/table,/obj/item/stack/packageWrap,/obj/item/weapon/hand_labeler,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/explab) "cjx" = (/obj/machinery/power/apc{cell_type = 5000; dir = 2; name = "E.X.P.E.R.I-MENTOR Lab APC"; pixel_y = -24},/obj/structure/cable,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table,/obj/item/weapon/folder,/obj/item/weapon/folder,/obj/item/device/radio,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/explab) @@ -6085,7 +6087,7 @@ "cnc" = (/obj/machinery/light{dir = 8},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research_shuttle_dock) "cnd" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/medical/research_shuttle_dock) "cne" = (/obj/machinery/camera{c_tag = "Research Shuttle Dock"; dir = 2; network = list("SS13","Research")},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cmo"},/area/medical/research_shuttle_dock) -"cnf" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/storage/emergency) +"cnf" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/genetics) "cng" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 1; name = "Science Maintenance APC"; pixel_y = 24},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "cnh" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/ward) "cni" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{tag = "icon-whiteblue (SOUTHEAST)"; icon_state = "whiteblue"; dir = 6},/area/medical/medbay2) @@ -6221,7 +6223,7 @@ "cpI" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "surgeryobs1"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/surgery) "cpJ" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "surgeryobs2"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/surgery) "cpK" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Operating Theatre"; req_access_txt = "45"},/obj/machinery/holosign/surgery{id = "surgery2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) -"cpL" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/obj/effect/landmark/start{name = "Civilian"},/turf/simulated/floor/plating,/area/storage/emergency) +"cpL" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/maintenance{name = "Genetics Maintenance"; req_access_txt = "9"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/maintenance/genetics) "cpM" = (/turf/simulated/wall/r_wall,/area/medical/surgery) "cpN" = (/turf/simulated/floor/plasteel,/area/medical/biostorage) "cpO" = (/obj/structure/closet/l3closet,/obj/item/clothing/mask/gas,/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 10},/area/medical/biostorage) @@ -6276,7 +6278,7 @@ "cqL" = (/obj/machinery/bodyscanner,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) "cqM" = (/obj/machinery/body_scanconsole,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) "cqN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) -"cqO" = (/obj/machinery/door/airlock{name = "Starboard Emergency Storage"; req_access_txt = "0"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/storage/emergency) +"cqO" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/maintenance{name = "Medbay Maintenance"; req_access_txt = "5"},/turf/simulated/floor/plating,/area/maintenance/asmaint) "cqP" = (/obj/structure/table,/obj/item/weapon/storage/box/gloves,/obj/item/weapon/storage/box/masks,/obj/item/weapon/reagent_containers/spray/cleaner{desc = "Someone has crossed out the Space from Space Cleaner and written in Surgery. 'Do not remove under punishment of death!!!' is scrawled on the back."; name = "Surgery Cleaner"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/light_switch{pixel_x = 5; pixel_y = 27},/obj/machinery/holosign_switch{id = "surgery2"; pixel_x = -5; pixel_y = 27},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) "cqQ" = (/obj/machinery/light{dir = 8},/obj/structure/closet/wardrobe/pjs,/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitered"},/area/medical/medbay2) "cqR" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plating,/area/maintenance/asmaint2) @@ -6561,7 +6563,7 @@ "cwk" = (/obj/structure/table,/obj/item/weapon/hemostat,/obj/item/weapon/scalpel,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) "cwl" = (/obj/structure/table,/obj/item/weapon/hemostat,/obj/item/weapon/scalpel,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) "cwm" = (/obj/structure/table,/obj/item/weapon/surgicaldrill,/obj/item/stack/medical/advanced/bruise_pack,/obj/machinery/camera{c_tag = "Medbay Surgery 2 South"; dir = 1; network = list("SS13"); pixel_x = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) -"cwn" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/storage/emergency) +"cwn" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/maintenance{name = "Medbay Maintenance"; req_access_txt = "5"},/turf/simulated/floor/plating,/area/maintenance/asmaint) "cwo" = (/obj/structure/closet/secure_closet/medical2,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) "cwp" = (/turf/space,/area/maintenance/asmaint) "cwq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel,/area/hallway/primary/aft) @@ -6679,7 +6681,7 @@ "cyy" = (/obj/machinery/atmospherics/pipe/manifold/hidden/cyan{level = 2},/turf/simulated/floor/plasteel,/area/atmos/control) "cyz" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 9; level = 2},/turf/simulated/floor/plasteel,/area/atmos/control) "cyA" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/atmos/control) -"cyB" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/door/airlock/maintenance{req_access_txt = "24"},/turf/simulated/floor/plating,/area/maintenance/asmaint) +"cyB" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/door/airlock/maintenance{name = "Atmospherics Maintenance"; req_access_txt = "24"},/turf/simulated/floor/plating,/area/maintenance/asmaint) "cyC" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plating,/area/maintenance/asmaint) "cyD" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/floor/plating,/area/maintenance/asmaint) "cyE" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/floor/plating,/area/maintenance/asmaint) @@ -7744,6 +7746,7 @@ "cSX" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 4},/turf/space,/area/space) "cSY" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible/yellow{level = 2},/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 4},/turf/space,/area/space) "cSZ" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible/cyan{level = 2},/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 4},/turf/space,/area/space) +"cTa" = (/obj/machinery/door/airlock/maintenance{name = "Medbay Maintenance"; req_access_txt = "5"},/turf/simulated/floor/plating,/area/maintenance/asmaint) "cTb" = (/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk6"; icon_state = "catwalk6"},/area/space) "cTc" = (/obj/machinery/power/emitter,/turf/simulated/floor/plating,/area/storage/secure) "cTd" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering) @@ -8070,8 +8073,6 @@ "cZn" = (/obj/structure/rack,/obj/effect/spawner/lootdrop/maintenance{lootcount = 2; name = "2maintenance loot spawner"},/obj/item/latexballon,/turf/simulated/floor/plating,/area/maintenance/asmaint) "cZo" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "cZp" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 8; icon_state = "twindow"; tag = ""},/obj/structure/window/reinforced/tinted{dir = 1},/obj/structure/window/reinforced/tinted{dir = 4; icon_state = "twindow"; tag = ""},/obj/structure/window/reinforced/tinted,/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"cZq" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/sortjunction{dir = 2; icon_state = "pipe-j2s"; sortType = 13},/turf/simulated/floor/plating,/area/storage/emergency) -"cZr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/sortjunction{dir = 2; icon_state = "pipe-j2s"; sortType = 12},/turf/simulated/floor/plating,/area/storage/emergency) "cZs" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 5},/obj/item/weapon/pen,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/turbine) "cZt" = (/obj/machinery/atmospherics/binary/valve,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/turbine) "cZu" = (/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/turbine) @@ -8223,7 +8224,6 @@ "dck" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel,/area/medical/patients_rooms) "dcl" = (/obj/structure/sign/securearea{pixel_x = -32},/turf/simulated/floor/plating,/area/maintenance/asmaint) "dcm" = (/turf/simulated/floor/plasteel{dir = 4; icon_state = "blue"},/area/medical/patients_rooms) -"dcn" = (/obj/machinery/door/airlock/maintenance{name = "Medbay Maintenance Access"; req_access_txt = "5"},/turf/simulated/floor/plating,/area/maintenance/asmaint) "dco" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/decal/warning_stripes/south,/turf/simulated/floor/plasteel,/area/engine/engineering) "dcp" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/effect/decal/warning_stripes/southeastcorner,/turf/simulated/floor/plasteel,/area/engine/engineering) "dcq" = (/obj/effect/decal/warning_stripes/south,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/medical/patients_rooms) @@ -8841,17 +8841,17 @@ bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbi bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaLyaCuaKzaKzaKzaDEaDEaDEaDEaDEaDEbtobpubgNbgNbgNbgNbgNbgNbpvbgNbgNbgNbejbejbpxblCbpybpzbosbpAblCdlEbpCbpBbcobnbbncbndbecbcobejbnfbngbpDbpEbpFboAbpFbngboCbpGbpHbpIbmubpKbpLbnmbpMbpNboIbpObpPbpQbpRbpSbpSbpRbpTbpUbmgbpVbnvbnvbpWbpXboTboSbnvbpYbmkbpZbqabqbbqcbqdbqebqbbqfbnAbqgbqhbqibqjbqkbqlbqmbqnbqnbqnbqnbqnbqnbqobqpbqqbqrbqnbqsbqnbqnbqnbqnbqnbqnbqnbqndcZbqubqvbqvbqvbqvbqvbqvbqwbqlbqxbqybqybqzbqAbqBbqAbqCbqAbqDbqEbqFbqAbqGbqHbqIbqJbqKbqKbqKbqKbqKbqKbqKbqLbqMbqNbqNbqNbqNbqObqNbqPbKnddHbPfddIbiibPfdlbbmKbmKbmKbmKddKbmKddKbmKbmKbmKddGbdBbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbtpbtqbtqbtqbtqbwpbwpbtqbtqbxZbikaabaInaLAaJtbzPbzObzRbzQbzQbzQbzQbzSbzUbzTbcsbdVbBFbrhblCblCblCbribotblCbcobcobcobcobnbbrjbrkbrlbcobrmbrnbngbrobrpboAbpFbrqbngboCbrrbpHbpIbpIbrsbrtbnmbrubpNboIbpObrvbrwbrxbrybrzbrAbpTbrBbmgbrCbpWbnvbrDbrEbrDbnvbpWbrFbnzbrGbqbbqbbqcbrHbqebqbbrIbnAbrJbqibqibqjbqkbqlbqnbqnbqnbqnbqnbqnbqnbrKbqnbqnbqnbqnbqnbqnbrLbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrNbrObrPbqKbqKbrQbmFbmFbmFbmFbmFbmGbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbrRbmFbrSbrTbatbatbatbatbatbatbatddLbaAbgKbaAbaAbaAbqUddMddOddNbdBddPbdBddPbdBddQddMddObqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbBGbDCbBHdjhbDDdjidjidjkdjjbtqbxZbjNaInaInaKBbrWbrXbrYbrXbrXbrXbrXbrZbsabsbbcsbcsbscbsdblCbmUbsebsfbpAblCbsgbshbsgbcobcobcobcobsibcobsjbskbngbslbsmbpFbsnbsobngboCbnmbspbpIbpIbpIbsqbnmbsrbpNboIbpObssbrwbrxbstbsubrAbpTbsvbmgbswbsxbnvbsybszbsAboSbsBbsCbsDbsEbsFbsGbsHbsIbsJbqbbsKbnAbsLbsMbqibqjbqkbqlbqnbsNbqnbqnbqnbqnbsObsPbsPbsPbsPbsQbqnbqnbqnbqnbsRbqnbsNbsSbqnbsTbsUbsVbqnbsWbsXbsXbsYbsZbtabtbbmFbmFbmFbmFbmFbmFbmFbtcbtdbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbtebtfbtfbtgddSddRddUddTddTddTddTddVddWbaAaabbikbikaabbqUddXddZddYdeabqUbikbqUdecdebdecdecbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbBGbDCdjldjidjidjidjidjidjidjideHdjnaGddjnaJrbtrbrXbtsbttbtubtvbtwbrZbtxbtybtzbtzbtAbtBblCblCblCbosbtCborbcsbcsbcsbcsbtDbejbejbskbejbsjbskbngbtEbtFbtGbtHboAbngbtIbnmbtJbpIbpIbpIbtKbtLbtMbpNbtNbnqbtObtPbpRbpRbpRbpRbpTbtQbmgbtRbtSbmgbmgbmgbmgbmgbmgbmgbnzbnAbtTbtUbtVbtWbtXbtYbtZbnAbvubuabuabucbucbucbucbucbucbucbudbudbuebufbugbugbufbuebudbudbuhbuhbuhbuhbuhbuhbuibuibujbuibuibuibuibuibukcqObumbunbmFbmFbuobuobupbupbupbupbupbuqbtfbtfbtebtfbmFbtfbtfbtfbtfburbusbusbusbusdedbuubuubuubuubuubuubuubuubuubikbikbikbikbdBddYddYddYdeebqUbikbqUdefdebdebdegbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbBGbDCdjodjpdjpdjidjpdjpdjpbtqdjqaInaInaInaKBbuvbrXbuwbuxbuxbuxbuybrZbejbuzbuAbuBbuCbuDblCbmUbuEbosbuFborbuGbuHbuIbuJbuKbuLbuLbuMbuLbuNbuObngbuPbuQbuRbuSbuTbuUbuVbnmbuWbpIbpIbuXbuYbuZbtMbpNbvabnqbvbbvcbvdbvebvfbvgbvhbnqbnqbvibvjbvkbvlbvmbvlbvnbvjbikbvobnAbvpbvqbvrbvsbtXbqbbvtbnAbxebvwbxfbucbvxbvybvzbvAbvBbvCbvDbvEbvFbvGbvHbvHbvGbvIbvJbvKbuhbvLbvMbvNbvObuhbvPbvQbvRbvSbvTbvUbvUbvVbukcpLbvXbvYbvZbvYbwabwabupbwbbwcbwdbupbwebwfbwebupbwgbtfburbusbwhbwibwhbusbwjbwkbusdeicngbxXbwobikbikbikbikbikbikbikbikbikbikbqUddXddZddYdejbqUbikbqUdekdekdekdekbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjrbtqbtqbtqbtqbtqbtqbtqbtqdjqbikbikaInbwqbdFbwrbrXbwsbrXbwtbuxbwubwvbrZbwwbwxbwybwzbuDblCblCblCblCblCblCbwAbwBbwCbwDbwEbngbngbngbngbngbngbngbwFbngbngbngbwGbngbwHbwIbwJbpIbpIbpIbwKbtLbwLbpNbwMbnqbwNbvcbnrbnrbnrbnqbwObnqbwPbwQbwRbwSbwTbwUbwVbwWbwXbwYbwZbnAbxabqbbxbbxcbtXbxdbqbbnAbzbbxgbANbucbxhbxibxjbxkbxlbxmbxnbvHbvHbvHbvHbvHbvHbvHbvHbxobxpbxqbxrbxsbxtbuhbxubxvbxwbxxbxybxzbxvbxAbukcnfbvXbxCbxDbxEbxFbxFbxGbxHbxIbxJbxKbxLbxMbxNbupbxObxPbxQbusbxRbxSbxTbxUbxUbxVbusbxWbxXbxYbwobikbikbikbikbikbikbikbikbikbikbDybtldemdemdemdenbikdeodepdepdepbtlbDzbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaLyaCuaKzaKzaInaInaInaInaInaInaInaKBaJrbyabrXbybbycbydbyebyebyfbygbyhbyibyibyjbykbtzbtzbtzbtzbtzbtzbylbymbymbynbyobngbypbyqbyrbysbytbyubyvbywbngbyxbyybyzbuVbtLbwJbpIbpIbyAbnmbnmbyBbyCbyDbyEbyFbyGbyHbyIbyJbyKbyLbyMbyNbyObwXbyPbyQbyPbyQbyRbwXbwYbySbyTbyUbyVbyWbyXbyYbyZbzabyTbAObvwbvwbucbzcbzdbzebzfbzgbucbxnbvHbvHbvHbvHbvHbvHbvHbzhbzibzjbzkbzlbxqbzmbuhbznbzobzpbxxbxAbxzbzqbzrbukcZrbztbzubzvbzvbzwbzxbzybzzbzAbzAbzAbzBbzAbzCbzDbzEbzFbzGbzHbzIbzJbzKbzKbzKbzLbusbzMbxXbzNbwobikbikbikbikbikbikbikbikbikbikbikbDyderderderbDzbikbDyderderderbDzbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaIndjtdjsdjuaIoaIoaIobdFaJraJrbrXbzVbrXbzWbzXbzYbzZbrXbcsbAabAabAbbAcbAbbAbbAbbAcbAbbcsbcsbngbngbngbAdbngbAebAebAebAebAebAebyvbAfbAgbAhbAibAjbAkbAlbAmbAnbAobApbAqbArbAsbAtbAubAvbAwbAwbAxbAybAzbAAbABbACbADbAEbvjbAFbwVbAGbwTbAHbvjbikbAIbAJbAKbALbAJbAJbAJbAJbAMbnAbCBbvwbCCbAPbAQbARbASbATbAUbucbAVbAWbAXbAYbAZbBabBbbBcbvHbBdbuhbBebzlbBfbBgbuhbBhbBibxwbxxbxAbxzbxvbxAbukcnfbvXbBjbBkbBlbBmbBnbBobBpbBqbBrbBsbBtbBubBvbupbBwbBxbBybusbBzbBAbBBbxUbBCbBDbusbzMbxXbBEbwobikbikbikbikaabaabaabaabaabaabaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaIndjwdjvdjuaJqaJqbBIbBJaJqbBKbrXbBLbycbBMbBNbBObBPbrXbikaabaabdetdesdesdesdesdesdeubikbikbBRbBSbBTbBUbBVbAebAebAebAebAebAebBWbBXbBYbBZbCabCbbCcbCdbnmbnmbCebCfbnmbnmbCgbChbCibCjbCkbClbClbCmbClbCnbCobCpbCqbAEbvjbCrbvlbvlbvlbCsbvjbikbAIbAJbCtbCubCvbCwbCxbCybCzbCAbEsbvwbEtbucbvxbCDbCEbCFbCGbCHbCIbCJbCKbCLbCMbCNbCObCPbCQbCRbCSbCTbzlbCUbCVbuhbCWbCXbCYbCZbDabDbbDcbvVbukcZqbDebDfbDgbDgbDhbDibDjbDkbDlbDmbDnbDobDpbDqbupbDrbBxbDsbusbDtbDubDvbxUbxUbDwbusbxWbxXbDxbwobikbikbikbikaabbDAbFfbDBbFfbDBbFfbFgaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaIndjudjubDEaInaInaLyaCubDFbDGbrXbDHbycbycbycbrXbrXbrXbikbikbikdewdevdevdexdevdevdewbikbikbBRbDIbAebDJbDKbDKbDKbDKbDKbDLbDMbDKbDNbDObDPbDQbDRbDSbDTbnmbDUbpIbDVbDWbtLbDXbDYbDZbCjbCjbCpbEabEbbEcbEdbEebCpbvibAEbvjbEfbEgbEhbqtbEjbvjbikbEkbAJbElbEmbEnbEobEpbEobEqbErbFWbvwbHBbucbEubEubEvbEwbExbEybEzbEAbEBbECbEDbEDbEEbEFbEGbEHbuhbCTbEIaJSbuhbuhbuibEKbELbEMbuibukbukbukbENcwnbvXbEPbBkbBlbEQbDgbDjbERbESbESbETbxJbEUbEVbEWbEXbxPbEYbusbEZbFabxUbFbbFcbFdbusbzMbFebwobwobikbikbikbikaabbFhbFjbFibGSbFkbGTbFhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydjydjydjydjAdjzdjydjydjydjydjBbikbikbikbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevdewbFnbBRbBRbFobFpbFqbFrbFrbFrbFpbAebyvbAfbAebAebAgbFsbFtbFubFvbFwbFxbFybpIbpIbFzbtLbDXbDYbFAbFBbFCbFDbFEbFFbFGbFHbFIbCpbFJbFKbwRbFLbFMbFNbFObFPbwXbwYbFQbAJbFRbFSbFTbEobFUbEobFVbErbJebvwbKObucbFYbFZbGabGbbGcbGdbGebGfbGgbGgbGhbGibGgbGgbGjbGkbGlbGmbGnbGobGpbGqbGrbGsbGtbGubGvbGwbNebIebNcbNdbvXbGBbGCbGDbGEbGFbxGbGGbESbESbGHbGIbEUbGJbupbGKbGKbGLbusbGMbGNbGObGPbxUbGQbusbzMbGRbwobikbikbikbikbikaabbGUbIybFibFkbFibKkbDBaabbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjCdjEdjDdjGdjFdjIdjHdjFdjJdjLdjKdjydjydjBbikbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevbGWbmrbNkbmrbGXbGYbGZbGYbGYbGYbGYbHabyvbAfbHbbngbngbHcbpIbAibFvbHdbtLbHebHfbHfbHgbHhbHibHjbHkbHlbHmbHnbHobHpbHqbHrbHsbCpbCqbAEbvjbEibHubHvbHwbHxbvjbikbEkbHybHzbHybHybHybHybHybHAbHybKPbvwbKObucbHCbHDbHDbHEbHFbEybHGbHHbHIbHJbHKbHLbHMbHIbHNbHObHPbHQbHRbHSbHTbHTbHUbHVbHWbHXbHYbKhbKibKjbLibLBbLCbIfbIfbIgbIhbIibxGbIjbxJbxJbIkbIlbEUbImbInbIobIpbIqbIrbIsbItbIubIvbIubusbusbIwbEXbGxbLDbLDbLDbLDbLDbGxbFhbFkbFibFkbFkbGTbFhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydjHdjHdjHdjMdjFdjNdjNdjFdjOdjHdjHdjQdjPdjydjBbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevbLFbKmbIAbKmbIBbAebFqbFrbFrbFrbAebAebyvbAfbICbIDbngbIEbpIbAibFvbIFbtLbIGbpIbrsbpIbIHbDXbvvbIIbHlbHmbIJbIKbILbIMbINbIObIPbIQbIRbISbISbITbIUbIVbvjbvjbikbEkbHybIWbIXbIYbIZbJabJbbJcbJdbMhbvwbKObCHbJfbJgbJhbJibJjbEybJkbJlbJmbJnbJobJpbJqbJrbJsbJtbJubJvbJwbJxbJybJzbJAbJBbJCbJDbJEbGwbIdbIebIbbIcbvYbJIbJJbJKbJLbJLbxGbJMbJNbJObxGbJPbEUbJQbxGbJRbJSbJTbJUbJVbJWbJXbJYbJZbKabKbbKcbKdbKebKfbKfbIxbJFbJHbKgbKlbFfbDBbNhbDBbFfbLEaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydjSdjRdjUdjTdjVdjFdjWdjHdjXdjHdjHdjHdjHdjHdjMdjFbikbikbikbikbikbikbikbikbikbikdewdeCdevdevdevcOfdewbFnbBRbBRdezbAebFqbAebAebAebAebAebyvbAfbICbKobngbKpbpIbKqbKrbpIbKsbpHbpIbpIbKtbtLbDXbvvbIIbHlbHmbCpbKubKvbKwbKxbKybKzbKAbKBbKCbKDbwXbKEbKFbwXbwYbwYbKGbHybKHbKIbKJbKKbKLbKLbKMbKNbMibvwbMjbucbEybKQbEubKRbKSbEybJkbKTbKUbKVbKWbKXbKYbKUbJkbKZbLabLbcchbLbbLcbLbbLdbLdbLebLfbLgbLhbLhbDdbLgbLgbLhbLhbLjbLkbLjbLjbxGbxGbxGbxGbxGbLlbLmbBobxGbLnbLobLpbLqbLqbLrbLsbLtbLubLvbLwbLxbLybLzbLAbLAbEObGAbHZbGxbGzbGzbGzbIabGxbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbBGbDCdjldjidjidjidjidjidjidjideHdjnaGddjnaJrbtrbrXbtsbttbtubtvbtwbrZbtxbtybtzbtzbtAbtBblCblCblCbosbtCborbcsbcsbcsbcsbtDbejbejbskbejbsjbskbngbtEbtFbtGbtHboAbngbtIbnmbtJbpIbpIbpIbtKbtLbtMbpNbtNbnqbtObtPbpRbpRbpRbpRbpTbtQbmgbtRbtSbmgbmgbmgbmgbmgbmgbmgbnzbnAbtTbtUbtVbtWbtXbtYbtZbnAbvubuabuabucbucbucbucbucbucbucbudbudbuebufbugbugbufbuebudbudbuhbuhbuhbuhbuhbuhbuibuibujbuibuibuibuibuibukafkbumbunbmFbmFbuobuobupbupbupbupbupbuqbtfbtfbtebtfbmFbtfbtfbtfbtfburbusbusbusbusdedbuubuubuubuubuubuubuubuubuubikbikbikbikbdBddYddYddYdeebqUbikbqUdefdebdebdegbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbBGbDCdjodjpdjpdjidjpdjpdjpbtqdjqaInaInaInaKBbuvbrXbuwbuxbuxbuxbuybrZbejbuzbuAbuBbuCbuDblCbmUbuEbosbuFborbuGbuHbuIbuJbuKbuLbuLbuMbuLbuNbuObngbuPbuQbuRbuSbuTbuUbuVbnmbuWbpIbpIbuXbuYbuZbtMbpNbvabnqbvbbvcbvdbvebvfbvgbvhbnqbnqbvibvjbvkbvlbvmbvlbvnbvjbikbvobnAbvpbvqbvrbvsbtXbqbbvtbnAbxebvwbxfbucbvxbvybvzbvAbvBbvCbvDbvEbvFbvGbvHbvHbvGbvIbvJbvKbuhbvLbvMbvNbvObuhbvPbvQbvRbvSbvTbvUbvUbvVbukafNbvXbvYbvZbvYbwabwabupbwbbwcbwdbupbwebwfbwebupbwgbtfburbusbwhbwibwhbusbwjbwkbusdeicngbxXbwobikbikbikbikbikbikbikbikbikbikbqUddXddZddYdejbqUbikbqUdekdekdekdekbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjrbtqbtqbtqbtqbtqbtqbtqbtqdjqbikbikaInbwqbdFbwrbrXbwsbrXbwtbuxbwubwvbrZbwwbwxbwybwzbuDblCblCblCblCblCblCbwAbwBbwCbwDbwEbngbngbngbngbngbngbngbwFbngbngbngbwGbngbwHbwIbwJbpIbpIbpIbwKbtLbwLbpNbwMbnqbwNbvcbnrbnrbnrbnqbwObnqbwPbwQbwRbwSbwTbwUbwVbwWbwXbwYbwZbnAbxabqbbxbbxcbtXbxdbqbbnAbzbbxgbANbucbxhbxibxjbxkbxlbxmbxnbvHbvHbvHbvHbvHbvHbvHbvHbxobxpbxqbxrbxsbxtbuhbxubxvbxwbxxbxybxzbxvbxAbukbDdbvXbxCbxDbxEbxFbxFbxGbxHbxIbxJbxKbxLbxMbxNbupbxObxPbxQbusbxRbxSbxTbxUbxUbxVbusbxWbxXbxYbwobikbikbikbikbikbikbikbikbikbikbDybtldemdemdemdenbikdeodepdepdepbtlbDzbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaLyaCuaKzaKzaInaInaInaInaInaInaInaKBaJrbyabrXbybbycbydbyebyebyfbygbyhbyibyibyjbykbtzbtzbtzbtzbtzbtzbylbymbymbynbyobngbypbyqbyrbysbytbyubyvbywbngbyxbyybyzbuVbtLbwJbpIbpIbyAbnmbnmbyBbyCbyDbyEbyFbyGbyHbyIbyJbyKbyLbyMbyNbyObwXbyPbyQbyPbyQbyRbwXbwYbySbyTbyUbyVbyWbyXbyYbyZbzabyTbAObvwbvwbucbzcbzdbzebzfbzgbucbxnbvHbvHbvHbvHbvHbvHbvHbzhbzibzjbzkbzlbxqbzmbuhbznbzobzpbxxbxAbxzbzqbzrbukbIbbztbzubzvbzvbzwbzxbzybzzbzAbzAbzAbzBbzAbzCbzDbzEbzFbzGbzHbzIbzJbzKbzKbzKbzLbusbzMbxXbzNbwobikbikbikbikbikbikbikbikbikbikbikbDyderderderbDzbikbDyderderderbDzbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaIndjtdjsdjuaIoaIoaIobdFaJraJrbrXbzVbrXbzWbzXbzYbzZbrXbcsbAabAabAbbAcbAbbAbbAbbAcbAbbcsbcsbngbngbngbAdbngbAebAebAebAebAebAebyvbAfbAgbAhbAibAjbAkbAlbAmbAnbAobApbAqbArbAsbAtbAubAvbAwbAwbAxbAybAzbAAbABbACbADbAEbvjbAFbwVbAGbwTbAHbvjbikbAIbAJbAKbALbAJbAJbAJbAJbAMbnAbCBbvwbCCbAPbAQbARbASbATbAUbucbAVbAWbAXbAYbAZbBabBbbBcbvHbBdbuhbBebzlbBfbBgbuhbBhbBibxwbxxbxAbxzbxvbxAbukbDdbvXbBjbBkbBlbBmbBnbBobBpbBqbBrbBsbBtbBubBvbupbBwbBxbBybusbBzbBAbBBbxUbBCbBDbusbzMbxXbBEbwobikbikbikbikaabaabaabaabaabaabaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaIndjwdjvdjuaJqaJqbBIbBJaJqbBKbrXbBLbycbBMbBNbBObBPbrXbikaabaabdetdesdesdesdesdesdeubikbikbBRbBSbBTbBUbBVbAebAebAebAebAebAebBWbBXbBYbBZbCabCbbCcbCdbnmbnmbCebCfbnmbnmbCgbChbCibCjbCkbClbClbCmbClbCnbCobCpbCqbAEbvjbCrbvlbvlbvlbCsbvjbikbAIbAJbCtbCubCvbCwbCxbCybCzbCAbEsbvwbEtbucbvxbCDbCEbCFbCGbCHbCIbCJbCKbCLbCMbCNbCObCPbCQbCRbCSbCTbzlbCUbCVbuhbCWbCXbCYbCZbDabDbbDcbvVbukbIcbDebDfbDgbDgbDhbDibDjbDkbDlbDmbDnbDobDpbDqbupbDrbBxbDsbusbDtbDubDvbxUbxUbDwbusbxWbxXbDxbwobikbikbikbikaabbDAbFfbDBbFfbDBbFfbFgaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaIndjudjubDEaInaInaLyaCubDFbDGbrXbDHbycbycbycbrXbrXbrXbikbikbikdewdevdevdexdevdevdewbikbikbBRbDIbAebDJbDKbDKbDKbDKbDKbDLbDMbDKbDNbDObDPbDQbDRbDSbDTbnmbDUbpIbDVbDWbtLbDXbDYbDZbCjbCjbCpbEabEbbEcbEdbEebCpbvibAEbvjbEfbEgbEhbqtbEjbvjbikbEkbAJbElbEmbEnbEobEpbEobEqbErbFWbvwbHBbucbEubEubEvbEwbExbEybEzbEAbEBbECbEDbEDbEEbEFbEGbEHbuhbCTbEIaJSbuhbuhbuibEKbELbEMbuibukbukbukbENbIdbvXbEPbBkbBlbEQbDgbDjbERbESbESbETbxJbEUbEVbEWbEXbxPbEYbusbEZbFabxUbFbbFcbFdbusbzMbFebwobwobikbikbikbikaabbFhbFjbFibGSbFkbGTbFhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydjydjydjydjAdjzdjydjydjydjydjBbikbikbikbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevdewbFnbBRbBRbFobFpbFqbFrbFrbFrbFpbAebyvbAfbAebAebAgbFsbFtbFubFvbFwbFxbFybpIbpIbFzbtLbDXbDYbFAbFBbFCbFDbFEbFFbFGbFHbFIbCpbFJbFKbwRbFLbFMbFNbFObFPbwXbwYbFQbAJbFRbFSbFTbEobFUbEobFVbErbJebvwbKObucbFYbFZbGabGbbGcbGdbGebGfbGgbGgbGhbGibGgbGgbGjbGkbGlbGmbGnbGobGpbGqbGrbGsbGtbGubGvbGwbKhbIebKjbKibvXbGBbGCbGDbGEbGFbxGbGGbESbESbGHbGIbEUbGJbupbGKbGKbGLbusbGMbGNbGObGPbxUbGQbusbzMbGRbwobikbikbikbikbikaabbGUbIybFibFkbFibKkbDBaabbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjCdjEdjDdjGdjFdjIdjHdjFdjJdjLdjKdjydjydjBbikbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevbGWbmrbNkbmrbGXbGYbGZbGYbGYbGYbGYbHabyvbAfbHbbngbngbHcbpIbAibFvbHdbtLbHebHfbHfbHgbHhbHibHjbHkbHlbHmbHnbHobHpbHqbHrbHsbCpbCqbAEbvjbEibHubHvbHwbHxbvjbikbEkbHybHzbHybHybHybHybHybHAbHybKPbvwbKObucbHCbHDbHDbHEbHFbEybHGbHHbHIbHJbHKbHLbHMbHIbHNbHObHPbHQbHRbHSbHTbHTbHUbHVbHWbHXbHYbLibLCbLBbNdbNcbNebIfbIfbIgbIhbIibxGbIjbxJbxJbIkbIlbEUbImbInbIobIpbIqbIrbIsbItbIubIvbIubusbusbIwbEXbGxbLDbLDbLDbLDbLDbGxbFhbFkbFibFkbFkbGTbFhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydjHdjHdjHdjMdjFdjNdjNdjFdjOdjHdjHdjQdjPdjydjBbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevbLFbKmbIAbKmbIBbAebFqbFrbFrbFrbAebAebyvbAfbICbIDbngbIEbpIbAibFvbIFbtLbIGbpIbrsbpIbIHbDXbvvbIIbHlbHmbIJbIKbILbIMbINbIObIPbIQbIRbISbISbITbIUbIVbvjbvjbikbEkbHybIWbIXbIYbIZbJabJbbJcbJdbMhbvwbKObCHbJfbJgbJhbJibJjbEybJkbJlbJmbJnbJobJpbJqbJrbJsbJtbJubJvbJwbJxbJybJzbJAbJBbJCbJDbJEbGwchEbIecnfcjubvYbJIbJJbJKbJLbJLbxGbJMbJNbJObxGbJPbEUbJQbxGbJRbJSbJTbJUbJVbJWbJXbJYbJZbKabKbbKcbKdbKebKfbKfbIxbJFbJHbKgbKlbFfbDBbNhbDBbFfbLEaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydjSdjRdjUdjTdjVdjFdjWdjHdjXdjHdjHdjHdjHdjHdjMdjFbikbikbikbikbikbikbikbikbikbikdewdeCdevdevdevcOfdewbFnbBRbBRdezbAebFqbAebAebAebAebAebyvbAfbICbKobngbKpbpIbKqbKrbpIbKsbpHbpIbpIbKtbtLbDXbvvbIIbHlbHmbCpbKubKvbKwbKxbKybKzbKAbKBbKCbKDbwXbKEbKFbwXbwYbwYbKGbHybKHbKIbKJbKKbKLbKLbKMbKNbMibvwbMjbucbEybKQbEubKRbKSbEybJkbKTbKUbKVbKWbKXbKYbKUbJkbKZbLabLbcchbLbbLcbLbbLdbLdbLebLfbLgbLhbLhcpLbLgbLgbLhbLhbLjbLkbLjbLjbxGbxGbxGbxGbxGbLlbLmbBobxGbLnbLobLpbLqbLqbLrbLsbLtbLubLvbLwbLxbLybLzbLAbLAbEObGAbHZbGxbGzbGzbGzbIabGxbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjZdjYdjHdjHdkadkadkadjFdjHdjHdjFdkbdkddkcdkfdkedkgdjFbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevbWobKmbIAbKmbFobLGbLHbAebAebAebLGbAebyvbAfbICbLIbngbLJbpIbAibFvbpIbnmbLKbpIbpIbLLbtLbDXbvvbLMbHlbLNbCpbLObLPbLQbLRbLSbKzbLTbLUbLVbLWbLXbLYbLZbMabikbikbikbHybMbbMcbMdbMdbMebMfbMgbHybNSbNRbKObNTbMkbMlbMmbMnbMobMpbMqbJlbMrbMsbMtbMubMvbMrbJkbKZbMwbMxbMybMzbMAbMBbLdbMCbMDbMEbLgbMFbMGbMHbMIbMJbMKbMLbKabMMbLqbLqbMNbMObLqbMPbMQbMRbMSbMTbLqbMUbiTbMWbMXbMYbMZbNabNbbNabNabNabIwbEXbGxbLDbLDbGxcnccndcnebOQbOSbUHbYdbGzbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkhdjYdjHdjHdjHdjHdjHdkidjHdjHdjFdjydjydjydjydjydjydkjbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevdeEdeDdeGdeDbNlbNmbNnbNnbNnbNnbNnbNobNpbNqbICbNrbngbNsbNtbNubNvbNwbNxbNybNybNybNzbNzbNAbvvbNBbNCbHmbCpbNDbNEbNFbKvbNGbKzbNHbNIbNJbNKbNLbFNbNMbMabikbikbikbHybNNbNObNPbNQbMebMfbMgbHybPibNUbQObPjbNVbNWbNXbNYbNZbOabObbOcbKUbKUbOdbOebKUbKUbJkbKZbOfbOgbOhbOibOjbOkbLdbOlbOmbOnbOobOpbOqbOrbOrbOsbOtbOubOvbOwbJVbJVbOxbJVbOybJVbOzbJVbOAbOBbOBbOCbODbOEbOFbOGbOHcsjbOJbOKbOLbNabOMbONbikbikbikbGxbORbJFbOPbOQbKgbOObNibGxbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkkdjydkmdkldkodkndjHdjFdjHdjHdjFdjHdkqdkpdkrbikbikbikbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevdewbFnbBRbBRbngbngbBRbBRbBRbBRbBRbngbngbBRbBRbBRbngbOVbOVbOVbOWbOVbNzbOXbOYbOZbPabNzbDXbvvbPbbPcbPcbCpbCpbCpbCpbCpbPdbKzbISbIRbPebNKbPgbPhbMabMabvjbvjbvjbHybHzbHybHybHybHybHybHybHybQPbvwbQQbPkbPlbPmbPnbPlbPlbPobPpbPqbPrbPsbPtbPubPvbPwbMqbPxbPybPzbPAbPBbPCbPDbPEbPFbPGbPHbPIbPJbPKbPLbMHbPMbLhbLhbPNbPObPNbPPbPQbPPbPPbPPbPRbPSbPTbPTbPUbPVbPWbPXbOFbPYbPZbQabQbbQcbQdbNabOMbONbikbikbikbGxbNfbNgbGxbKgbGxbGxbKgbGxbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik @@ -8866,8 +8866,8 @@ bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbi bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbYcbOTbYgbOTbZxbikaabbikbOVbOVbUIbUIbUIbOVbikbUTccAccBccCccDbZFccEccFbUVccGccHccIbYnccJccKccLccMccNccOccPbUZccQccRccSccTccUccUccUccUccVccWccXccYccYccZccZcdacdbcdcbVibPlcddcdecdfcdgcdhbYKcdicbtcdjcdkcdlcdmbSwcdncdocdpcffcdrcdrcdscdrcdrcdrcdtbVAcducdvcdwcdxcdycdzcdAcbPcdBcdCcdDcdEcdFcdCcdGcdHcdCcdIcdJbRBbPTbPTcdKcdLcdMcdNcdOcdPcdQcdRcdScdTcdUcdVcdWcdXcdYcdZceacebceaceccebcebcebcedceecefcegcehaabbikbikbikbikaabbikbikbikbikbikbikbikbWhbWhceibXZbXZbXZbXZbXZbXZbXZbXZbXZbXZbXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabcejbUTbUTbUTcekbUTbUTcelbUVcemcenceocepceqcercescetceucevcewccKcexceycezceAceBceBceBceBceCceDceEceFceGceFceHceIceJceKceLceMceNceOcePceQceRceSceTceUceVceWceXceYceZcfacfbcfccfgbMmbMmcfichOcgHceYchVcfjcfjcfkcfjcflcfmcfncfocbPcfpcfqcfrcfscfrcftcfucfvcdCbPTcfwbPTbPTcfxcfybZnbBxbEXbUAcfzbUAbUAcfAcfBcfCcfDcfEcebcfFcfGcfHcdUcfHcdUcfIcdUcdUbUAcfJcfKcfLcfMaabaabaabaabaabaabaabaabbikbikbikbikbikbWhbXZbXZbXZbXZbXZbXZcfNbXZcfObXZbXZbXZbXZbXZbWhbWhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikcejcfPcfQcfRbUTcfSbUVcfTcfUcfVbZHcfWcfXcfYbYpcfZcgacgbcfXcgccgdcgecgfcgfcggcghcgicgjcgkcglcgmbGycgnbVicgobGybGycgpcgqcgrcgscgtceQcgucgvcgwcgxcgycgzbMVcgBcgCcgzcgzcgDcgEcgEcgEcgEcgEcgGcgFciOcgJcgJcgKcgLcgMcgNcgOcgPcbPcgQcgRcgScgTcgScgUcgVcfrcgWcgXcgYbBxcgZbBxcfybZnbBxbEXchachbchcbUAbUAbUAbUAbUAchdcdUchechfcfIcdUchgcdUbZpcdUchhbUAchichjchkbUAaabbikbikbikbikaabbikbikbikbikbikbikbikbWhchlchlchlchlchlchlchmbXZchnchlcfObXZbXZbXZbXZbWhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikcejchochpchqbUTcfSchrchrchrchrchrchrbUZbUZbUZbUZbUZbUZbUZchschtchuchvchwchxchychychzchAcglbGybGychBchCchDbGybGybGychEchFchGceOchHchIchJcgEchKchLchMbSqchLchNcfdcfdcfdcjncjlcjlcjlcjlckacgIbSqclPchPchQchRchSchTchUclQcbPchWchXcfrchYcfrchZciacibciccidciecifbBxcigcfybZncihbEXbFeciicijcikbwobxXbxXbUAcilcimcinciocipciqcirciscitciucivbUAciwciycixcizbikbikbikbikaahbikbikbikbikbikbikbikbikciAbXXbXXbXXbXXbXXbXXbXXciBciCbXZbXZbXZbXZciDbYabWhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikcejcejcejcejbUTcfScejbikbikbikbikciEbaTciGciHciIciJciKciLciMciNcmPciPciQciRciSciSciTciUciVciWciWciWciWciXciWbGybGybPlciYciZcjacjbcjccjdchScjecjfcjgcjhcjicjjcjkcjlcfdcnicjpcjpcjpcjpckNclSckUcnjcjqcjrcjscjtcbAcjucjvcbPcjwcjxcjycjzcjAcfrcjBcbPcbPbEXcjCbEXbEXbEXcjDcjEcjFbEXbxXciicjGcjHbwobwobwobUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbikbikbikbikbikaabbikbikbikbikbikbikbikbWhccvccvccvccvccvccvcjIbXZccuccvcjJbXZbXZbXZbXZbWhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikcejchochpchqbUTcfSchrchrchrchrchrchrbUZbUZbUZbUZbUZbUZbUZchschtchuchvchwchxchychychzchAcglbGybGychBchCchDbGybGybGycqOchFchGceOchHchIchJcgEchKchLchMbSqchLchNcfdcfdcfdcjncjlcjlcjlcjlckacgIbSqclPchPchQchRchSchTchUclQcbPchWchXcfrchYcfrchZciacibciccidciecifbBxcigcfybZncihbEXbFeciicijcikbwobxXbxXbUAcilcimcinciocipciqcirciscitciucivbUAciwciycixcizbikbikbikbikaahbikbikbikbikbikbikbikbikciAbXXbXXbXXbXXbXXbXXbXXciBciCbXZbXZbXZbXZciDbYabWhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikcejcejcejcejbUTcfScejbikbikbikbikciEbaTciGciHciIciJciKciLciMciNcmPciPciQciRciSciSciTciUciVciWciWciWciWciXciWbGybGybPlciYciZcjacjbcjccjdchScjecjfcjgcjhcjicjjcjkcjlcfdcnicjpcjpcjpcjpckNclSckUcnjcjqcjrcjscjtcbAcwncjvcbPcjwcjxcjycjzcjAcfrcjBcbPcbPbEXcjCbEXbEXbEXcjDcjEcjFbEXbxXciicjGcjHbwobwobwobUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbUAbikbikbikbikbikaabbikbikbikbikbikbikbikbWhccvccvccvccvccvccvcjIbXZccuccvcjJbXZbXZbXZbXZbWhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikcAjbikaabaabcjKcjKcjKcjKcjKcjKcjLcjKbUTcelcjMbikcjNcjOcjPcjQcjRcjScjTcjUcjVcjWcjXcjYcjZcosckbckcckdckeckfckgckhciVckickjckjckjckkciWbGybGycklcklcklcklckmcklckncknckocklcklckpcklckqckrckscktcksclZaPKcmacmmcmlcmocmnckzckAckBckCckDckEckFcdccbPcbPckGcbPckHcbPckIckJckKcgnckLckMckvckOckPckQckRckSckPbxXciickTbxXbxXckVckWckXchabxXbxXbxXbxXbxXbxXbxXckYckZbONbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbWhbXZbXZbXZbXZbXZbXZcfNbXZcjJbXZbXZbXZbXZbXZbWhbWhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikclaclbclbclbclccldcleclfclgclhclicjLcljcelcjMbikclkcllclmclnclocjSclpclqclrclsciLcltcgdcoaciPcluchyclvchyclwclxclyclzclAclAclAclBciWbGybGycklclCclDclEclFclGclHclHclIclJclKclLclMclNclOcotcfhcpwcmpcmrcmqctbcsZcuoctcckDclVclWclXckzclYcmtcmscmbcmbcmccmdcmecmfcmgcmhcmfcmfcmfcmicmfcmfcmjcmucnpcnlcqRcoXcrGcqScrHcrHcrIcrHcrHcrHcrHcrJcrKcrHcrHcrHcrMcmvbxXbONbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbWhbWhceibXZbXZbXZbXZbXZbXZbXZbXZbXZbXZbXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikcmwcmxcmxcmxcmxcmycmzcmAcmBcmCcmCcmDcjKcmEcfScjMbikclkcmFcmGcmHcmIcmJcmKcmLcmIcmIcmMcmNcmOcpxcmQcmQcmRbHtchycmTcmUclyclAclAclAclAcmVciWbGybGycklcmWcmXcmYcmZcnacnbcnbbzsbvWbulbxBclHcnhcklcqQcfdcrLcjpcwscvxcwEcwCcxNcxIckDcnmcnncnockDbJGcumctecnqcnqcnqcnqcnqcnrcnscntcnucnvcnvcnwcnwcnvcnxcnycnzcnAcnBcnCcnDcnEcnCcnCcnCcnCcnCcnCcnCcnCcnCcnCcnCcnCcuncnFcnGbONbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikcaUbWhbWhchlchlbXZbXZbXZbXZbXZbXZbXZbXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik @@ -8881,7 +8881,7 @@ bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbi bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikadbabLcrjcrjcrjcrjcrjcrjcvFcvGcvGcvHctBcvIcrjcrmcvJcvKcvKcvLcvKcvMcvKcvKcvNcvOcvKcvKcvOcvOcvOcvKcvKcvKcvKcvPcvQcvRcvScvTcvUcvVcvWcvXcvWcvWcvWcvWcvZcwacwbcwccwdcsObGycvrcwecwfcwgcwhcwicwjcwkcpFcwlcwjcwmcqNcqKcwocpMbikbikbikdbFdbZdbYdcadbIdccdcbdbUczRdbycyObVibVicuscoAbikbikbikbikbikbikckPcwtcwucwvcwwcwxcwycwzcwAcwBczScwDckPcxOcBZcyPckPaabaabcwGcwHcwIcwJcwKcwLcwGbxXbxXcvzczfbwobikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGacGacGafxafxacGafxafxafxagiafxafxaabagiaqZbikaabaabcwNcwNcwNcrjcwOcwPcwQcwRcwScwTcwUcwVcwWcwXcwYcwZcxacxbcxccxdcxecxfcxgcvKcxfcxhcxicxjcxjcxkcvKcxlcxmcxncxocbkcxpcxqcxrcxscxtcxucxtcxvcxwcxxcxycxzcxAcsOcsOcvrcwecpMcpMcxBcpMcpMcxCcxDcxEcxEcxEcxFcxEcyUcpMbikbikbikdbFdbFdbFdbFdbFdbydcedcgdcfdbybGybGyczhcuscoAbikbikbikbikbikbikckPcxOcxPcxOcxQcxRcqUcxScwAcxTczicxTckPcxOcxOcMpckPaabbikcwGcxWcxXcwJcwJcxYcwGczjbxXcvzbzNczMbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGbikbikaabaabbikaabaabbikbikaabaabaabbikaqZbikbikbikaabaabcwNcrjcrjcrjcrjcrjcrjcrjcrjcybcwWcwXcyccydcyecyfcyfcyfcyfcygcyhcyicxjcyjcxjcxjcykcxjcylcymcyncyocxocbkcypcyqcmScxscyscytcyucxscyvcywcyxcyycyzcyAcyBcyCcyDcyEcyEcAaczUcAdcAccAeczTcALceJcAhbGycAMcoAcoAcoAcoAcoAbikbikbikbikdcidchdckdcjdbydclbVibVicuscoAcoAcoAcoAcoAbikbikckPcxOcxOcxOcyZczaczbczcczdcAicAOcAvckPcAVcAYcAWckPbikbikcwGczkcwJczlcwJczmcwGbxXbxXcvzczMbwobikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGbikczoczpczqbikczoczpczqbikczoczpczqaabczraabbikbikbikbikaabaabaabbikbikbikbikbikbikczscwWcwXcztcxjcykczucxjcxjcxjczvcxjcztcztcxjcxjcxjcxjczwczxcymczyctEczzcoacyqcyqczAcxsczBczCczDcxsczEctWczFczGczHczIczJczKbGyczLcdcczLbGycBacAZcBccBccBccBccBPcBNcBNcBNcBNcBNcBQcoAbikbikbikbikdcidchdckdcmdcnbGyckObVicusbGybGybGycgmcoAbikbikckPcwAcwAcwAcwAczWcqUczXczYczZcCfcAbckPcCGcCYcCIckPbikbikcwGcAfcAgcDLcwJcDNcwGcEdbxXcvzbwoaabaabaabaabbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGbikczoczpczqbikczoczpczqbikczoczpczqaabczraabbikbikbikbikaabaabaabbikbikbikbikbikbikczscwWcwXcztcxjcykczucxjcxjcxjczvcxjcztcztcxjcxjcxjcxjczwczxcymczyctEczzcoacyqcyqczAcxsczBczCczDcxsczEctWczFczGczHczIczJczKbGyczLcdcczLbGycBacAZcBccBccBccBccBPcBNcBNcBNcBNcBNcBQcoAbikbikbikbikdcidchdckdcmcTabGyckObVicusbGybGybGycgmcoAbikbikckPcwAcwAcwAcwAczWcqUczXczYczZcCfcAbckPcCGcCYcCIckPbikbikcwGcAfcAgcDLcwJcDNcwGcEdbxXcvzbwoaabaabaabaabbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGbikczocAkczqbikczocAkczqbikczocAkczqaabaabaabaabbikbikbikbikbikbikbikbikbikaabaabaabczscwWcwXcztcAlcxjcAmcAncAocAocyjcxjcztcApcxjcxjcxjcxjcAqcArcAscAtbZNcAucAPcAwcAxcAycxsczBcAzcAAcxscABctWcsOcACcsLcADcAEcAFcAGcAHcAIcAJcAGcAKcAGcAGcAGcoAcoAcoAcoAcoAcoAcoAcoAcEhcoAbikbikbikbikdcicBTdcqcBUdbycgmcFdbVicFmcFlcFlcFnbGycoAbikbikckPcwtcwucwvcAQcARczbcAScATcAUcFrcIScAXcGscIScGtckPbikbikcwGcwGcBbcCrcBdcwGcwGbwobxXcGycyJcyJcyJbwobikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaahbikbikbikafxaabczocAkczqbikczocAkczqaabczocAkczqaabbikbikaabaabaabaabaabbikbikbikbikbikaabbikbikczscwWcvKcBecxjcBfcBgcBhcBicBjcBicBkcBicBlcBmcxfcBncztcztczxcBocBpcBqcBrcBscBtcBucBvcBwcBxcBycBzcBAcBBcBCcBDcBDcBEcBFcBGcBHcBIcBJcBKcBLcBMcrecBOcHucHtcDPcDPcDPcDPcDPcDPcHvcoAcEhclUclUclUclUclUclUcjmbEJcjmcFfclUclUcoAcoAcoAcoAcusbGycoAbikbikckPcxOcBZcxOcCacxRcqUcCbcCccCdcCecqUcqUcCgcqUcChckPbikaabaabcwGcwGcCscwGcwGbikbwobxXcvzcyJcHycHxbwobikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikczocAkczqaabczocAkczqbikczocAkczqbikbikbikbikbikbikaabaabaabbikaabbikaabaabbikbikcybcCicvKcCjcCkcCkcClcvKcvKcvKcvKcvKcvKcvKcvKcvKcvKcvKcvKcvKcCmcCncCmcCocCmcrmcCpcCqcFbcCtcCtcCtcCucCvcBCcCwcCxcCycCzcCAcCBcBIcCCcCDcCEcCFcHzcCHcHAcCJaabcCKcCKcCKcCKcCKcHBcoAcHDcHCcIGcHHcIHctackycjocBWckuckycBXcCPcBYcCRcCQcoAcusbGycoAbikbikckPcxOcxOcxOcAQcCTczbcCUcCVcCWcCXcCZcCZcDacqUcDbckPaabaabbikbikbikcIKbikbikbikbwobxXcvzcyJbxXbxXbwobikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik diff --git a/_maps/map_files/cyberiad/z2.dmm b/_maps/map_files/cyberiad/z2.dmm index 3784519ff95..d41366bfd14 100644 --- a/_maps/map_files/cyberiad/z2.dmm +++ b/_maps/map_files/cyberiad/z2.dmm @@ -153,6 +153,8 @@ "cW" = (/obj/structure/stool/bed,/turf/unsimulated/floor{icon_state = "floorscorched2"},/area/prison/solitary) "cX" = (/obj/effect/decal/cleanable/blood,/turf/unsimulated/floor{name = "plating"},/area/prison/solitary) "cY" = (/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/weapon/gun/projectile/shotgun/automatic/combat,/obj/item/weapon/gun/projectile/shotgun/automatic/combat,/obj/item/weapon/gun/projectile/shotgun/automatic/combat,/turf/simulated/floor/engine,/area/shuttle/gamma/space) +"cZ" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/mousetraps,/obj/item/weapon/storage/box/trackimp,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) +"da" = (/obj/structure/table/reinforced,/obj/item/weapon/scalpel,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) "db" = (/turf/simulated/floor/holofloor{tag = "icon-carpet2-0 (EAST)"; icon_state = "carpet2-0"; dir = 4},/area/holodeck/source_theatre) "do" = (/obj/effect/landmark{name = "prisonwarp"},/turf/unsimulated/floor{name = "plating"},/area/prison/solitary) "dp" = (/turf/unsimulated/floor{icon_state = "floorgrime"},/area/prison/solitary) @@ -1135,8 +1137,6 @@ "HJ" = (/turf/unsimulated/floor{tag = "icon-redbluefull (WEST)"; icon_state = "redbluefull"; dir = 8},/area/tdome/tdomeobserve) "HK" = (/obj/machinery/vending/coffee,/turf/unsimulated/floor{tag = "icon-redbluefull (WEST)"; icon_state = "redbluefull"; dir = 8},/area/tdome/tdomeobserve) "HL" = (/obj/structure/table/reinforced,/obj/item/weapon/melee/classic_baton/telescopic,/obj/item/weapon/paper/Court,/obj/item/weapon/pen,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) -"HM" = (/obj/structure/table/reinforced,/obj/item/weapon/scalpel,/obj/item/weapon/storage/box/syndie_kit/mindslave,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) -"HN" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/mousetraps,/obj/item/weapon/storage/box/trackimp,/obj/item/weapon/storage/box/syndie_kit/imp_explosive,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) "HO" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/flashbangs,/obj/item/weapon/storage/box/flashes,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) "HP" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/grenades,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) "HQ" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/teargas,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) @@ -1435,7 +1435,7 @@ aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDtDwDwDwDwDAHeHfDADwDwDwDwDuaNEfDKDKDAaNaNEMDwHgHhHiDwEnaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNHjHjHjHjHkHjHjHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDtDAHlHmHnDAHoFvFvHpDAHqHrHsHpDwGaDKDKDAaNaNaNHtHuHvHwHtaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNHjHxHyHyHyHyHzHjHjHjHjHjHjHjHjHkHjHjHjHjHjHjHjHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNHAFvFvFvHBFvFvFvFvHCFvFvFvFvHCDKDKDKDAaNaNEMDwDwHDDwDwEnaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNHjHxHyHyHyHyHzHjHEHFHGHFHHHIHJHJHJHIHHHJHHHJHKHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDAHLHMHNDAGVFvFvGWDAHOHPHQGWDwEIDKDKDAaNaNaNEMaNaNaNEnaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNHjHxHyHyHyHyHzHjHEHFHGHFHHHIHJHJHJHIHHHJHHHJHKHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDAHLdacZDAGVFvFvGWDAHOHPHQGWDwEIDKDKDAaNaNaNEMaNaNaNEnaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNHjHRHyHyHyHyHSHjHJHTHTHTHTHTHJHJHJHTHTHTHTHTHUHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDwDwDwDwGZHVHWDADwDwDwDwEnaNDIDKDKDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNHjHRHXHYHYHyHyHZHJHJHJIaHJHJHJHJHJHJHJIaHJHJHJHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMaNaNEMDAGXIbDAEnaNaNaNaNaNEfDKDKDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNHjHjHjHjHjHjHjHjHJHTHTHTHTHTHJHJHJHTHTHTHTHTHJHjHjHjHjHjHjHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDwDwEnaNDtDxDyDyDzGaDKDKDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index 521349b02af..d3f4abef037 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -60,11 +60,12 @@ #define FEET_NOSLIP 4 #define HAS_HEAD_ACCESSORY 8 #define HAS_TAIL 16 -#define HAS_SKIN_TONE 32 -#define HAS_SKIN_COLOR 64 -#define HAS_MARKINGS 128 -#define TAIL_WAGGING 256 -#define NO_EYES 512 +#define TAIL_OVERLAPPED 32 +#define HAS_SKIN_TONE 64 +#define HAS_SKIN_COLOR 128 +#define HAS_MARKINGS 256 +#define TAIL_WAGGING 512 +#define NO_EYES 1024 //Species Diet Flags #define DIET_CARN 1 diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index f65f13f4f9f..4136771eef5 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -35,6 +35,7 @@ #define ROLE_SENTIENT "sentient animal" #define ROLE_POSIBRAIN "positronic brain" #define ROLE_GUARDIAN "guardian" +#define ROLE_MORPH "morph" //Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR. @@ -67,4 +68,5 @@ var/global/list/special_roles = list( ROLE_POSIBRAIN, ROLE_REVENANT, ROLE_GUARDIAN, + ROLE_MORPH, ) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index f821b19e665..03a684fc743 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -306,6 +306,22 @@ proc/isInSight(var/atom/A, var/atom/B) return candidates +/proc/get_candidate_ghosts(be_special_type, afk_bracket=3000, override_age=0, override_jobban=0) + var/roletext = get_roletext(be_special_type) + var/list/candidates = list() + // Keep looping until we find a non-afk candidate within the time bracket (we limit the bracket to 10 minutes (6000)) + while(!candidates.len && afk_bracket < 6000) + for(var/mob/dead/observer/G in player_list) + if(G.client != null) + if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD)) + if(!G.client.is_afk(afk_bracket) && (be_special_type in G.client.prefs.be_special)) + if(!override_jobban || (!jobban_isbanned(G, roletext) && !jobban_isbanned(G,"Syndicate"))) + if(override_age || player_old_enough_antag(G.client,be_special_type)) + candidates += G + afk_bracket += 600 // Add a minute to the bracket, for every attempt + + return candidates + /proc/ScreenText(obj/O, maptext="", screen_loc="CENTER-7,CENTER-7", maptext_height=480, maptext_width=480) if(!isobj(O)) O = new /obj/screen/text() O.maptext = maptext diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index bd1d4dd579a..7c1e933bfcd 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -198,7 +198,6 @@ datum/hud/New(mob/owner) blob_hud() else if(mymob.mind && mymob.mind.vampire) vampire_hud() - human_hud('icons/mob/screen1_Vampire.dmi') else if(isswarmer(mymob)) swarmer_hud() else if(isguardian(mymob)) diff --git a/code/controllers/Processes/shuttles/supply.dm b/code/controllers/Processes/shuttles/supply.dm index 6be3d442030..a32ac4a3d0b 100644 --- a/code/controllers/Processes/shuttles/supply.dm +++ b/code/controllers/Processes/shuttles/supply.dm @@ -446,8 +446,8 @@ for(var/set_name in shuttle_master.requestlist) var/datum/supply_order/SO = set_name if(SO) - // Check if the usr owns the request, so they can cancel requests - var/obj/item/weapon/card/id/I = usr.get_id_card() + // Check if the user owns the request, so they can cancel requests + var/obj/item/weapon/card/id/I = user.get_id_card() var/owned = 0 if(I && SO.orderedby == I.registered_name) owned = 1 @@ -493,15 +493,16 @@ return 1 var/crates = 1 if(multi) - var/num_input = input(usr, "Amount:", "How many crates?", "") as num - crates = Clamp(round(text2num(num_input)), 1, 20) - if(..()) + var/num_input = input(usr, "Amount:", "How many crates?") as null|num + if(!num_input || ..()) return 1 + crates = Clamp(round(num_input), 1, 20) var/timeout = world.time + 600 - var/reason = sanitize(copytext(input(usr,"Reason:","Why do you require this item?","") as null|text, 1, MAX_MESSAGE_LEN)) + var/reason = input(usr,"Reason:","Why do you require this item?","") as null|text if(world.time > timeout || !reason || ..()) return 1 + reason = sanitize(copytext(reason, 1, MAX_MESSAGE_LEN)) var/idname = "*None Provided*" var/idrank = "*None Provided*" @@ -666,15 +667,16 @@ return 1 var/crates = 1 if(multi) - var/num_input = input(usr, "Amount:", "How many crates?", "") as num - crates = Clamp(round(text2num(num_input)), 1, 20) - if(!is_authorized(usr) || ..()) + var/num_input = input(usr, "Amount:", "How many crates?") as null|num + if(!num_input || !is_authorized(usr) || ..()) return 1 + crates = Clamp(round(num_input), 1, 20) var/timeout = world.time + 600 - var/reason = sanitize(copytext(input(usr,"Reason:","Why do you require this item?","") as null|text,1,MAX_MESSAGE_LEN)) + var/reason = input(usr,"Reason:","Why do you require this item?","") as null|text if(world.time > timeout || !reason || !is_authorized(usr) || ..()) return 1 + reason = sanitize(copytext(reason, 1, MAX_MESSAGE_LEN)) var/idname = "*None Provided*" var/idrank = "*None Provided*" diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 41019d29356..2c4273b2c23 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -140,14 +140,14 @@ proc/get_id_photo(var/mob/living/carbon/human/H) temp = new /icon(icobase, "head_[g]") preview_icon.Blend(temp, ICON_OVERLAY) - for(var/obj/item/organ/external/E in H.organs) - preview_icon.Blend(E.get_icon(), ICON_OVERLAY) - //Tail if(H.species.tail && H.species.flags & HAS_TAIL) temp = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[H.species.tail]_s") preview_icon.Blend(temp, ICON_OVERLAY) + for(var/obj/item/organ/external/E in H.organs) + preview_icon.Blend(E.get_icon(), ICON_OVERLAY) + // Skin tone if(H.species.bodyflags & HAS_SKIN_TONE) if (H.s_tone >= 0) diff --git a/code/datums/hud.dm b/code/datums/hud.dm index 7b76230864f..70a97f648f8 100644 --- a/code/datums/hud.dm +++ b/code/datums/hud.dm @@ -71,7 +71,13 @@ var/datum/atom_hud/huds = list( \ // for(var/datum/gang/G in ticker.mode.gangs) // gang_huds += G.ganghud - for(var/datum/atom_hud/hud in huds)//|gang_huds)) + var/serv_huds = list()//mindslaves and/or vampire thralls + if(ticker.mode) + for(var/datum/mindslaves/serv in (ticker.mode.vampires | ticker.mode.traitors)) + serv_huds += serv.thrallhud + + + for(var/datum/atom_hud/hud in (huds|serv_huds))//|gang_huds)) if(src in hud.hudusers) hud.add_hud_to(src) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 860ebdd01b9..6287bd5a1d7 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -60,6 +60,7 @@ var/antag_hud_icon_state = null //this mind's ANTAG_HUD should have this icon_state var/datum/atom_hud/antag/antag_hud = null //this mind's antag HUD + var/datum/mindslaves/som //stands for slave or master...hush.. var/rev_cooldown = 0 @@ -146,7 +147,7 @@ var/mob/living/carbon/human/H = current if (istype(current, /mob/living/carbon/human)) /** Impanted**/ - if(H.is_loyalty_implanted()) + if(isloyal(H)) text = "Loyalty Implant:Remove|Implanted
" else text = "Loyalty Implant:No Implant|Implant him!
" @@ -156,7 +157,7 @@ if (ticker.mode.config_tag=="revolution") text += uppertext(text) text = "[text]: " - if (H.is_loyalty_implanted()) + if (isloyal(H)) text += "LOYAL EMPLOYEE|headrev|rev" else if (src in ticker.mode.head_revolutionaries) text = "employee|HEADREV|rev" @@ -192,7 +193,7 @@ if (ticker.mode.config_tag=="cult") text = uppertext(text) text = "[text]: " - if (H.is_loyalty_implanted()) + if (isloyal(H)) text += "LOYAL EMPLOYEE|cultist" else if (src in ticker.mode.cult) text += "employee|CULTIST" @@ -306,7 +307,7 @@ if (ticker.mode.config_tag=="traitor" || ticker.mode.config_tag=="traitorchan") text = uppertext(text) text = "[text]: " - if (H.is_loyalty_implanted()) + if (isloyal(H)) text +="traitor|LOYAL EMPLOYEE" else if (src in ticker.mode.traitors) @@ -618,9 +619,9 @@ switch(href_list["implant"]) if("remove") for(var/obj/item/weapon/implant/loyalty/I in H.contents) - for(var/obj/item/organ/external/organs in H.organs) - if(I in organs.implants) - qdel(I) + if(I && I.implanted) + I.removed(H) + qdel(I) H << "\blue Your loyalty implant has been deactivated." log_admin("[key_name(usr)] has deactivated [key_name(current)]'s loyalty implant") message_admins("[key_name_admin(usr)] has deactivated [key_name_admin(current)]'s loyalty implant") @@ -628,9 +629,6 @@ var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 - var/obj/item/organ/external/affected = H.organs_by_name["head"] - affected.implants += L - L.part = affected H.sec_hud_set_implants() log_admin("[key_name(usr)] has given [key_name(current)] a loyalty implant") @@ -654,11 +652,6 @@ cult.memorize_cult_objectives(src) current << "\red The nanobots in the loyalty implant remove all thoughts about being in a cult. Have a productive day!" memory = "" - if(src in ticker.mode.traitors) - ticker.mode.traitors -= src - special_role = null - current << "\red The nanobots in the loyalty implant remove all thoughts about being a traitor to Nanotrasen. Have a nice day!" - log_admin("[key_name_admin(usr)] has de-traitor'ed [current].") else if (href_list["revolution"]) @@ -903,6 +896,9 @@ ticker.mode.vampires += src ticker.mode.grant_vampire_powers(current) ticker.mode.update_vampire_icons_added(src) + var/datum/mindslaves/slaved = new() + slaved.masters += src + src.som = slaved //we MIGT want to mindslave someone special_role = "Vampire" current << "Your powers are awoken. Your lust for blood grows... You are a Vampire!" log_admin("[key_name(usr)] has vampired [key_name(current)]") @@ -999,6 +995,9 @@ if("traitor") if(!(src in ticker.mode.traitors)) ticker.mode.traitors += src + var/datum/mindslaves/slaved = new() + slaved.masters += src + src.som = slaved //we MIGT want to mindslave someone special_role = "traitor" current << "\red You are a traitor!" log_admin("[key_name(usr)] has traitored [key_name(current)]") diff --git a/code/datums/spells/area_teleport.dm b/code/datums/spells/area_teleport.dm index 6a087a2a643..6041122fd98 100644 --- a/code/datums/spells/area_teleport.dm +++ b/code/datums/spells/area_teleport.dm @@ -26,6 +26,10 @@ var/area/thearea = teleportlocs[A] + if(thearea.tele_proof && !istype(thearea, /area/wizard_station)) + usr << "A mysterious force disrupts your arcane spell matrix, and you remain where you are." + return + return thearea /obj/effect/proc_holder/spell/targeted/area_teleport/cast(list/targets,area/thearea) diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 4fbb2271b1c..9c30b3305f0 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -720,9 +720,9 @@ var/list/uplink_items = list() /datum/uplink_item/device_tools/elite_hardsuit name = "Elite Syndicate Hardsuit" - desc = "The elite Syndicate hardsuit is worn by only the best nuclear agents. Features much better armoring and complete fireproofing, as well as a built in jetpack. \ - When the built in helmet is deployed your identity will be protected, even in death, as the suit cannot be removed by outside forces. Toggling the suit into combat mode \ - will allow you all the mobility of a loose fitting uniform without sacrificing armoring. Additionally the suit is collapsible, small enough to fit within a backpack. \ + desc = "The elite Syndicate hardsuit is worn by only the best nuclear agents. Features much better armoring and complete fireproofing. \ + When the built in helmet is deployed your identity will be protected. Toggling the suit into combat mode will allow you all the mobility \ + of a loose fitting uniform without sacrificing armoring. Additionally the suit is collapsible, small enough to fit within a backpack. \ Nanotrasen crewmembers are trained to report red space suit sightings; these suits in particular are known to drive employees into a panic." reference = "ESHS" item = /obj/item/weapon/storage/box/syndie_kit/elite_hardsuit @@ -875,18 +875,11 @@ var/list/uplink_items = list() cost = 14 surplus = 0 -/datum/uplink_item/implants/explosive - name = "Explosive Implant" - desc = "An implant injected into the body, and later activated using a vocal command to cause a large explosion from the implant." - reference = "EI" - item = /obj/item/weapon/implanter/explosive - cost = 12 - -/datum/uplink_item/implants/compression - name = "Compressed Matter Implant" - desc = "An implant injected into the body, and later activated using a bodily gesture to retrieve an item that was earlier compressed." - reference = "CI" - item = /obj/item/weapon/implanter/compressed +/datum/uplink_item/implants/storage + name = "Storage Implant" + desc = "An implant injected into the body, and later activated at the user's will. It will open a small subspace pocket capable of storing two items." + reference = "ESI" + item = /obj/item/weapon/implanter/storage cost = 8 /datum/uplink_item/implants/mindslave @@ -903,6 +896,15 @@ var/list/uplink_items = list() item = /obj/item/weapon/implanter/adrenalin cost = 8 +/datum/uplink_item/implants/microbomb + name = "Microbomb Implant" + desc = "An implant injected into the body, and later activated either manually or automatically upon death. The more implants inside of you, the higher the explosive power. \ + This will permanently destroy your body, however." + reference = "MBI" + item = /obj/item/weapon/implanter/explosive + cost = 2 + gamemodes = list(/datum/game_mode/nuclear) + // POINTLESS BADASSERY /datum/uplink_item/badass @@ -949,6 +951,14 @@ var/list/uplink_items = list() item = /obj/item/toy/syndicateballoon cost = 20 +/datum/uplink_item/implants/macrobomb + name = "Macrobomb Implant" + desc = "An implant injected into the body, and later activated either manually or automatically upon death. Upon death, releases a massive explosion that will wipe out everything nearby." + reference = "HAB" + item = /obj/item/weapon/implanter/explosive_macro + cost = 20 + gamemodes = list(/datum/game_mode/nuclear) + /*/datum/uplink_item/badass/random name = "Random Item" desc = "Picking this choice will send you a random item from the list. Useful for when you cannot think of a strategy to finish your objectives with." diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index b49d880fcab..c393a1d91cc 100644 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -902,6 +902,10 @@ var/list/ghostteleportlocs = list() name = "Waste Disposal" icon_state = "disposal" +/area/maintenance/genetics + name = "Genetics Maintenance" + icon_state = "asmaint" + /area/maintenance/electrical name = "Electrical Maintenance" diff --git a/code/game/gamemodes/antag_hud.dm b/code/game/gamemodes/antag_hud.dm index facf096b610..0b2ee9320de 100644 --- a/code/game/gamemodes/antag_hud.dm +++ b/code/game/gamemodes/antag_hud.dm @@ -1,20 +1,20 @@ /datum/atom_hud/antag hud_icons = list(SPECIALROLE_HUD,NATIONS_HUD) -/datum/atom_hud/antag/proc/join_hud(mob/M) +/datum/atom_hud/antag/proc/join_hud(mob/M,var/slave) if(!istype(M)) CRASH("join_hud(): [M] ([M.type]) is not a mob!") - if(M.mind.antag_hud) //note: please let this runtime if a mob has no mind, as mindless mobs shouldn't be getting antagged + if(M.mind.antag_hud && !slave) //note: please let this runtime if a mob has no mind, as mindless mobs shouldn't be getting antagged M.mind.antag_hud.leave_hud(M) if(!ismask(M))//FUCK YOU MASK OF NARNAR! add_to_hud(M) add_hud_to(M) M.mind.antag_hud = src -/datum/atom_hud/antag/proc/join_solo_hud(mob/M)//for non team antags and for observer huds +/datum/atom_hud/antag/proc/join_solo_hud(mob/M,var/slave)//for non team antags and for observer huds if(!istype(M)) CRASH("join_hud(): [M] ([M.type]) is not a mob!") - if(M.mind.antag_hud) //note: please let this runtime if a mob has no mind, as mindless mobs shouldn't be getting antagged + if(M.mind.antag_hud && !slave) //note: please let this runtime if a mob has no mind, as mindless mobs shouldn't be getting antagged M.mind.antag_hud.leave_hud(M) add_to_hud(M) M.mind.antag_hud = src @@ -74,3 +74,27 @@ for(var/datum/atom_hud/data/hud in huds) if(current in hud.hudusers) hud.remove_hud_from(current) + + +///Master Servent Datum Sytems,Based on TG Gang system// + +/datum/mindslaves + var/name = "ERROR" + var/list/datum/mind/masters = list() + var/list/datum/mind/serv = list() + var/datum/atom_hud/antag/thrallhud + var/icontype + +/datum/mindslaves/New(loc,mastername) + + name = mastername + thrallhud = new() + +/datum/mindslaves/proc/add_serv_hud(datum/mind/serv_mind,var/icon) + thrallhud.join_hud(serv_mind.current,1) + icontype = "hud[icon]" + ticker.mode.set_antag_hud(serv_mind.current,icontype) + +/datum/mindslaves/proc/leave_serv_hud(datum/mind/free_mind) + thrallhud.leave_hud(free_mind.current) + ticker.mode.set_antag_hud(free_mind.current,null) \ No newline at end of file diff --git a/code/game/gamemodes/autotraitor/autotraitor.dm b/code/game/gamemodes/autotraitor/autotraitor.dm index 06b09867e6e..a0059416276 100644 --- a/code/game/gamemodes/autotraitor/autotraitor.dm +++ b/code/game/gamemodes/autotraitor/autotraitor.dm @@ -92,9 +92,8 @@ if(ishuman(player.current)) var/mob/living/carbon/human/H = player.current for(var/obj/item/weapon/implant/loyalty/I in H.contents) - for(var/obj/item/organ/external/organs in H.organs) - if(I in organs.implants) - possible_traitors -= player + if(I && I.implanted) + possible_traitors -= player //message_admins("Live Players: [playercount]") //message_admins("Live Traitors: [traitorcount]") diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 0ec4d72b5de..87cc9c46b58 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -22,7 +22,7 @@ return 0 if(ishuman(mind.current)) var/mob/living/carbon/human/H = mind.current - if(H.is_loyalty_implanted()) + if(isloyal(H)) return 0 return 1 diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm index 07163cb3669..f45253262d1 100644 --- a/code/game/gamemodes/heist/heist.dm +++ b/code/game/gamemodes/heist/heist.dm @@ -113,12 +113,9 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' limb.status &= ~(ORGAN_DESTROYED | ORGAN_ROBOT) //Now apply cortical stack. - var/obj/item/organ/external/E = vox.get_organ("head") var/obj/item/weapon/implant/cortical/I = new(vox) I.imp_in = vox I.implanted = 1 - I.part = E - E.implants += I cortical_stacks += I vox.equip_vox_raider() diff --git a/code/modules/mob/living/simple_animal/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm similarity index 100% rename from code/modules/mob/living/simple_animal/borer.dm rename to code/game/gamemodes/miniantags/borer/borer.dm diff --git a/code/modules/events/borers.dm b/code/game/gamemodes/miniantags/borer/borer_event.dm similarity index 100% rename from code/modules/events/borers.dm rename to code/game/gamemodes/miniantags/borer/borer_event.dm diff --git a/code/modules/mob/living/simple_animal/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm similarity index 97% rename from code/modules/mob/living/simple_animal/bot_swarm/swarmer.dm rename to code/game/gamemodes/miniantags/bot_swarm/swarmer.dm index f4fb0bd59d1..99f0f98e256 100644 --- a/code/modules/mob/living/simple_animal/bot_swarm/swarmer.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm @@ -224,13 +224,21 @@ /obj/machinery/blackbox_recorder/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) S << "This machine has recorded large amounts of data on this structure and its inhabitants, it will be a useful resource to our masters in the future. Aborting. " - /obj/machinery/power/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) S << "Disrupting the power grid would bring no benefit to us. Aborting." /obj/machinery/gateway/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) S << "This bluespace source will be important to us later. Aborting." +/obj/machinery/cryopod/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) + S << "This cryogenic sleeper should be preserved, it will be a useful resource to our masters in the future. Aborting." + +/obj/structure/cryofeed/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) + S << "This cryogenic feed should be preserved, it will be a useful resource to our masters in the future. Aborting." + +/obj/machinery/computer/cryopod/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) + S << "This cryopod control computer should be preserved, it contains useful items and information about the inhabitants. Aborting." + /turf/simulated/wall/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) for(var/turf/T in range(1, src)) if(istype(T, /turf/space) || istype(T.loc, /area/space)) diff --git a/code/modules/mob/living/simple_animal/bot_swarm/swarmer_event.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer_event.dm similarity index 100% rename from code/modules/mob/living/simple_animal/bot_swarm/swarmer_event.dm rename to code/game/gamemodes/miniantags/bot_swarm/swarmer_event.dm diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm similarity index 100% rename from code/modules/mob/living/simple_animal/guardian/guardian.dm rename to code/game/gamemodes/miniantags/guardian/guardian.dm diff --git a/code/game/gamemodes/miniantags/morph/morph.dm b/code/game/gamemodes/miniantags/morph/morph.dm new file mode 100644 index 00000000000..378ef84990a --- /dev/null +++ b/code/game/gamemodes/miniantags/morph/morph.dm @@ -0,0 +1,183 @@ +#define MORPH_COOLDOWN 50 + +/mob/living/simple_animal/hostile/morph + name = "morph" + real_name = "morph" + desc = "A revolting, pulsating pile of flesh." + speak_emote = list("gurgles") + emote_hear = list("gurgles") + icon = 'icons/mob/animal.dmi' + icon_state = "morph" + icon_living = "morph" + icon_dead = "morph_dead" + speed = 2 + a_intent = "harm" + stop_automated_movement = 1 + status_flags = CANPUSH + pass_flags = PASSTABLE + ventcrawler = 2 + + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + + minbodytemp = 0 + maxHealth = 150 + health = 150 + environment_smash = 1 + melee_damage_lower = 20 + melee_damage_upper = 20 + see_in_dark = 8 + see_invisible = SEE_INVISIBLE_MINIMUM + idle_vision_range = 1 // Only attack when target is close + wander = 0 + attacktext = "glomps" + attack_sound = 'sound/effects/blobattack.ogg' + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/slab + + var/morphed = 0 + var/atom/movable/form = null + var/morph_time = 0 + + var/playstyle_string = "You are a morph, an abomination of science created primarily with changeling cells. \ + You may take the form of anything nearby by shift-clicking it. This process will alert any nearby \ + observers, and can only be performed once every five seconds. While morphed, you move faster, but do \ + less damage. In addition, anyone within three tiles will note an uncanny wrongness if examining you. \ + You can attack any item or dead creature to consume it - creatures will restore 1/3 of your max health. \ + Finally, you can restore yourself to your original form while morphed by shift-clicking yourself." + +/mob/living/simple_animal/hostile/morph/examine(mob/user) + if(morphed) + if(form) + form.examine(user) // Refactor examine to return desc so it's static? Not sure if worth it + // If the object you've disguised as has been deleted, your cover's probably blown + else + ..() + if(get_dist(user,src)<=3) + user << "It doesn't look quite right..." + else + ..() + return + +/mob/living/simple_animal/hostile/morph/proc/allowed(atom/movable/A) // make it into property/proc ? not sure if worth it + if(istype(A,/obj/screen)) + return 0 + if(istype(A,/obj/singularity)) + return 0 + if(istype(A,/mob/living/simple_animal/hostile/morph)) + return 0 + return 1 + +/mob/living/simple_animal/hostile/morph/proc/eat(atom/movable/A) + if(A && A.loc != src) + visible_message("[src] swallows [A] whole!") + A.forceMove(src) + return 1 + return 0 + +/mob/living/simple_animal/hostile/morph/ShiftClickOn(atom/movable/A) + if(morph_time <= world.time && !stat) + if(A == src) + restore() + return + if(istype(A) && allowed(A)) + assume(A) + else + src << "Your chameleon skin is still repairing itself!" + ..() + +/mob/living/simple_animal/hostile/morph/proc/assume(atom/movable/target) + morphed = 1 + form = target + visible_message("[src] suddenly twists and changes shape, becoming a copy of [target]!", \ + "You twist your body and assume the form of [target].") + + appearance = target.appearance + transform = initial(transform) + pixel_y = initial(pixel_y) + pixel_x = initial(pixel_x) + //Morphed is weaker + melee_damage_lower = 5 + melee_damage_upper = 5 + speed = 0 + + morph_time = world.time + MORPH_COOLDOWN + return + +/mob/living/simple_animal/hostile/morph/proc/restore() + if(!morphed) + return + morphed = 0 + form = null + + //anim(loc,src,'icons/mob/mob.dmi',,"morph",,src.dir) + + visible_message("[src] suddenly collapses in on itself, dissolving into a pile of green flesh!", \ + "You reform to your normal body.") + name = initial(name) + icon = initial(icon) + icon_state = initial(icon_state) + overlays.Cut() + + //Baseline stats + melee_damage_lower = initial(melee_damage_lower) + melee_damage_upper = initial(melee_damage_upper) + speed = initial(speed) + + morph_time = world.time + MORPH_COOLDOWN + +/mob/living/simple_animal/hostile/morph/handle_state_icons() + return + +/mob/living/simple_animal/hostile/morph/death(gibbed) + if(morphed) + visible_message("[src] twists and dissolves into a pile of green flesh!", \ + "Your skin ruptures! Your flesh breaks apart! No disguise can ward off de--") + restore() + if(gibbed) + for(var/atom/movable/AM in src) + AM.forceMove(loc) + if(prob(90)) + step(AM, pick(alldirs)) + ..(gibbed) + +/mob/living/simple_animal/hostile/morph/Aggro() // automated only + ..() + restore() + +/mob/living/simple_animal/hostile/morph/LoseAggro() + vision_range = idle_vision_range + +/mob/living/simple_animal/hostile/morph/AIShouldSleep(var/list/possible_targets) + . = ..() + if(.) + var/list/things = list() + for(var/atom/movable/A in view(src)) + if(allowed(A)) + things += A + var/atom/movable/T = pick(things) + assume(T) + +/mob/living/simple_animal/hostile/morph/AttackingTarget() + if(isliving(target)) // Eat Corpses to regen health + var/mob/living/L = target + if(L.stat == DEAD) + if(do_after(src, 30, target = L)) + if(eat(L)) + heal_overall_damage(50,50) + return + else if(istype(target,/obj/item)) // Eat items just to be annoying + var/obj/item/I = target + if(!I.anchored) + if(do_after(src,20, target = I)) + eat(I) + return + target.attack_animal(src) + +/mob/living/simple_animal/hostile/morph/update_action_buttons() //So all eaten objects are not counted every life + return \ No newline at end of file diff --git a/code/game/gamemodes/miniantags/morph/morph_event.dm b/code/game/gamemodes/miniantags/morph/morph_event.dm new file mode 100644 index 00000000000..4a65ba85d83 --- /dev/null +++ b/code/game/gamemodes/miniantags/morph/morph_event.dm @@ -0,0 +1,45 @@ +/datum/event/spawn_morph + var/key_of_morph + +/datum/event/spawn_morph/proc/get_morph(end_if_fail = 0) + key_of_morph = null + if(!key_of_morph) + var/list/candidates = get_candidates(ROLE_MORPH) + if(!candidates.len) + if(end_if_fail) + return 0 + return find_morph() + var/client/C = pick(candidates) + key_of_morph = C.key + if(!key_of_morph) + if(end_if_fail) + return 0 + return find_morph() + var/datum/mind/player_mind = new /datum/mind(key_of_morph) + player_mind.active = 1 + if(!xeno_spawn) + return find_morph() + var/mob/living/simple_animal/hostile/morph/S = new /mob/living/simple_animal/hostile/morph(pick(xeno_spawn)) + player_mind.transfer_to(S) + player_mind.assigned_role = "Morph" + player_mind.special_role = "Morph" + ticker.mode.traitors |= player_mind + S << S.playstyle_string + S << 'sound/magic/Mutate.ogg' + message_admins("[key_of_morph] has been made into morph by an event.") + log_game("[key_of_morph] was spawned as a morph by an event.") + return 1 + +/datum/event/spawn_morph/start() + get_morph() + + +/datum/event/spawn_morph/proc/find_morph() + message_admins("Attempted to spawn a morph but there was no players available. Will try again momentarily.") + spawn(50) + if(get_morph(1)) + message_admins("Situation has been resolved, [key_of_morph] has been spawned as a morph.") + log_game("[key_of_morph] was spawned as a morph by an event.") + return 0 + message_admins("Unfortunately, no candidates were available for becoming a morph. Shutting down.") + return kill() diff --git a/code/modules/mob/living/simple_animal/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm similarity index 100% rename from code/modules/mob/living/simple_animal/revenant/revenant.dm rename to code/game/gamemodes/miniantags/revenant/revenant.dm diff --git a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm similarity index 100% rename from code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm rename to code/game/gamemodes/miniantags/revenant/revenant_abilities.dm diff --git a/code/modules/mob/living/simple_animal/revenant/revenant_spawn_event.dm b/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm similarity index 100% rename from code/modules/mob/living/simple_animal/revenant/revenant_spawn_event.dm rename to code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm diff --git a/code/modules/mob/living/bloodcrawl.dm b/code/game/gamemodes/miniantags/slaughter/bloodcrawl.dm similarity index 100% rename from code/modules/mob/living/bloodcrawl.dm rename to code/game/gamemodes/miniantags/slaughter/bloodcrawl.dm diff --git a/code/modules/mob/living/simple_animal/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm similarity index 100% rename from code/modules/mob/living/simple_animal/slaughter/slaughter.dm rename to code/game/gamemodes/miniantags/slaughter/slaughter.dm diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index cb6a50af8ce..3b5127c10c6 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -273,9 +273,8 @@ proc/issyndicate(mob/living/M as mob) if (synd_mob.internals) synd_mob.internals.icon_state = "internal1" - var/obj/item/weapon/implant/dexplosive/E = new/obj/item/weapon/implant/dexplosive(synd_mob) - E.imp_in = synd_mob - E.implanted = 1 + var/obj/item/weapon/implant/explosive/E = new/obj/item/weapon/implant/explosive(synd_mob) + E.implant(synd_mob) synd_mob.faction |= "syndicate" synd_mob.update_icons() return 1 diff --git a/code/game/gamemodes/nuclear/nuclear_challenge.dm b/code/game/gamemodes/nuclear/nuclear_challenge.dm index d3599db49b1..7ab4e51f56e 100644 --- a/code/game/gamemodes/nuclear/nuclear_challenge.dm +++ b/code/game/gamemodes/nuclear/nuclear_challenge.dm @@ -1,4 +1,4 @@ -#define CHALLENGE_TIME_LIMIT 3000 +#define CHALLENGE_TIME_LIMIT 6000 #define MIN_CHALLENGE_PLAYERS 50 #define CHALLENGE_SHUTTLE_DELAY 15000 //25 minutes, so the ops have at least 5 minutes before the shuttle is callable. @@ -45,4 +45,4 @@ #undef CHALLENGE_TIME_LIMIT #undef MIN_CHALLENGE_PLAYERS -#undef CHALLENGE_SHUTTLE_DELAY \ No newline at end of file +#undef CHALLENGE_SHUTTLE_DELAY diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm index df18240e7bf..7fe0121090e 100644 --- a/code/game/gamemodes/traitor/traitor.dm +++ b/code/game/gamemodes/traitor/traitor.dm @@ -53,6 +53,9 @@ var/datum/mind/traitor = pick(possible_traitors) traitors += traitor traitor.special_role = "traitor" + var/datum/mindslaves/slaved = new() + slaved.masters += traitor + traitor.som = slaved //we MIGT want to mindslave someone traitor.restricted_roles = restricted_jobs possible_traitors.Remove(traitor) @@ -337,8 +340,8 @@ traitor_mob.mind.store_memory("Potential Collaborator: [M.real_name]") /datum/game_mode/proc/update_traitor_icons_added(datum/mind/traitor_mind) - //var/ref = "\ref[traitor_mind]" var/datum/atom_hud/antag/tatorhud = huds[ANTAG_HUD_SOLO] + //var/ref = "\ref[traitor_mind]" tatorhud.join_solo_hud(traitor_mind.current) set_antag_hud(traitor_mind.current, "hudsyndicate") @@ -347,6 +350,7 @@ tatorhud.leave_hud(traitor_mind.current) set_antag_hud(traitor_mind.current, null) + /datum/game_mode/proc/remove_traitor_mind(datum/mind/traitor_mind, datum/mind/head) //var/list/removal var/ref = "\ref[head]" @@ -354,7 +358,13 @@ implanter[ref] -= traitor_mind implanted -= traitor_mind traitors -= traitor_mind - traitor_mind.special_role = null + if(traitor_mind.som) + var/datum/mindslaves/slaved = traitor_mind.som + slaved.serv -= traitor_mind + traitor_mind.special_role = null + traitor_mind.som = null + slaved.leave_serv_hud(traitor_mind) + update_traitor_icons_removed(traitor_mind) //world << "Removed [traitor_mind.current.name] from traitor shit" traitor_mind.current << "\red The fog clouding your mind clears. You remember nothing from the moment you were implanted until now.(You don't remember who implanted you)" diff --git a/code/game/gamemodes/vampire/hud.dm b/code/game/gamemodes/vampire/hud.dm index 06e956413ac..8df7e893273 100644 --- a/code/game/gamemodes/vampire/hud.dm +++ b/code/game/gamemodes/vampire/hud.dm @@ -1,9 +1,9 @@ -/datum/hud/proc/vampire_hud(ui_style = 'icons/mob/screen1_Vampire.dmi') +/datum/hud/proc/vampire_hud(ui_style = 'icons/mob/screen1_Midnight.dmi') vampire_blood_display = new /obj/screen() vampire_blood_display.name = "Vampire Blood" vampire_blood_display.icon_state = "dark128" - vampire_blood_display.screen_loc = "EAST-1:28,CENTER+1:15" + vampire_blood_display.screen_loc = "WEST:6,CENTER-1:15" vampire_blood_display.layer = 20 mymob.client.screen += list(vampire_blood_display) \ No newline at end of file diff --git a/code/game/gamemodes/vampire/vampire.dm b/code/game/gamemodes/vampire/vampire.dm index 0931adfe4ef..3cdcab84d17 100644 --- a/code/game/gamemodes/vampire/vampire.dm +++ b/code/game/gamemodes/vampire/vampire.dm @@ -59,6 +59,9 @@ vampires += vampire vampire.restricted_roles = restricted_jobs modePlayer += vampires + var/datum/mindslaves/slaved = new() + slaved.masters += vampire + vampire.som = slaved //we MIGT want to mindslave someone vampire.special_role = "Vampire" // Needs to be done in pre-setup to prevent role bugs return 1 else @@ -398,6 +401,10 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha vampire_thralls[ref] -= vampire_mind vampire_enthralled -= vampire_mind vampire_mind.special_role = null + var/datum/mindslaves/slaved = vampire_mind.som + slaved.serv -= vampire_mind + vampire_mind.som = null + slaved.leave_serv_hud(vampire_mind) update_vampire_icons_removed(vampire_mind) //world << "Removed [vampire_mind.current.name] from vampire shit" vampire_mind.current << "\red The fog clouding your mind clears. You remember nothing from the moment you were enthralled until now." @@ -424,7 +431,6 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha if(hud_used) if(!hud_used.vampire_blood_display) hud_used.vampire_hud() - hud_used.human_hud('icons/mob/screen1_Vampire.dmi') hud_used.vampire_blood_display.maptext_width = 64 hud_used.vampire_blood_display.maptext_height = 26 hud_used.vampire_blood_display.maptext = "
U:[mind.vampire.bloodusable]
T:[mind.vampire.bloodtotal]
" diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm index 615f99c1b4c..e07f24983b1 100644 --- a/code/game/gamemodes/vampire/vampire_powers.dm +++ b/code/game/gamemodes/vampire/vampire_powers.dm @@ -325,13 +325,20 @@ ticker.mode.vampire_thralls[ref] = list(H.mind) else ticker.mode.vampire_thralls[ref] += H.mind + + ticker.mode.update_vampire_icons_added(H.mind) + ticker.mode.update_vampire_icons_added(src.mind) + var/datum/mindslaves/slaved = src.mind.som + H.mind.som = slaved + slaved.serv += H + slaved.add_serv_hud(src.mind,"vampire")//handles master servent icons + slaved.add_serv_hud(H.mind,"vampthrall") + ticker.mode.vampire_enthralled.Add(H.mind) ticker.mode.vampire_enthralled[H.mind] = src.mind H.mind.special_role = "VampThrall" H << "\red You have been Enthralled by [name]. Follow their every command." src << "\red You have successfully Enthralled [H.name]. If they refuse to do as you say just adminhelp." - ticker.mode.update_vampire_icons_added(H.mind) - ticker.mode.update_vampire_icons_added(src.mind) log_admin("[ckey(src.key)] has mind-slaved [ckey(H.key)].") /client/vampire/proc/vampire_bats() diff --git a/code/game/gamemodes/wizard/raginmages.dm b/code/game/gamemodes/wizard/raginmages.dm index d2818448736..7092469efd1 100644 --- a/code/game/gamemodes/wizard/raginmages.dm +++ b/code/game/gamemodes/wizard/raginmages.dm @@ -8,8 +8,10 @@ var/making_mage = 0 var/mages_made = 1 var/time_checked = 0 - var/players_per_mage = 4 // If the admin wants to tweak things or something + var/players_per_mage = 8 // If the admin wants to tweak things or something but_wait_theres_more = 1 + var/delay_per_mage = 4200 // Every 7 minutes by default + var/time_till_chaos = 18000 // Half-hour in /datum/game_mode/wizard/raginmages/announce() world << "The current game mode is - Ragin' Mages!" @@ -76,7 +78,7 @@ if (wizards_alive) if(!time_checked) time_checked = world.time - if(world.time > time_checked + 3000 && (mages_made < max_mages)) + if(world.time > time_till_chaos && world.time > time_checked + delay_per_mage && (mages_made < max_mages)) time_checked = world.time make_more_mages() else @@ -100,7 +102,8 @@ wizards -= M // No, you don't get to occupy a slot marked_for_death |= M.current for(var/mob/living/L in marked_for_death) - L << "STOP FIGHTING." + if(L.stat == CONSCIOUS) // Probably a troublemaker - I'd like to see YOU fight when unconscious + L << "STOP FIGHTING." L.ghostize() if(istype(L, /mob/living/carbon/brain)) // diediedie @@ -123,11 +126,11 @@ return 0 making_mage = 1 var/list/candidates = list() - var/client/theclient = null + var/mob/dead/observer/harry = null spawn(rand(200, 600)) message_admins("SWF is still pissed, sending another wizard - [max_mages - mages_made] left.") //Protip: This returns clients, not ghosts - candidates = get_candidates(ROLE_WIZARD) + candidates = get_candidate_ghosts(ROLE_WIZARD) if(!candidates.len) message_admins("No applicable clients for the next ragin' mage, asking ghosts instead.") var/time_passed = world.time @@ -138,7 +141,7 @@ if("Yes") if((world.time-time_passed)>300)//If more than 30 game seconds passed. continue - candidates += G.client + candidates += G if("No") continue sleep(300) @@ -148,23 +151,41 @@ return else candidates = shuffle(candidates) - for(var/client/i in candidates) + for(var/mob/dead/observer/i in candidates) if(!i) continue //Dont bother removing them from the list since we only grab one wizard - theclient = i + // YER A WIZZERD HARRY + harry = i break making_mage = 0 - if(theclient) - var/mob/living/carbon/human/new_character= create_human_for_client_from_prefs(theclient) + if(harry) + var/mob/living/carbon/human/new_character= makeBody(harry) new_character.mind.make_Wizard() // This puts them at the wizard spawn, worry not mages_made++ return 1 + else + log_to_dd("The candidates list for ragin' mages contained non-observer entries!") + return 0 + +// ripped from -tg-'s wizcode, because whee lets make a very general proc for a very specific gamemode +// This probably wouldn't do half bad as a proc in __HELPERS +// Lemme know if this causes species to mess up spectacularly or anything +/datum/game_mode/wizard/raginmages/proc/makeBody(var/mob/dead/observer/G) + if(!G || !G.key) return // Let's not steal someone's soul here + + var/mob/living/carbon/human/new_character = new(pick(latejoin)) + + G.client.prefs.copy_to(new_character) + + new_character.key = G.key + + return new_character /datum/game_mode/wizard/raginmages/declare_completion() if(finished) feedback_set_details("round_end_result","loss - wizard killed") world << "\red The crew has managed to hold off the wizard attack! The Space Wizards Federation has been taught a lesson they will not soon forget!" - ..(1) \ No newline at end of file + ..(1) diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index ac8874c003d..14f5eb08b9a 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -177,7 +177,7 @@ if(!L) return 0 if(!istype(L, /list)) return 0 return has_access(req_access, req_one_access, L) - + /proc/has_access(var/list/req_access, var/list/req_one_access, var/list/accesses) for(var/req in req_access) if(!(req in accesses)) //doesn't have this access @@ -254,19 +254,19 @@ /proc/get_all_syndicate_access() return list(access_syndicate, access_syndicate_leader, access_vox) - + /proc/get_all_misc_access() return list(access_salvage_captain) - + /proc/get_absolutely_all_accesses() return (get_all_accesses() | get_all_centcom_access() | get_all_syndicate_access() | get_all_misc_access()) - + /proc/get_region_accesses(var/code) switch(code) if(0) return get_all_accesses() if(1) //security - return list(access_sec_doors, access_security, access_brig, access_armory, access_forensics_lockers, access_court, access_pilot, access_hos) + return list(access_sec_doors, access_weapons, access_security, access_brig, access_armory, access_forensics_lockers, access_court, access_pilot, access_hos) if(2) //medbay return list(access_medical, access_genetics, access_morgue, access_chemistry, access_psychiatrist, access_virology, access_surgery, access_cmo, access_paramedic) if(3) //research diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index b752a9f28aa..9fe84dba496 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -43,9 +43,6 @@ var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 - var/obj/item/organ/external/affected = H.organs_by_name["head"] - affected.implants += L - L.part = affected H.sec_hud_set_implants() return 1 @@ -90,9 +87,6 @@ var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 - var/obj/item/organ/external/affected = H.organs_by_name["head"] - affected.implants += L - L.part = affected H.sec_hud_set_implants() return 1 @@ -146,9 +140,6 @@ var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 - var/obj/item/organ/external/affected = H.organs_by_name["head"] - affected.implants += L - L.part = affected H.sec_hud_set_implants() H.dna.SetSEState(SOBERBLOCK,1) @@ -194,9 +185,6 @@ var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 - var/obj/item/organ/external/affected = H.organs_by_name["head"] - affected.implants += L - L.part = affected H.sec_hud_set_implants() return 1 @@ -233,9 +221,6 @@ var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 - var/obj/item/organ/external/affected = H.organs_by_name["head"] - affected.implants += L - L.part = affected H.sec_hud_set_implants() return 1 @@ -274,8 +259,5 @@ var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 - var/obj/item/organ/external/affected = H.organs_by_name["head"] - affected.implants += L - L.part = affected H.sec_hud_set_implants() return 1 \ No newline at end of file diff --git a/code/game/jobs/job/supervisor.dm b/code/game/jobs/job/supervisor.dm index b42f221aaa5..2475df770b3 100644 --- a/code/game/jobs/job/supervisor.dm +++ b/code/game/jobs/job/supervisor.dm @@ -38,11 +38,8 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 - captain_announcement.Announce("All hands, captain [H.real_name] on deck!") - var/obj/item/organ/external/affected = H.organs_by_name["head"] - affected.implants += L - L.part = affected H.sec_hud_set_implants() + captain_announcement.Announce("All hands, captain [H.real_name] on deck!") callHook("captain_spawned", list("captain" = H)) return 1 @@ -137,9 +134,6 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 - var/obj/item/organ/external/affected = H.organs_by_name["head"] - affected.implants += L - L.part = affected H.sec_hud_set_implants() return 1 @@ -176,18 +170,17 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) H.equip_or_collect(new /obj/item/clothing/glasses/hud/health/health_advanced, slot_glasses) H.equip_or_collect(new /obj/item/clothing/under/rank/blueshield(H), slot_w_uniform) H.equip_or_collect(new /obj/item/clothing/suit/armor/vest/blueshield(H), slot_wear_suit) - H.equip_or_collect(new /obj/item/weapon/gun/energy/advtaser(H), slot_s_store) H.equip_or_collect(new /obj/item/device/pda/heads/blueshield(H), slot_wear_pda) + if(H.backbag == 1) H.equip_or_collect(new /obj/item/weapon/storage/box/deathimp(H), slot_r_hand) + H.equip_or_collect(new /obj/item/weapon/gun/energy/blueshield(H), slot_l_hand) else H.equip_or_collect(new /obj/item/weapon/storage/box/deathimp(H.back), slot_in_backpack) + H.equip_or_collect(new /obj/item/weapon/gun/energy/blueshield(H.back), slot_in_backpack) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 - var/obj/item/organ/external/affected = H.organs_by_name["head"] - affected.implants += L - L.part = affected H.sec_hud_set_implants() return 1 @@ -229,9 +222,6 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 - var/obj/item/organ/external/affected = H.organs_by_name["head"] - affected.implants += L - L.part = affected H.sec_hud_set_implants() return 1 @@ -272,8 +262,5 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 - var/obj/item/organ/external/affected = H.organs_by_name["head"] - affected.implants += L - L.part = affected H.sec_hud_set_implants() return 1 \ No newline at end of file diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 534c59d2150..22d33684c4a 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -196,7 +196,6 @@ /obj/machinery/body_scanconsole var/obj/machinery/bodyscanner/connected - var/known_implants = list(/obj/item/weapon/implant/chem, /obj/item/weapon/implant/death_alarm, /obj/item/weapon/implant/loyalty, /obj/item/weapon/implant/tracking) var/delete var/temphtml name = "Body Scanner Console" @@ -363,8 +362,6 @@ for(var/obj/I in E.implants) var/implantSubData[0] implantSubData["name"] = I.name - if(is_type_in_list(I, known_implants)) - implantSubData["known"] = 1 implantData.Add(list(implantSubData)) @@ -571,10 +568,7 @@ var/unknown_body = 0 for(var/I in e.implants) - if(is_type_in_list(I,known_implants)) - imp += "[I] implanted:" - else - unknown_body++ + unknown_body++ if(unknown_body || e.hidden) imp += "Unknown body present:" diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index 4e7dd4e28cf..92c642a3495 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -372,17 +372,20 @@ var/time_last_changed_position = 0 else if (modify && !mode) P.name = "access report" P.info = {"

Access Report

- Prepared By: [scan.registered_name ? scan.registered_name : "Unknown"]
+ Prepared By: [scan && scan.registered_name ? scan.registered_name : "Unknown"]
For: [modify.registered_name ? modify.registered_name : "Unregistered"]

Assignment: [modify.assignment]
Account Number: #[modify.associated_account_number]
Blood Type: [modify.blood_type]

- Access:
+ Access:
"} + var/first = 1 for(var/A in modify.access) - P.info += " [get_access_desc(A)]" + P.info += "[first ? "" : ", "][get_access_desc(A)]" + first = 0 + P.info += "
" if ("terminate") if (is_authenticated(usr)) diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm index 6c67ddd71cc..d9c8578c853 100644 --- a/code/game/machinery/computer/prisoner.dm +++ b/code/game/machinery/computer/prisoner.dm @@ -40,7 +40,7 @@ dat += text("Insert Prisoner ID
") dat += "
Chemical Implants
" var/turf/Tr = null - for(var/obj/item/weapon/implant/chem/C in tracking_implants) + for(var/obj/item/weapon/implant/chem/C in tracked_implants) Tr = get_turf(C) if((Tr) && (Tr.z != src.z)) continue//Out of range if(!C.implanted) continue @@ -54,7 +54,7 @@ ********************************
"} // END AUTOFIX dat += "
Tracking Implants
" - for(var/obj/item/weapon/implant/tracking/T in tracking_implants) + for(var/obj/item/weapon/implant/tracking/T in tracked_implants) Tr = get_turf(T) if((Tr) && (Tr.z != src.z)) continue//Out of range if(!T.implanted) continue @@ -63,8 +63,6 @@ if((M.z in config.station_levels) && !istype(M.loc, /turf/space)) var/turf/mob_loc = get_turf(M) loc_display = mob_loc.loc - if(T.malfunction) - loc_display = pick(teleportlocs) dat += "ID: [T.id] | Location: [loc_display]
" dat += "(Message Holder) |
" dat += "********************************
" diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index 374bfd0e4e6..f54365c2c05 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -169,17 +169,23 @@ var/icon/side = new(active1.fields["photo"], dir = WEST) user << browse_rsc(front, "front.png") user << browse_rsc(side, "side.png") - dat += text(" \ -
\ - Name: [active1.fields["name"]]
\ - ID: [active1.fields["id"]]
\n \ - Sex: [active1.fields["sex"]]
\n \ - Age: [active1.fields["age"]]
\n \ - Rank: [active1.fields["rank"]]
\n \ - Fingerprint: [active1.fields["fingerprint"]]
\n \ - Physical Status: [active1.fields["p_stat"]]
\n \ - Mental Status: [active1.fields["m_stat"]]
Photo:
\ -
") + dat += {" + +
+ Name: [active1.fields["name"]]
+ ID: [active1.fields["id"]]
+ Sex: [active1.fields["sex"]]
+ Age: [active1.fields["age"]]
+ Rank: [active1.fields["rank"]]
+ Fingerprint: [active1.fields["fingerprint"]]
+ Physical Status: [active1.fields["p_stat"]]
+ Mental Status: [active1.fields["m_stat"]]
+
+ Photo:
+ +
+ Print Photo +
"} else dat += "General Record Lost!
" if ((istype(active2, /datum/data/record) && data_core.security.Find(active2))) @@ -334,6 +340,15 @@ What a mess.*/ P.info += "" P.name = "paper - 'Security Record'" printing = null + + if ("Print Photo") + if(!printing) + printing = 1 + sleep(50) + if(istype(active1, /datum/data/record) && data_core.general.Find(active1)) + create_record_photo(active1) + printing = null + //RECORD DELETE if ("Delete All Records") temp = "" @@ -546,6 +561,43 @@ What a mess.*/ updateUsrDialog() return +/obj/machinery/computer/secure_data/proc/create_record_photo(datum/data/record/R) + // basically copy-pasted from the camera code but different enough that it has to be redone + var/icon/photoimage = get_record_photo(R) + var/icon/small_img = icon(photoimage) + var/icon/tiny_img = icon(photoimage) + var/icon/ic = icon('icons/obj/items.dmi',"photo") + var/icon/pc = icon('icons/obj/bureaucracy.dmi', "photo") + small_img.Scale(8, 8) + tiny_img.Scale(4, 4) + ic.Blend(small_img,ICON_OVERLAY, 10, 13) + pc.Blend(tiny_img,ICON_OVERLAY, 12, 19) + + var/datum/picture/P = new() + P.fields["name"] = "File Photo - [R.fields["name"]]" + P.fields["author"] = "Central Command" + P.fields["icon"] = ic + P.fields["tiny"] = pc + P.fields["img"] = photoimage + P.fields["desc"] = "You can see [R.fields["name"]] on the photo." + P.fields["pixel_x"] = rand(-10, 10) + P.fields["pixel_y"] = rand(-10, 10) + P.fields["size"] = 2 + + var/obj/item/weapon/photo/Photo = new/obj/item/weapon/photo(loc) + Photo.construct(P) + +/obj/machinery/computer/secure_data/proc/get_record_photo(datum/data/record/R) + // similar to the code to make a photo, but of course the actual rendering is completely different + var/icon/res = icon('icons/effects/96x96.dmi', "") + // will be 2x2 to fit the 2 directions + res.Scale(2 * 32, 2 * 32) + // transparent background (it's a plastic transparency, you see) with the front and side icons + res.Blend(icon(R.fields["photo"], dir = SOUTH), ICON_OVERLAY, 1, 17) + res.Blend(icon(R.fields["photo"], dir = WEST), ICON_OVERLAY, 33, 17) + + return res + /obj/machinery/computer/secure_data/emp_act(severity) if(stat & (BROKEN|NOPOWER)) ..(severity) diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 2d2e7adcfa3..c466a3890a4 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -23,9 +23,9 @@ FIRE ALARM /obj/machinery/firealarm/New() var/area/A = get_area_master(src) - if (!( istype(A, /area) )) + if(!istype(A, /area)) return - master_area=A + master_area = A /obj/machinery/firealarm/update_icon() @@ -50,10 +50,9 @@ FIRE ALARM icon_state = "fire0" /obj/machinery/firealarm/temperature_expose(datum/gas_mixture/air, temperature, volume) - if(src.detecting) + if(detecting) if(temperature > T0C+200) - src.alarm() // added check of detector status here - return + alarm() // added check of detector status here /obj/machinery/firealarm/attack_ai(mob/user as mob) src.add_hiddenprint(user) @@ -74,7 +73,7 @@ FIRE ALARM /obj/machinery/firealarm/attackby(obj/item/W as obj, mob/user as mob, params) src.add_fingerprint(user) - if (istype(W, /obj/item/weapon/screwdriver) && buildstage == 2) + if(istype(W, /obj/item/weapon/screwdriver) && buildstage == 2) wiresexposed = !wiresexposed update_icon() return @@ -83,8 +82,8 @@ FIRE ALARM switch(buildstage) if(2) if(istype(W, /obj/item/device/multitool)) - src.detecting = !( src.detecting ) - if (src.detecting) + detecting = !detecting + if(detecting) user.visible_message("\red [user] has reconnected [src]'s detecting unit!", "You have reconnected [src]'s detecting unit.") else user.visible_message("\red [user] has disconnected [src]'s detecting unit!", "You have disconnected [src]'s detecting unit.") @@ -100,14 +99,10 @@ FIRE ALARM if(1) if(istype(W, /obj/item/stack/cable_coil)) var/obj/item/stack/cable_coil/coil = W - if(coil.amount < 5) + if(!coil.use(5)) user << "You cut the wires!" return - coil.amount -= 5 - if(!coil.amount) - qdel(coil) - buildstage = 2 user << "You wire \the [src]!" update_icon() @@ -134,22 +129,21 @@ FIRE ALARM qdel(src) return - src.alarm() - return + alarm() /obj/machinery/firealarm/process()//Note: this processing was mostly phased out due to other code, and only runs when needed if(stat & (NOPOWER|BROKEN)) return - if(src.timing) - if(src.time > 0) - src.time = src.time - ((world.timeofday - last_process)/10) + if(timing) + if(time > 0) + time = time - ((world.timeofday - last_process)/10) else - src.alarm() - src.time = 0 - src.timing = 0 + alarm() + time = 0 + timing = 0 processing_objects.Remove(src) - src.updateDialog() + updateDialog() last_process = world.timeofday if(locate(/obj/effect/hotspot) in loc) @@ -167,12 +161,15 @@ FIRE ALARM update_icon() /obj/machinery/firealarm/attack_hand(mob/user as mob) - if((user.stat && !isobserver(user)) || stat & (NOPOWER|BROKEN)) - return + if(stat & (NOPOWER|BROKEN) || buildstage != 2) + return 1 - if (buildstage != 2) - return + if(user.incapacitated()) + return 1 + ui_interact(user) + +/* user.set_machine(src) var/area/A = src.loc var/d1 @@ -207,32 +204,53 @@ FIRE ALARM var/minute = (round(src.time) - second) / 60 var/dat = "[stars("Fire alarm")] [d1]\n
The current alert level is: [stars(get_security_level())]

\nTimer System: [d2]
\nTime Left: [(minute ? text("[]:", minute) : null)][second] - - + +\n
" user << browse(dat, "window=firealarm") - onclose(user, "firealarm") - return + onclose(user, "firealarm")*/ + +/obj/machinery/firealarm/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state) + var/data[0] + + var/area/A = get_area(src) + data["fire"] = A.fire + data["timing"] = timing + + data["sec_level"] = get_security_level() + + var/second = round(time) % 60 + var/minute = (round(time) - second) / 60 + + data["time_left"] = "[minute ? minute + ":" : null][second]" + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + ui = new(user, src, ui_key, "firealarm.tmpl", name, 400, 400, state = state) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + + + /obj/machinery/firealarm/Topic(href, href_list) if(..()) return 1 - if (buildstage != 2) + if(buildstage != 2) return 1 - if (href_list["reset"]) - src.reset() - else if (href_list["alarm"]) - src.alarm() - else if (href_list["time"]) - src.timing = text2num(href_list["time"]) + add_fingerprint(usr) + + if(href_list["reset"]) + reset() + else if(href_list["alarm"]) + alarm() + else if(href_list["time"]) + timing = text2num(href_list["time"]) last_process = world.timeofday processing_objects.Add(src) - else if (href_list["tp"]) + else if(href_list["tp"]) var/tp = text2num(href_list["tp"]) - src.time += tp - src.time = min(max(round(src.time), 0), 120) - - src.updateUsrDialog() - src.add_fingerprint(usr) - return + time += tp + time = min(max(round(src.time), 0), 120) /obj/machinery/firealarm/proc/reset() if (!( src.working )) diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm index b5baada5773..e95b39e28f8 100644 --- a/code/game/machinery/kitchen/gibber.dm +++ b/code/game/machinery/kitchen/gibber.dm @@ -1,4 +1,4 @@ - +#define GIBBER_ANIMATION_DELAY 16 /obj/machinery/gibber name = "Gibber" desc = "The name isn't descriptive enough?" @@ -27,6 +27,276 @@ if(occupant) occupant = null return ..() +/obj/machinery/gibber/RefreshParts() //If you want to make the machine upgradable, this is where you would change any vars basd on its stock parts. + return + +/obj/machinery/gibber/New() + ..() + overlays += image('icons/obj/kitchen.dmi', "grjam") + +/obj/machinery/gibber/update_icon() + overlays.Cut() + + if(dirty) + overlays += image('icons/obj/kitchen.dmi', "grbloody") + + if(stat & (NOPOWER|BROKEN)) + return + + if(!occupant) + overlays += image('icons/obj/kitchen.dmi', "grjam") + + else if(operating) + overlays += image('icons/obj/kitchen.dmi', "gruse") + + else + overlays += image('icons/obj/kitchen.dmi', "gridle") + +/obj/machinery/gibber/relaymove(mob/user as mob) + if(locked) + return + + go_out() + +/obj/machinery/gibber/attack_hand(mob/user as mob) + if(stat & (NOPOWER|BROKEN)) + return + + if(operating) + user << "The gibber is locked and running, wait for it to finish." + return + + if(locked) + user << "Wait for [occupant.name] to finish being loaded!" + return + + else + startgibbing(user) + +/obj/machinery/gibber/attackby(obj/item/P as obj, mob/user as mob, params) + if(istype(P, /obj/item/weapon/grab)) + var/obj/item/weapon/grab/G = P + if(G.state < 2) + user << "You need a better grip to do that!" + return + move_into_gibber(user,G.affecting) + qdel(G) + return + + if(default_deconstruction_screwdriver(user, "grinder_open", "grinder", P)) + return + + if(exchange_parts(user, P)) + return + + if(default_unfasten_wrench(user, P)) + return + + default_deconstruction_crowbar(P) + +/obj/machinery/gibber/MouseDrop_T(mob/target, mob/user) + if(user.incapacitated() || !ishuman(user)) + return + + if(!isliving(target)) + return + + var/mob/living/targetl = target + + if(targetl.buckled) + return + + move_into_gibber(user,target) + +/obj/machinery/gibber/proc/move_into_gibber(var/mob/user,var/mob/living/victim) + if(occupant) + user << "The gibber is full, empty it first!" + return + + if(operating) + user << "The gibber is locked and running, wait for it to finish." + return + + if(!ishuman(victim) || issmall(victim)) + user << "This is not suitable for the gibber!" + return + + if(victim.abiotic(1)) + user << "Subject may not have abiotic items on." + return + + user.visible_message("[user] starts to put [victim] into the gibber!") + src.add_fingerprint(user) + if(do_after(user, 30, target = victim) && user.Adjacent(src) && victim.Adjacent(user) && !occupant) + user.visible_message("[user] stuffs [victim] into the gibber!") + + victim.forceMove(src) + occupant = victim + + update_icon() + feedinTopanim() + +/obj/machinery/gibber/verb/eject() + set category = "Object" + set name = "Empty Gibber" + set src in oview(1) + + if(usr.stat != CONSCIOUS) + return + + go_out() + add_fingerprint(usr) + +/obj/machinery/gibber/proc/go_out() + if(operating || !occupant) //no going out if operating, just in case they manage to trigger go_out before being dead + return + + if(locked) + return + + for(var/obj/O in src) + O.loc = src.loc + + occupant.forceMove(get_turf(src)) + occupant = null + + update_icon() + + return + +/obj/machinery/gibber/proc/feedinTopanim() + if(!occupant) + return + + locked = 1 //lock gibber + + var/image/gibberoverlay = new //used to simulate 3D effects + gibberoverlay.icon = icon + gibberoverlay.icon_state = "grinderoverlay" + gibberoverlay.overlays += image('icons/obj/kitchen.dmi', "gridle") + + var/image/feedee = new + occupant.dir = 2 + feedee.icon = getFlatIcon(occupant, 2) //makes the image a copy of the occupant + + var/atom/movable/holder = new //holder for occupant image + holder.name = null //make unclickable + holder.overlays += feedee //add occupant to holder overlays + holder.pixel_y = 25 //above the gibber + holder.pixel_x = 2 + holder.loc = get_turf(src) + holder.layer = MOB_LAYER //simulate mob-like layering + holder.anchored = 1 + + var/atom/movable/holder2 = new //holder for gibber overlay, used to simulate 3D effect + holder2.name = null + holder2.overlays += gibberoverlay + holder2.loc = get_turf(src) + holder2.layer = MOB_LAYER + 0.1 //3D, it's above the mob, rest of the gibber is behind + holder2.anchored = 1 + + animate(holder, pixel_y = 16, time = GIBBER_ANIMATION_DELAY) //animate going down + + sleep(GIBBER_ANIMATION_DELAY) + + holder.overlays -= feedee //reset static icon + feedee.icon += icon('icons/obj/kitchen.dmi', "footicon") //this is some byond magic; += to the icon var with a black and white image will mask it + holder.overlays += feedee + animate(holder, pixel_y = -3, time = GIBBER_ANIMATION_DELAY) //animate going down further + + sleep(GIBBER_ANIMATION_DELAY) //time everything right, animate doesn't prevent proc from continuing + + qdel(holder) //get rid of holder object + qdel(holder2) //get rid of holder object + locked = 0 //unlock + +/obj/machinery/gibber/proc/startgibbing(var/mob/user, var/UserOverride=0) + if(!istype(user) && !UserOverride) + log_debug("Some shit just went down with the gibber at X[x], Y[y], Z[z] with an invalid user. (JMP)") + return + + if(UserOverride) + msg_admin_attack("[key_name_admin(occupant)] was gibbed by an autogibber (\the [src]) (JMP)") + + if(operating) + return + + if(!occupant) + visible_message("You hear a loud metallic grinding sound.") + return + + use_power(1000) + visible_message("You hear a loud squelchy grinding sound.") + + operating = 1 + update_icon() + var/offset = prob(50) ? -2 : 2 + animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 200) //start shaking + + var/slab_name = occupant.name + var/slab_count = 3 + var/slab_type = /obj/item/weapon/reagent_containers/food/snacks/meat/human //gibber can only gib humans on paracode, no need to check meat type + var/slab_nutrition = src.occupant.nutrition / 15 + + slab_nutrition /= slab_count + + for(var/i=1 to slab_count) + var/obj/item/weapon/reagent_containers/food/snacks/meat/new_meat = new slab_type(src) + new_meat.name = "[slab_name] [new_meat.name]" + new_meat.reagents.add_reagent("nutriment",slab_nutrition) + + if(occupant.reagents) + occupant.reagents.trans_to(new_meat, round(occupant.reagents.total_volume/slab_count,1)) + + new /obj/effect/decal/cleanable/blood/gibs(src) + + if(!UserOverride) + occupant.attack_log += "\[[time_stamp()]\] Was gibbed by [key_name(user)]" //One shall not simply gib a mob unnoticed! + user.attack_log += "\[[time_stamp()]\] Gibbed [key_name(occupant)]" + + if(occupant.ckey) + msg_admin_attack("[key_name_admin(user)] gibbed [key_name_admin(occupant)]") + + if(!iscarbon(user)) + occupant.LAssailant = null + else + occupant.LAssailant = user + + else //this looks ugly but it's better than a copy-pasted startgibbing proc override + occupant.attack_log += "\[[time_stamp()]\] Was gibbed by an autogibber (\the [src])" + + occupant.emote("scream") + playsound(get_turf(src), 'sound/effects/gib.ogg', 50, 1) + + victims += "\[[time_stamp()]\] [occupant.name] ([occupant.ckey]) killed by [UserOverride ? "Autogibbing" : "[user] ([user.ckey])"]" //have to do this before ghostizing + occupant.death(1) + occupant.ghostize() + + qdel(occupant) + + spawn(gibtime) + playsound(get_turf(src), 'sound/effects/splat.ogg', 50, 1) + operating = 0 + + for (var/obj/item/thing in contents) //Meat is spawned inside the gibber and thrown out afterwards. + thing.loc = get_turf(thing) // Drop it onto the turf for throwing. + thing.throw_at(get_edge_target_turf(src,gib_throw_dir),rand(1,5),15) // Being pelted with bits of meat and bone would hurt. + sleep(1) + + for (var/obj/effect/gibs in contents) //throw out the gibs too + gibs.loc = get_turf(gibs) //drop onto turf for throwing + gibs.throw_at(get_edge_target_turf(src,gib_throw_dir),rand(1,5),15) + sleep(1) + + pixel_x = initial(pixel_x) //return to it's spot after shaking + operating = 0 + update_icon() + + + +/* AUTOGIBBER */ + + //gibs anything that stands on it's input /obj/machinery/gibber/autogibber @@ -46,9 +316,6 @@ component_parts += new /obj/item/weapon/stock_parts/manipulator(null) RefreshParts() -/obj/machinery/gibber/RefreshParts() //If you want to make the machine upgradable, this is where you would change any vars basd on its stock parts. - return - /obj/machinery/gibber/autogibber/process() if(!lturf || occupant || locked || dirty || operating) return @@ -75,12 +342,8 @@ if(!istype(victim)) return 0 visible_message("\The [victim.name] gets sucked into \the [src]!") - if(victim.client) - victim.client.perspective = EYE_PERSPECTIVE - victim.client.eye = src - - victim.loc = src - src.occupant = victim + victim.forceMove(src) + occupant = victim update_icon() feedinTopanim() @@ -125,310 +388,3 @@ sleep(1) if(spats) visible_message("\The [src] spits out more possessions!") - -/* -//auto-gibs anything that bumps into it -/obj/machinery/gibber/autogibber - var/turf/input_plate - -/obj/machinery/gibber/autogibber/New() - ..() - spawn(5) - for(var/i in cardinal) - var/obj/machinery/mineral/input/input_obj = locate( /obj/machinery/mineral/input, get_step(src.loc, i) ) - if(input_obj) - if(isturf(input_obj.loc)) - input_plate = input_obj.loc - qdel(input_obj) - break - - if(!input_plate) - log_misc("a [src] didn't find an input plate.") - return - -/obj/machinery/gibber/autogibber/Bumped(var/atom/A) - if(!input_plate) return - - if(ismob(A)) - var/mob/M = A - - if(M.loc == input_plate) - M.loc = src - M.gib() -*/ - -/obj/machinery/gibber/New() - ..() - src.overlays += image('icons/obj/kitchen.dmi', "grjam") - -/obj/machinery/gibber/update_icon() - overlays.Cut() - - if (dirty) - src.overlays += image('icons/obj/kitchen.dmi', "grbloody") - - if(stat & (NOPOWER|BROKEN)) - return - - if (!occupant) - src.overlays += image('icons/obj/kitchen.dmi', "grjam") - - else if (operating) - src.overlays += image('icons/obj/kitchen.dmi', "gruse") - - else - src.overlays += image('icons/obj/kitchen.dmi', "gridle") - -/obj/machinery/gibber/relaymove(mob/user as mob) - if(locked) - return - - src.go_out() - - return - -/obj/machinery/gibber/attack_hand(mob/user as mob) - if(stat & (NOPOWER|BROKEN)) - return - - if(operating) - user << "The gibber is locked and running, wait for it to finish." - return - - if(locked) - user << "Wait for [occupant.name] to finish being loaded!" - return - - else - src.startgibbing(user) - -/obj/machinery/gibber/attackby(obj/item/P as obj, mob/user as mob, params) - if(istype(P, /obj/item/weapon/grab)) - var/obj/item/weapon/grab/G = P - if(G.state < 2) - user << "You need a better grip to do that!" - return - move_into_gibber(user,G.affecting) - qdel(G) - return - - if(default_deconstruction_screwdriver(user, "grinder_open", "grinder", P)) - return - - if(exchange_parts(user, P)) - return - - if(default_unfasten_wrench(user, P)) - return - - default_deconstruction_crowbar(P) - -/obj/machinery/gibber/MouseDrop_T(mob/target, mob/user) - if(usr.stat || (!ishuman(user)) || user.restrained() || user.weakened || user.stunned || user.paralysis || user.resting) - return - - if(!istype(target,/mob/living)) - return - - var/mob/living/targetl = target - - if(targetl.buckled) - return - - move_into_gibber(user,target) - -/obj/machinery/gibber/proc/move_into_gibber(var/mob/user,var/mob/living/victim) - if(src.occupant) - user << "The gibber is full, empty it first!" - return - - if(operating) - user << "The gibber is locked and running, wait for it to finish." - return - - if(!(istype(victim, /mob/living/carbon/human))) - user << "This is not suitable for the gibber!" - return - - if(victim.abiotic(1)) - user << "Subject may not have abiotic items on." - return - - user.visible_message("[user] starts to put [victim] into the gibber!") - src.add_fingerprint(user) - if(do_after(user, 30, target = victim) && user.Adjacent(src) && victim.Adjacent(user) && !occupant) - - user.visible_message("[user] stuffs [victim] into the gibber!") - - if(victim.client) - victim.client.perspective = EYE_PERSPECTIVE - victim.client.eye = src - - victim.loc = src - src.occupant = victim - - update_icon() - feedinTopanim() - -/obj/machinery/gibber/verb/eject() - set category = "Object" - set name = "Empty Gibber" - set src in oview(1) - - if (usr.stat != 0) - return - - src.go_out() - add_fingerprint(usr) - - return - -/obj/machinery/gibber/proc/go_out() - if (operating || !src.occupant) //no going out if operating, just in case they manage to trigger go_out before being dead - return - - if (locked) - return - - for(var/obj/O in src) - O.loc = src.loc - - if (src.occupant.client) - src.occupant.client.eye = src.occupant.client.mob - src.occupant.client.perspective = MOB_PERSPECTIVE - - src.occupant.loc = src.loc - src.occupant = null - - update_icon() - - return - -/obj/machinery/gibber/proc/feedinTopanim() - if(!occupant) return - - var/arbitrary_delay = 16 //arbitrary delay for animating going down - locked = 1 //lock gibber - - var/image/gibberoverlay = new //used to simulate 3D effects - gibberoverlay.icon = src.icon - gibberoverlay.icon_state = "grinderoverlay" - gibberoverlay.overlays += image('icons/obj/kitchen.dmi', "gridle") - - var/image/feedee = new - occupant.dir = 2 - feedee.icon = getFlatIcon(occupant, 2) //makes the image a copy of the occupant - - var/atom/movable/holder = new //holder for occupant image - holder.name = null //make unclickable - holder.overlays += feedee //add occupant to holder overlays - holder.pixel_y = 25 //above the gibber - holder.pixel_x = 2 - holder.loc = get_turf(src) - holder.layer = MOB_LAYER //simulate mob-like layering - holder.anchored = 1 - - var/atom/movable/holder2 = new //holder for gibber overlay, used to simulate 3D effect - holder2.name = null - holder2.overlays += gibberoverlay - holder2.loc = get_turf(src) - holder2.layer = MOB_LAYER + 0.1 //3D, it's above the mob, rest of the gibber is behind - holder2.anchored = 1 - - animate(holder, pixel_y = 16, time = arbitrary_delay) //animate going down - - sleep(arbitrary_delay) - - holder.overlays -= feedee //reset static icon - feedee.icon += icon('icons/obj/kitchen.dmi', "footicon") //this is some byond magic; += to the icon var with a black and white image will mask it - holder.overlays += feedee - animate(holder, pixel_y = -3, time = arbitrary_delay) //animate going down further - - sleep(arbitrary_delay) //time everything right, animate doesn't prevent proc from continuing - - qdel(holder) //get rid of holder object - qdel(holder2) //get rid of holder object - locked = 0 //unlock - -/obj/machinery/gibber/proc/startgibbing(var/mob/user, var/UserOverride=0) - if(!istype(user) && !UserOverride) - log_debug("Some shit just went down with the gibber at X[x], Y[y], Z[z] with an invalid user. (JMP)") - return - - if(UserOverride) - msg_admin_attack("[key_name_admin(occupant)] was gibbed by an autogibber (\the [src]) (JMP)") - - if(src.operating) - return - - if(!src.occupant) - visible_message("You hear a loud metallic grinding sound.") - return - - use_power(1000) - visible_message("You hear a loud squelchy grinding sound.") - - src.operating = 1 - update_icon() - var/offset = prob(50) ? -2 : 2 - animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 200) //start shaking - - var/slab_name = occupant.name - var/slab_count = 3 - var/slab_type = /obj/item/weapon/reagent_containers/food/snacks/meat/human //gibber can only gib humans on paracode, no need to check meat type - var/slab_nutrition = src.occupant.nutrition / 15 - - slab_nutrition /= slab_count - - for(var/i=1 to slab_count) - var/obj/item/weapon/reagent_containers/food/snacks/meat/new_meat = new slab_type(src) - new_meat.name = "[slab_name] [new_meat.name]" - new_meat.reagents.add_reagent("nutriment",slab_nutrition) - - if(src.occupant.reagents) - src.occupant.reagents.trans_to(new_meat, round(occupant.reagents.total_volume/slab_count,1)) - - new /obj/effect/decal/cleanable/blood/gibs(src) - - if(!UserOverride) - src.occupant.attack_log += "\[[time_stamp()]\] Was gibbed by [key_name(user)]" //One shall not simply gib a mob unnoticed! - user.attack_log += "\[[time_stamp()]\] Gibbed [key_name(occupant)]" - - if(src.occupant.ckey) - msg_admin_attack("[key_name_admin(user)] gibbed [key_name_admin(occupant)]") - - if(!iscarbon(user)) - src.occupant.LAssailant = null - else - src.occupant.LAssailant = user - - if(UserOverride) //this looks ugly but it's better than a copy-pasted startgibbing proc override - occupant.attack_log += "\[[time_stamp()]\] Was gibbed by an autogibber (\the [src])" - - src.occupant.emote("scream") - playsound(src.loc, 'sound/effects/gib.ogg', 50, 1) - - victims += "\[[time_stamp()]\] [occupant.name] ([occupant.ckey]) killed by [UserOverride ? "Autogibbing" : "[user] ([user.ckey])"]" //have to do this before ghostizing - src.occupant.death(1) - src.occupant.ghostize() - - qdel(src.occupant) - - spawn(src.gibtime) - - playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) - operating = 0 - - for (var/obj/item/thing in contents) //Meat is spawned inside the gibber and thrown out afterwards. - thing.loc = get_turf(thing) // Drop it onto the turf for throwing. - thing.throw_at(get_edge_target_turf(src,gib_throw_dir),rand(1,5),15) // Being pelted with bits of meat and bone would hurt. - sleep(1) - - for (var/obj/effect/gibs in contents) //throw out the gibs too - gibs.loc = get_turf(gibs) //drop onto turf for throwing - gibs.throw_at(get_edge_target_turf(src,gib_throw_dir),rand(1,5),15) - sleep(1) - - pixel_x = initial(pixel_x) //return to it's spot after shaking - src.operating = 0 - update_icon() \ No newline at end of file diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index 2af6157b0ee..6d0f70fc528 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -192,7 +192,7 @@ areaindex[tmpname] = 1 L[tmpname] = R - for (var/obj/item/weapon/implant/tracking/I in tracking_implants) + for (var/obj/item/weapon/implant/tracking/I in tracked_implants) if (!I.implanted || !ismob(I.loc)) continue else diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index ead588f462d..8dd72489b76 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -390,42 +390,34 @@ (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \ )) // you can't stab someone in the eyes wearing a mask! - user << "\red You're going to need to remove that mask/helmet/glasses first." + user << "You're going to need to remove that mask/helmet/glasses first!" return if(istype(M, /mob/living/carbon/alien) || istype(M, /mob/living/carbon/slime))//Aliens don't have eyes./N slimes also don't have eyes! - user << "\red You cannot locate any eyes on this creature!" + user << "You cannot locate any eyes on this creature!" return - user.attack_log += "\[[time_stamp()]\] Attacked [key_name(M)] with [src.name] (INTENT: [uppertext(user.a_intent)])" - M.attack_log += "\[[time_stamp()]\] Attacked by [key_name(user)] with [src.name] (INTENT: [uppertext(user.a_intent)])" - if(M.ckey) - msg_admin_attack("[key_name_admin(user)] attacked [key_name_admin(M)] with [src.name] (INTENT: [uppertext(user.a_intent)])") //BS12 EDIT ALG - if(!iscarbon(user)) M.LAssailant = null else M.LAssailant = user src.add_fingerprint(user) - //if((CLUMSY in user.mutations) && prob(50)) - // M = user - /* - M << "\red You stab yourself in the eye." - M.sdisabilities |= BLIND - M.weakened += 4 - M.adjustBruteLoss(10) - */ + + playsound(loc, src.hitsound, 30, 1, -1) + if(M != user) - for(var/mob/O in (viewers(M) - user - M)) - O.show_message("\red [M] has been stabbed in the eye with [src] by [user].", 1) - M << "\red [user] stabs you in the eye with [src]!" - user << "\red You stab [M] in the eye with [src]!" + M.visible_message("[user] has stabbed [M] in the eye with [src]!", \ + "[user] stabs you in the eye with [src]!") + user.do_attack_animation(M) else user.visible_message( \ - "\red [user] has stabbed themself with [src]!", \ - "\red You stab yourself in the eyes with [src]!" \ + "[user] has stabbed themself in the eyes with [src]!", \ + "You stab yourself in the eyes with [src]!" \ ) + + add_logs(M, user, "attacked", "[src.name]", "(INTENT: [uppertext(user.a_intent)])") + if(istype(H)) var/obj/item/organ/internal/eyes/eyes = H.get_int_organ(/obj/item/organ/internal/eyes) if(!eyes) @@ -434,17 +426,17 @@ if(eyes.damage >= eyes.min_bruised_damage) if(M.stat != 2) if(!(eyes.status & ORGAN_ROBOT) || !(eyes.status & ORGAN_ASSISTED)) //robot eyes bleeding might be a bit silly - M << "\red Your eyes start to bleed profusely!" + M << "Your eyes start to bleed profusely!" if(prob(50)) if(M.stat != 2) - M << "\red You drop what you're holding and clutch at your eyes!" + M << "You drop what you're holding and clutch at your eyes!" M.drop_item() M.eye_blurry += 10 M.Paralyse(1) M.Weaken(2) if (eyes.damage >= eyes.min_broken_damage) if(M.stat != 2) - M << "\red You go blind!" + M << "You go blind!" var/obj/item/organ/external/affecting = H.get_organ("head") if(affecting.take_damage(7)) H.UpdateDamageIcon() diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index 0db5724b527..8f916059010 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -6,7 +6,7 @@ w_class = 2.0 slot_flags = SLOT_BELT origin_tech = "programming=2" - var/request_cooldown = 60 // one minute + var/request_cooldown = 5 // five seconds var/last_request var/obj/item/device/radio/radio var/looking_for_personality = 0 diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index a096e8b0c8d..b984cc86719 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -57,13 +57,14 @@ return ..() -/obj/item/device/radio/headset/receive_range(freq, level, aiOverride = 0) - if (aiOverride) - return ..(freq, level) - if(ishuman(src.loc)) - var/mob/living/carbon/human/H = src.loc +/obj/item/device/radio/headset/receive_range(freq, level) + if(ishuman(loc)) + var/mob/living/carbon/human/H = loc if(H.l_ear == src || H.r_ear == src) return ..(freq, level) + else if(isanimal(loc)) + // frankly, all the ones with inventory are small enough to not warrant snowflaking the slot check somehow + return ..(freq, level) return -1 /obj/item/device/radio/headset/alt diff --git a/code/game/objects/items/stacks/telecrystal.dm b/code/game/objects/items/stacks/telecrystal.dm index d160dfe7342..2008eab9490 100644 --- a/code/game/objects/items/stacks/telecrystal.dm +++ b/code/game/objects/items/stacks/telecrystal.dm @@ -10,6 +10,14 @@ flags = NOBLUDGEON origin_tech = "materials=6;syndicate=1" +/obj/item/stack/telecrystal/attack(mob/target as mob, mob/user as mob) + if(target == user) //You can't go around smacking people with crystals to find out if they have an uplink or not. + for(var/obj/item/weapon/implant/uplink/I in target) + if(I && I.implanted) + I.hidden_uplink.uses +=1 + use(1) + user << "You press the [src] onto yourself and charge your hidden uplink." + /obj/item/stack/telecrystal/afterattack(var/obj/item/I as obj, mob/user as mob, proximity) if(!proximity) return diff --git a/code/game/objects/items/weapons/implants/deadman.dm b/code/game/objects/items/weapons/implants/deadman.dm deleted file mode 100644 index 29433380d7e..00000000000 --- a/code/game/objects/items/weapons/implants/deadman.dm +++ /dev/null @@ -1,35 +0,0 @@ -/obj/item/weapon/implant/deadman - name = "deadman switch implant" - desc = "Activates a signal on death." - var/obj/item/device/assembly/signaler/signaler - icon_state = "implant_evil" - -/obj/item/weapon/implant/deadman/get_data() - var/dat = {" -Implant Specifications:
-Name: Robust Corp RX-79 Deadman Switch Implant
-Life: Activates upon death.
-Important Notes: Sends triggering signal
-
-Implant Details:
-Function: Contains a compact, electric signaller that activates upon host death.
-Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."} - return dat - -/obj/item/weapon/implant/deadman/implanted(mob/source as mob) - signaler = new /obj/item/device/assembly/signaler(src) - signaler.interact(source) - usr.mind.store_memory("Deadman switch will broadcast signal on [signaler.frequency] using encryption [signaler.code].", 0, 0) - usr << "Deadman switch will broadcast signal on [signaler.frequency] using encryption [signaler.code]." - -/obj/item/weapon/implant/deadman/trigger(emote, source as mob) - if(emote == "deathgasp") - src.activate("death") - return - -/obj/item/weapon/implant/deadman/activate(var/cause) - if((!cause) || (!src.imp_in)) return 0 - signaler.signal() - -/obj/item/weapon/implant/deadman/islegal() - return 0 \ No newline at end of file diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index 9b2e3ef86fc..c466c5ba811 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -1,612 +1,81 @@ -#define MALFUNCTION_TEMPORARY 1 -#define MALFUNCTION_PERMANENT 2 /obj/item/weapon/implant name = "implant" - icon = 'icons/obj/device.dmi' - icon_state = "implant" + icon = 'icons/obj/implants.dmi' + icon_state = "generic" //Shows up as the action button icon + action_button_is_hands_free = 1 origin_tech = "materials=2;biotech=3;programming=2" + + var/activated = 1 //1 for implant types that can be activated, 0 for ones that are "always on" like loyalty implants var/implanted = null var/mob/living/imp_in = null - var/obj/item/organ/external/part = null item_color = "b" - var/allow_reagents = 0 - var/malfunction = 0 + var/allow_multiple = 0 + var/uses = -1 -/obj/item/weapon/implant/proc/trigger(emote, source as mob) + +/obj/item/weapon/implant/proc/trigger(emote, mob/source) return /obj/item/weapon/implant/proc/activate() return -// What does the implant do upon injection? -// return 0 if the implant fails (ex. Revhead and loyalty implant.) -// return 1 if the implant succeeds (ex. Nonrevhead and loyalty implant.) -/obj/item/weapon/implant/proc/implanted(var/mob/source) +/obj/item/weapon/implant/ui_action_click() + activate("action_button") + + +//What does the implant do upon injection? +//return 1 if the implant injects +//return -1 if the implant fails to inject +//return 0 if there is no room for implant +/obj/item/weapon/implant/proc/implant(var/mob/source, var/mob/user) + var/obj/item/weapon/implant/imp_e = locate(src.type) in source + if(!allow_multiple && imp_e && imp_e != src) + if(imp_e.uses < initial(imp_e.uses)*2) + if(uses == -1) + imp_e.uses = -1 + else + imp_e.uses = min(imp_e.uses + uses, initial(imp_e.uses)*2) + qdel(src) + return 1 + else + return 0 + + + if(activated) + action_button_name = "Activate [src.name]" + src.loc = source + imp_in = source + implanted = 1 if(istype(source, /mob/living/carbon/human)) var/mob/living/carbon/human/H = source H.sec_hud_set_implants() + + if(user) + add_logs(source, user, "implanted", object="[name]") + return 1 +/obj/item/weapon/implant/proc/removed(var/mob/source) + src.loc = null + imp_in = null + implanted = 0 + + if(istype(source, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = source + H.sec_hud_set_implants() + + return 1 + +/obj/item/weapon/implant/Destroy() + if(imp_in) + removed(imp_in) + return ..() + + /obj/item/weapon/implant/proc/get_data() return "No information available" -/obj/item/weapon/implant/proc/hear(message, source as mob) - return - -/obj/item/weapon/implant/proc/islegal() - return 1 - -/obj/item/weapon/implant/proc/meltdown() //breaks it down, making implant unrecongizible - imp_in << "\red You feel something melting inside [part ? "your [part.name]" : "you"]!" - if (part) - part.take_damage(burn = 15, used_weapon = "Electronics meltdown") - else - var/mob/living/M = imp_in - M.apply_damage(15,BURN) - name = "melted implant" - desc = "Charred circuit in melted plastic case. Wonder what that used to be..." - icon_state = "implant_melted" - malfunction = MALFUNCTION_PERMANENT - -/obj/item/weapon/implant/Destroy() - if(part) - part.implants.Remove(src) - return ..() - -/obj/item/weapon/implant/tracking - name = "tracking" - desc = "Track with this." - origin_tech = "materials=2;magnets=2;programming=2;biotech=2" - var/id = 1.0 - -/obj/item/weapon/implant/tracking/New() - ..() - tracking_implants += src - -/obj/item/weapon/implant/tracking/Destroy() - tracking_implants -= src - return ..() - -/obj/item/weapon/implant/tracking/get_data() - var/dat = {"Implant Specifications:
-Name: Tracking Beacon
-Life: 10 minutes after death of host
-Important Notes: None
-
-Implant Details:
-Function: Continuously transmits low power signal. Useful for tracking.
-Special Features:
-Neuro-Safe- Specialized shell absorbs excess voltages self-destructing the chip if -a malfunction occurs thereby securing safety of subject. The implant will melt and -disintegrate into bio-safe elements.
-Integrity: Gradient creates slight risk of being overcharged and frying the -circuitry. As a result neurotoxins can cause massive damage.
-Implant Specifics:
"} - return dat - -/obj/item/weapon/implant/tracking/emp_act(severity) - if (malfunction) //no, dawg, you can't malfunction while you are malfunctioning - return - malfunction = MALFUNCTION_TEMPORARY - - var/delay = 20 - switch(severity) - if(1) - if(prob(60)) - meltdown() - if(2) - delay = rand(5*60*10,15*60*10) //from 5 to 15 minutes of free time - - spawn(delay) - malfunction-- - -/obj/item/weapon/implant/dexplosive - name = "explosive" - desc = "And boom goes the weasel." - origin_tech = "materials=2;combat=3;biotech=4;syndicate=4" - icon_state = "implant_evil" - -/obj/item/weapon/implant/dexplosive/get_data() - var/dat = {" -Implant Specifications:
-Name: Robust Corp RX-78 Employee Management Implant
-Life: Activates upon death.
-Important Notes: Explodes
-
-Implant Details:
-Function: Contains a compact, electrically detonated explosive that detonates upon receiving a specially encoded signal or upon host death.
-Special Features: Explodes
-Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."} - return dat - -/obj/item/weapon/implant/dexplosive/trigger(emote, source as mob) - if(emote == "deathgasp") - src.activate("death") - return - -/obj/item/weapon/implant/dexplosive/activate(var/cause) - if((!cause) || (!src.imp_in)) return 0 - explosion(src, 0, 1, 3, 6)//This might be a bit much, dono will have to see. - if(src.imp_in) - src.imp_in.gib() - -/obj/item/weapon/implant/dexplosive/islegal() - return 0 - -//BS12 Explosive -/obj/item/weapon/implant/explosive - name = "explosive implant" - desc = "A military grade micro bio-explosive. Highly dangerous." - origin_tech = "materials=2;combat=3;biotech=4;syndicate=4" - var/elevel = "Localized Limb" - var/phrase = "supercalifragilisticexpialidocious" - icon_state = "implant_evil" - -/obj/item/weapon/implant/explosive/get_data() - var/dat = {" -Implant Specifications:
-Name: Robust Corp RX-78 Intimidation Class Implant
-Life: Activates upon codephrase.
-Important Notes: Explodes
-
-Implant Details:
-Function: Contains a compact, electrically detonated explosive that detonates upon receiving a specially encoded signal or upon host death.
-Special Features: Explodes
-Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."} - return dat - -/obj/item/weapon/implant/explosive/hear_talk(mob/M as mob, msg) - hear(msg) - return - -/obj/item/weapon/implant/explosive/hear(var/msg) - var/list/replacechars = list("'" = "","\"" = "",">" = "","<" = "","(" = "",")" = "") - msg = sanitize_simple(msg, replacechars) - if(findtext(msg,phrase)) - activate() - qdel(src) - -/obj/item/weapon/implant/explosive/activate() - if (malfunction == MALFUNCTION_PERMANENT) - return - - var/need_gib = null - if(istype(imp_in, /mob/)) - var/mob/T = imp_in - message_admins("Explosive implant triggered in [key_name_admin(T)]") - log_game("Explosive implant triggered in [key_name(T)].") - need_gib = 1 - - if(ishuman(imp_in)) - if (elevel == "Localized Limb") - if(part) //For some reason, small_boom() didn't work. So have this bit of working copypaste. - imp_in.visible_message("\red Something beeps inside [imp_in][part ? "'s [part.name]" : ""]!") - playsound(loc, 'sound/items/countdown.ogg', 75, 1, -3) - sleep(25) - if (istype(part,/obj/item/organ/external/chest) || \ - istype(part,/obj/item/organ/external/groin) || \ - istype(part,/obj/item/organ/external/head)) - part.createwound(BRUISE, 60) //mangle them instead - explosion(get_turf(imp_in), -1, -1, 2, 3) - qdel(src) - else - explosion(get_turf(imp_in), -1, -1, 2, 3) - part.droplimb() - qdel(src) - if (elevel == "Destroy Body") - explosion(get_turf(T), -1, 0, 1, 6) - T.gib() - if (elevel == "Full Explosion") - explosion(get_turf(T), 0, 1, 3, 6) - T.gib() - - else - explosion(get_turf(imp_in), 0, 1, 3, 6) - - if(need_gib) - imp_in.gib() - - var/turf/t = get_turf(imp_in) - - if(t) - t.hotspot_expose(3500,125) - -/obj/item/weapon/implant/explosive/implanted(mob/source as mob) - elevel = alert("What sort of explosion would you prefer?", "Implant Intent", "Localized Limb", "Destroy Body", "Full Explosion") - phrase = input("Choose activation phrase:") as text - var/list/replacechars = list("'" = "","\"" = "",">" = "","<" = "","(" = "",")" = "") - phrase = sanitize_simple(phrase, replacechars) - usr.mind.store_memory("Explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', say [src.phrase] to attempt to activate.", 0, 0) - usr << "The implanted explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', say [src.phrase] to attempt to activate." - return 1 - -/obj/item/weapon/implant/explosive/emp_act(severity) - if (malfunction) - return - malfunction = MALFUNCTION_TEMPORARY - switch (severity) - if (2.0) //Weak EMP will make implant tear limbs off. - if (prob(50)) - small_boom() - if (1.0) //strong EMP will melt implant either making it go off, or disarming it - if (prob(70)) - if (prob(50)) - small_boom() - else - if (prob(50)) - activate() //50% chance of bye bye - else - meltdown() //50% chance of implant disarming - spawn (20) - malfunction-- - -/obj/item/weapon/implant/explosive/islegal() - return 0 - -/obj/item/weapon/implant/explosive/proc/small_boom() - if (ishuman(imp_in) && part) - imp_in.visible_message("\red Something beeps inside [imp_in][part ? "'s [part.name]" : ""]!") - playsound(loc, 'sound/items/countdown.ogg', 75, 1, -3) - spawn(25) - if (ishuman(imp_in) && part) - //No tearing off these parts since it's pretty much killing - //and you can't replace groins - if (istype(part,/obj/item/organ/external/chest) || \ - istype(part,/obj/item/organ/external/groin) || \ - istype(part,/obj/item/organ/external/head)) - part.createwound(BRUISE, 60) //mangle them instead - else - part.droplimb() - explosion(get_turf(imp_in), -1, -1, 2, 3) - qdel(src) - -/obj/item/weapon/implant/chem - name = "chem" - desc = "Injects things." - origin_tech = "materials=3;biotech=4" - allow_reagents = 1 - -/obj/item/weapon/implant/chem/get_data() - var/dat = {" -Implant Specifications:
-Name: Robust Corp MJ-420 Prisoner Management Implant
-Life: Deactivates upon death but remains within the body.
-Important Notes: Due to the system functioning off of nutrients in the implanted subject's body, the subject
-will suffer from an increased appetite.

-
-Implant Details:
-Function: Contains a small capsule that can contain various chemicals. Upon receiving a specially encoded signal
-the implant releases the chemicals directly into the blood stream.
-Special Features: -Micro-Capsule- Can be loaded with any sort of chemical agent via the common syringe and can hold 50 units.
-Can only be loaded while still in its original case.
-Integrity: Implant will last so long as the subject is alive. However, if the subject suffers from malnutrition,
-the implant may become unstable and either pre-maturely inject the subject or simply break."} - return dat - -/obj/item/weapon/implant/chem/New() - ..() - var/datum/reagents/R = new/datum/reagents(50) - reagents = R - R.my_atom = src - tracking_implants += src - -/obj/item/weapon/implant/chem/Destroy() - tracking_implants -= src - return ..() - -/obj/item/weapon/implant/chem/trigger(emote, source as mob) - if(emote == "deathgasp") - src.activate(src.reagents.total_volume) - return - -/obj/item/weapon/implant/chem/activate(var/cause) - if((!cause) || (!src.imp_in)) return 0 - var/mob/living/carbon/R = src.imp_in - src.reagents.trans_to(R, cause) - R << "You hear a faint *beep*." - if(!src.reagents.total_volume) - R << "You hear a faint click from your chest." - spawn(0) - qdel(src) - return - -/obj/item/weapon/implant/chem/emp_act(severity) - if (malfunction) - return - malfunction = MALFUNCTION_TEMPORARY - - switch(severity) - if(1) - if(prob(60)) - activate(20) - if(2) - if(prob(30)) - activate(5) - - spawn(20) - malfunction-- - -/obj/item/weapon/implant/loyalty - name = "loyalty" - desc = "Makes you loyal or such." - origin_tech = "materials=2;biotech=4;programming=4" - -/obj/item/weapon/implant/loyalty/get_data() - var/dat = {" -Implant Specifications:
-Name: Nanotrasen Employee Management Implant
-Life: Ten years.
-Important Notes: Personnel injected with this device tend to be much more loyal to the company.
-
-Implant Details:
-Function: Contains a small pod of nanobots that manipulate the host's mental functions.
-Special Features: Will prevent and cure most forms of brainwashing.
-Integrity: Implant will last so long as the nanobots are inside the bloodstream."} - return dat - - -/obj/item/weapon/implant/loyalty/implanted(mob/M) - if(!istype(M, /mob/living/carbon/human)) return 0 - var/mob/living/carbon/human/H = M - if(H.mind in ticker.mode.head_revolutionaries) - H.visible_message("[H] seems to resist the implant!", "You feel the corporate tendrils of Nanotrasen try to invade your mind!") - return 0 - else if(H.mind in ticker.mode:revolutionaries) - ticker.mode:remove_revolutionary(H.mind) - H << "You feel a surge of loyalty towards Nanotrasen." - return 1 - -/obj/item/weapon/implant/traitor - name = "Mindslave Implant" - desc = "Divide and Conquer" - icon_state = "implant_evil" - -/obj/item/weapon/implant/traitor/get_data() - var/dat = {" -Implant Specifications:
-Name: Mind-Slave Implant
-Life: ???
-Important Notes: Any humanoid injected with this implant will become loyal to the injector, unless of course the host is already loyal to someone else.
-
-Implant Details:
-Function: Contains a small pod of nanobots that manipulate the host's mental functions.
-Special Features: Diplomacy was never so easy.
-Integrity: Implant will last so long as the nanobots are inside the bloodstream."} - return dat - -/obj/item/weapon/implant/traitor/implanted(mob/M, mob/user) - var/list/implanters - var/ref = "\ref[user.mind]" - if(!ishuman(M)) return 0 - if(!M.mind) return 0 - var/mob/living/carbon/human/H = M - if(M == user) - user << "Making yourself loyal to yourself was a great idea! Perhaps even the best idea ever! Actually, you just feel like an idiot." - if(isliving(user)) - var/mob/living/L = user - L.adjustBrainLoss(20) - return - if(locate(/obj/item/weapon/implant/loyalty) in H.contents) - H.visible_message("[H] seems to resist the implant!", "You feel a strange sensation in your head that quickly dissipates.") - return 0 - if(locate(/obj/item/weapon/implant/traitor) in H.contents) - H.visible_message("[H] seems to resist the implant!", "You feel a strange sensation in your head that quickly dissipates.") - return 0 - H.implanting = 1 - H << "You feel completely loyal to [user.name]." - if(!(user.mind in ticker.mode:implanter)) - ticker.mode:implanter[ref] = list() - implanters = ticker.mode:implanter[ref] - implanters.Add(H.mind) - ticker.mode.implanted.Add(H.mind) - ticker.mode.implanted[H.mind] = user.mind - //ticker.mode:implanter[user.mind] += H.mind - ticker.mode:implanter[ref] = implanters - ticker.mode.traitors += H.mind - H.mind.special_role = "traitor" - H << "You're now completely loyal to [user.name]! You now must lay down your life to protect them and assist in their goals at any cost." - var/datum/objective/protect/p = new - p.owner = H.mind - p.target = user:mind - p.explanation_text = "Obey every order from and protect [user:real_name], the [user:mind:assigned_role=="MODE" ? (user:mind:special_role) : (user:mind:assigned_role)]." - H.mind.objectives += p - for(var/datum/objective/objective in H.mind.objectives) - H << "Objective #1: [objective.explanation_text]" - ticker.mode.update_traitor_icons_added(H.mind) - ticker.mode.update_traitor_icons_added(user.mind) - log_admin("[ckey(user.key)] has mind-slaved [ckey(H.key)].") - return 1 - -/obj/item/weapon/implant/traitor/islegal() - return 0 - -/obj/item/weapon/implant/adrenalin - name = "adrenalin" - desc = "Removes all stuns and knockdowns." - origin_tech = "materials=2;biotech=4;combat=3;syndicate=4" - var/uses = 3 - -/obj/item/weapon/implant/adrenalin/get_data() - var/dat = {" -Implant Specifications:
-Name: Cybersun Industries Adrenalin Implant
-Life: Five days.
-Important Notes: Illegal
-
-Implant Details: Subjects injected with implant can activate an injection of medical cocktails.
-Function: Removes stuns, increases speed, and has a mild healing effect.
-Special Features: Will prevent and cure most forms of brainwashing.
-Integrity: Implant can only be used three times before the nanobots are depleted."} - return dat - -/obj/item/weapon/implant/adrenalin/trigger(emote, mob/source as mob) - if (src.uses < 1) return 0 - if (emote == "pale") - src.uses-- - source << "\blue You feel a sudden surge of energy!" - source.SetStunned(0) - source.SetWeakened(0) - source.SetParalysis(0) - imp_in.adjustStaminaLoss(-75) - source.lying = 0 - source.update_canmove() - - source.reagents.add_reagent("synaptizine", 10) - source.reagents.add_reagent("omnizine", 10) - source.reagents.add_reagent("stimulative_agent", 10) - - return - -/obj/item/weapon/implant/adrenalin/implanted(mob/source) - source.mind.store_memory("A implant can be activated by using the pale emote, say *pale to attempt to activate.", 0, 0) - source << "The implanted freedom implant can be activated by using the pale emote, say *pale to attempt to activate." - return 1 - -/obj/item/weapon/implant/death_alarm - name = "death alarm implant" - desc = "An alarm which monitors host vital signs and transmits a radio message upon death." - var/mobname = "Will Robinson" - -/obj/item/weapon/implant/death_alarm/get_data() - var/dat = {" -Implant Specifications:
-Name: Nanotrasen \"Profit Margin\" Class Employee Lifesign Sensor
-Life: Activates upon death.
-Important Notes: Alerts crew to crewmember death.
-
-Implant Details:
-Function: Contains a compact radio signaler that triggers when the host's lifesigns cease.
-Special Features: Alerts crew to crewmember death.
-Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."} - return dat - -/obj/item/weapon/implant/death_alarm/process() - if (!implanted) return - var/mob/M = imp_in - - if(isnull(M)) // If the mob got gibbed - activate() - else if(M.stat == 2) - activate("death") - -/obj/item/weapon/implant/death_alarm/activate(var/cause) - var/mob/M = imp_in - var/area/t = get_area(M) - switch (cause) - if("death") - var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null) - if(istype(t, /area/syndicate_station) || istype(t, /area/syndicate_mothership) || istype(t, /area/shuttle/syndicate_elite) ) - //give the syndies a bit of stealth - a.autosay("[mobname] has died in Space!", "[mobname]'s Death Alarm") - else - a.autosay("[mobname] has died in [t.name]!", "[mobname]'s Death Alarm") - qdel(a) - processing_objects.Remove(src) - if ("emp") - var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null) - var/name = prob(50) ? t.name : pick(teleportlocs) - a.autosay("[mobname] has died in [name]!", "[mobname]'s Death Alarm") - qdel(a) - else - var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null) - a.autosay("[mobname] has died-zzzzt in-in-in...", "[mobname]'s Death Alarm") - qdel(a) - processing_objects.Remove(src) - -/obj/item/weapon/implant/death_alarm/emp_act(severity) //for some reason alarms stop going off in case they are emp'd, even without this - if (malfunction) //so I'm just going to add a meltdown chance here - return - malfunction = MALFUNCTION_TEMPORARY - - activate("emp") //let's shout that this dude is dead - if(severity == 1) - if(prob(40)) //small chance of obvious meltdown - meltdown() - else if (prob(60)) //but more likely it will just quietly die - malfunction = MALFUNCTION_PERMANENT - processing_objects.Remove(src) - - spawn(20) - malfunction-- - -/obj/item/weapon/implant/death_alarm/implanted(mob/source as mob) - mobname = source.real_name - processing_objects.Add(src) - return 1 - -/obj/item/weapon/implant/compressed - name = "compressed matter implant" - desc = "Based on compressed matter technology, can store a single item." - icon_state = "implant_evil" - origin_tech = "materials=2;magnets=4;bluespace=4;syndicate=4" - var/activation_emote = "sigh" - var/obj/item/scanned = null - -/obj/item/weapon/implant/compressed/get_data() - var/dat = {" -Implant Specifications:
-Name: Nanotrasen \"Profit Margin\" Class Employee Lifesign Sensor
-Life: Activates upon death.
-Important Notes: Alerts crew to crewmember death.
-
-Implant Details:
-Function: Contains a compact radio signaler that triggers when the host's lifesigns cease.
-Special Features: Alerts crew to crewmember death.
-Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."} - return dat - -/obj/item/weapon/implant/compressed/trigger(emote, mob/source as mob) - if (src.scanned == null) - return 0 - - if (emote == src.activation_emote) - source << "The air glows as \the [src.scanned.name] uncompresses." - activate() - -/obj/item/weapon/implant/compressed/activate() - var/turf/t = get_turf(src) - if (imp_in) - imp_in.put_in_hands(scanned) - else - scanned.loc = t +/obj/item/weapon/implant/dropped(mob/user) + . = 1 qdel(src) - -/obj/item/weapon/implant/compressed/implanted(mob/source as mob) - src.activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch_s", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink") - if (source.mind) - source.mind.store_memory("Compressed matter implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", 0, 0) - source << "The implanted compressed matter implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate." - return 1 - -/obj/item/weapon/implant/compressed/islegal() - return 0 - -/obj/item/weapon/implant/cortical - name = "cortical stack" - desc = "A fist-sized mass of biocircuits and chips." - icon_state = "implant_evil" - -/obj/item/weapon/implant/emp - name = "emp implant" - desc = "Triggers an EMP." - origin_tech = "materials=2;biotech=3;magnets=4;syndicate=4" - var/activation_emote = "chuckle" - var/uses = 2 - -/obj/item/weapon/implant/emp/New() - activation_emote = pick("blink", "blink_r", "eyebrow", "chuckle", "twitch_s", "frown", "nod", "blush", "giggle", "grin", "groan", "smile", "pale", "sniff", "whimper", "wink") - ..() - return - -/obj/item/weapon/implant/emp/trigger(emote, mob/living/carbon/source as mob) - if (src.uses < 1) return 0 - if (emote == src.activation_emote) - src.uses-- - empulse(source, 3, 5) - return - -/obj/item/weapon/implant/emp/implanted(mob/living/carbon/source) - source.mind.store_memory("EMP implant can be activated [uses] time\s by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", 0, 0) - source << "The implanted EMP implant can be activated [uses] time\s by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate." - return 1 \ No newline at end of file + return . diff --git a/code/game/objects/items/weapons/implants/implant_chem.dm b/code/game/objects/items/weapons/implants/implant_chem.dm new file mode 100644 index 00000000000..a0540dbe79c --- /dev/null +++ b/code/game/objects/items/weapons/implants/implant_chem.dm @@ -0,0 +1,61 @@ +/obj/item/weapon/implant/chem + name = "chem implant" + desc = "Injects things." + icon_state = "reagents" + origin_tech = "materials=3;biotech=4" + flags = OPENCONTAINER + +/obj/item/weapon/implant/chem/get_data() + var/dat = {"Implant Specifications:
+ Name: Robust Corp MJ-420 Prisoner Management Implant
+ Life: Deactivates upon death but remains within the body.
+ Important Notes: Due to the system functioning off of nutrients in the implanted subject's body, the subject
+ will suffer from an increased appetite.

+
+ Implant Details:
+ Function: Contains a small capsule that can contain various chemicals. Upon receiving a specially encoded signal
+ the implant releases the chemicals directly into the blood stream.
+ Special Features: + Micro-Capsule- Can be loaded with any sort of chemical agent via the common syringe and can hold 50 units.
+ Can only be loaded while still in its original case.
+ Integrity: Implant will last so long as the subject is alive."} + return dat + +/obj/item/weapon/implant/chem/New() + ..() + create_reagents(50) + tracked_implants += src + +/obj/item/weapon/implant/chem/Destroy() + tracked_implants -= src + return ..() + + + + +/obj/item/weapon/implant/chem/trigger(emote, mob/source) + if(emote == "deathgasp") + activate(reagents.total_volume) + +/obj/item/weapon/implant/chem/activate(cause) + if(!cause || !imp_in) return 0 + var/mob/living/carbon/R = imp_in + var/injectamount = null + if (cause == "action_button") + injectamount = reagents.total_volume + else + injectamount = cause + reagents.trans_to(R, injectamount) + R << "You hear a faint beep." + if(!reagents.total_volume) + R << "You hear a faint click from your chest." + qdel(src) + + +/obj/item/weapon/implantcase/chem + name = "implant case - 'Remote Chemical'" + desc = "A glass case containing a remote chemical implant." + +/obj/item/weapon/implantcase/chem/New() + imp = new /obj/item/weapon/implant/chem(src) + ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/implants/implant_death_alarm.dm b/code/game/objects/items/weapons/implants/implant_death_alarm.dm new file mode 100644 index 00000000000..58b9de4589a --- /dev/null +++ b/code/game/objects/items/weapons/implants/implant_death_alarm.dm @@ -0,0 +1,71 @@ +/obj/item/weapon/implant/death_alarm + name = "death alarm implant" + desc = "An alarm which monitors host vital signs and transmits a radio message upon death." + var/mobname = "Will Robinson" + activated = 0 + +/obj/item/weapon/implant/death_alarm/get_data() + var/dat = {"Implant Specifications:
+ Name: Nanotrasen \"Profit Margin\" Class Employee Lifesign Sensor
+ Life: Activates upon death.
+ Important Notes: Alerts crew to crewmember death.
+
+ Implant Details:
+ Function: Contains a compact radio signaler that triggers when the host's lifesigns cease.
+ Special Features: Alerts crew to crewmember death.
+ Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."} + return dat + +/obj/item/weapon/implant/death_alarm/Destroy() + processing_objects.Remove(src) + return ..() + +/obj/item/weapon/implant/death_alarm/process() + if(!implanted) + return + var/mob/M = imp_in + + if(isnull(M)) // If the mob got gibbed + activate() + else if(M.stat == DEAD) + activate("death") + +/obj/item/weapon/implant/death_alarm/activate(var/cause) + var/mob/M = imp_in + var/area/t = get_area(M) + switch (cause) + if("death") + var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null) + if(istype(t, /area/syndicate_station) || istype(t, /area/syndicate_mothership) || istype(t, /area/shuttle/syndicate_elite) ) + //give the syndies a bit of stealth + a.autosay("[mobname] has died in Space!", "[mobname]'s Death Alarm") + else + a.autosay("[mobname] has died in [t.name]!", "[mobname]'s Death Alarm") + qdel(a) + qdel(src) + if ("emp") + var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null) + var/name = prob(50) ? t.name : pick(teleportlocs) + a.autosay("[mobname] has died in [name]!", "[mobname]'s Death Alarm") + qdel(a) + else + var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null) + a.autosay("[mobname] has died-zzzzt in-in-in...", "[mobname]'s Death Alarm") + qdel(a) + qdel(src) + +/obj/item/weapon/implant/death_alarm/emp_act(severity) //for some reason alarms stop going off in case they are emp'd, even without this + activate("emp") //let's shout that this dude is dead + +/obj/item/weapon/implant/death_alarm/implant(mob/target) + if(..()) + mobname = target.real_name + processing_objects.Add(src) + return 1 + return 0 + +/obj/item/weapon/implant/death_alarm/removed(mob/target) + if(..()) + processing_objects.Remove(src) + return 1 + return 0 \ No newline at end of file diff --git a/code/game/objects/items/weapons/implants/implant_explosive.dm b/code/game/objects/items/weapons/implants/implant_explosive.dm new file mode 100644 index 00000000000..3006a437943 --- /dev/null +++ b/code/game/objects/items/weapons/implants/implant_explosive.dm @@ -0,0 +1,128 @@ +/obj/item/weapon/implant/explosive + name = "microbomb implant" + desc = "And boom goes the weasel." + icon_state = "explosive" + origin_tech = "materials=2;combat=3;biotech=4;syndicate=4" + var/weak = 2 + var/medium = 0.8 + var/heavy = 0.4 + var/delay = 7 + +/obj/item/weapon/implant/explosive/get_data() + var/dat = {"Implant Specifications:
+ Name: Robust Corp RX-78 Employee Management Implant
+ Life: Activates upon death.
+ Important Notes: Explodes
+
+ Implant Details:
+ Function: Contains a compact, electrically detonated explosive that detonates upon receiving a specially encoded signal or upon host death.
+ Special Features: Explodes
+ "} + return dat + +/obj/item/weapon/implant/explosive/trigger(emote, mob/source) + if(emote == "deathgasp") + activate("death") + +/obj/item/weapon/implant/explosive/activate(cause) + if(!cause || !imp_in) return 0 + if(cause == "action_button" && alert(imp_in, "Are you sure you want to activate your microbomb implant? This will cause you to explode!", "Microbomb Implant Confirmation", "Yes", "No") != "Yes") + return 0 + heavy = round(heavy) + medium = round(medium) + weak = round(weak) + imp_in << "You activate your microbomb implant." +//If the delay is short, just blow up already jeez + if(delay <= 7) + explosion(src,heavy,medium,weak,weak, flame_range = weak) + if(imp_in) + imp_in.gib() + qdel(src) + return + timed_explosion() + +/obj/item/weapon/implant/explosive/implant(mob/source) + var/obj/item/weapon/implant/explosive/imp_e = locate(src.type) in source + if(imp_e && imp_e != src) + imp_e.heavy += heavy + imp_e.medium += medium + imp_e.weak += weak + imp_e.delay += delay + qdel(src) + return 1 + + return ..() + +/obj/item/weapon/implant/explosive/proc/timed_explosion() + imp_in.visible_message("[imp_in] starts beeping ominously!") + playsound(loc, 'sound/items/timer.ogg', 30, 0) + sleep(delay/4) + if(imp_in && imp_in.stat) + imp_in.visible_message("[imp_in] doubles over in pain!") + imp_in.Weaken(7) + playsound(loc, 'sound/items/timer.ogg', 30, 0) + sleep(delay/4) + playsound(loc, 'sound/items/timer.ogg', 30, 0) + sleep(delay/4) + playsound(loc, 'sound/items/timer.ogg', 30, 0) + sleep(delay/4) + explosion(src,heavy,medium,weak,weak, flame_range = weak) + if(imp_in) + imp_in.gib() + qdel(src) + +/obj/item/weapon/implant/explosive/macro + name = "macrobomb implant" + desc = "And boom goes the weasel. And everything else nearby." + icon_state = "explosive" + origin_tech = "materials=3;combat=5;biotech=4;syndicate=5" + weak = 16 + medium = 8 + heavy = 4 + delay = 70 + +/obj/item/weapon/implant/explosive/macro/activate(cause) + if(!cause || !imp_in) return 0 + if(cause == "action_button" && alert(imp_in, "Are you sure you want to activate your macrobomb implant? This will cause you to explode and gib!", "Macrobomb Implant Confirmation", "Yes", "No") != "Yes") + return 0 + imp_in << "You activate your macrobomb implant." + timed_explosion() + +/obj/item/weapon/implant/explosive/macro/implant(mob/source) + var/obj/item/weapon/implant/explosive/imp_e = locate(src.type) in source + if(imp_e && imp_e != src) + return 0 + imp_e = locate(/obj/item/weapon/implant/explosive) in source + if(imp_e && imp_e != src) + heavy += imp_e.heavy + medium += imp_e.medium + weak += imp_e.weak + delay += imp_e.delay + qdel(imp_e) + + return ..() + + +/obj/item/weapon/implanter/explosive + name = "implanter (explosive)" + +/obj/item/weapon/implanter/explosive/New() + imp = new /obj/item/weapon/implant/explosive(src) + ..() + + +/obj/item/weapon/implantcase/explosive + name = "implant case - 'Explosive'" + desc = "A glass case containing an explosive implant." + +/obj/item/weapon/implantcase/explosive/New() + imp = new /obj/item/weapon/implant/explosive(src) + ..() + + +/obj/item/weapon/implanter/explosive_macro + name = "implanter (macro-explosive)" + +/obj/item/weapon/implanter/explosive_macro/New() + imp = new /obj/item/weapon/implant/explosive/macro(src) + ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/implants/implant_freedom.dm b/code/game/objects/items/weapons/implants/implant_freedom.dm new file mode 100644 index 00000000000..e3e70e982a2 --- /dev/null +++ b/code/game/objects/items/weapons/implants/implant_freedom.dm @@ -0,0 +1,50 @@ +/obj/item/weapon/implant/freedom + name = "freedom implant" + desc = "Use this to escape from those evil Red Shirts." + icon_state = "freedom" + item_color = "r" + origin_tech = "materials=2;magnets=3;biotech=3;syndicate=4" + uses = 4 + + +/obj/item/weapon/implant/freedom/activate() + if(uses == 0) return 0 + if(uses != -1) uses-- + imp_in << "You feel a faint click." + if(iscarbon(imp_in)) + var/mob/living/carbon/C_imp_in = imp_in + C_imp_in.uncuff() + + +/obj/item/weapon/implant/freedom/get_data() + var/dat = {" +Implant Specifications:
+Name: Freedom Beacon
+Life: optimum 5 uses
+Important Notes: Illegal
+
+Implant Details:
+Function: Transmits a specialized cluster of signals to override handcuff locking +mechanisms
+Special Features:
+Neuro-Scan- Analyzes certain shadow signals in the nervous system
+
+No Implant Specifics"} + return dat + + +/obj/item/weapon/implanter/freedom + name = "implanter (freedom)" + +/obj/item/weapon/implanter/freedom/New() + imp = new /obj/item/weapon/implant/freedom(src) + ..() + + +/obj/item/weapon/implantcase/freedom + name = "implant case - 'Freedom'" + desc = "A glass case containing a freedom implant." + +/obj/item/weapon/implantcase/freedom/New() + imp = new /obj/item/weapon/implant/freedom(src) + ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/implants/implant_loyality.dm b/code/game/objects/items/weapons/implants/implant_loyality.dm new file mode 100644 index 00000000000..088c70bf3c1 --- /dev/null +++ b/code/game/objects/items/weapons/implants/implant_loyality.dm @@ -0,0 +1,59 @@ +/obj/item/weapon/implant/loyalty + name = "loyalty implant" + desc = "Makes you loyal or such." + origin_tech = "materials=2;biotech=4;programming=4" + activated = 0 + +/obj/item/weapon/implant/loyalty/get_data() + var/dat = {"Implant Specifications:
+ Name: Nanotrasen Employee Management Implant
+ Life: Ten years.
+ Important Notes: Personnel injected with this device tend to be much more loyal to the company.
+
+ Implant Details:
+ Function: Contains a small pod of nanobots that manipulate the host's mental functions.
+ Special Features: Will prevent and cure most forms of brainwashing.
+ Integrity: Implant will last so long as the nanobots are inside the bloodstream."} + return dat + + +/obj/item/weapon/implant/loyalty/implant(mob/target) + if(..()) + if(target.mind in ticker.mode.head_revolutionaries || is_shadow_or_thrall(target)) + target.visible_message("[target] seems to resist the implant!", "You feel the corporate tendrils of Nanotrasen try to invade your mind!") + removed(target, 1) + qdel(src) + return -1 + if(target.mind in ticker.mode.revolutionaries) + ticker.mode.remove_revolutionary(target.mind) + if(target.mind in ticker.mode.cult) + target << "You feel the corporate tendrils of Nanotrasen try to invade your mind!" + else + target << "You feel a surge of loyalty towards Nanotrasen." + return 1 + return 0 + +/obj/item/weapon/implant/loyalty/removed(mob/target, var/silent = 0) + if(..()) + if(target.stat != DEAD && !silent) + target << "You feel a sense of liberation as Nanotrasen's grip on your mind fades away." + return 1 + return 0 + + +/obj/item/weapon/implanter/loyalty + name = "implanter (loyalty)" + +/obj/item/weapon/implanter/loyalty/New() + imp = new /obj/item/weapon/implant/loyalty(src) + ..() + update_icon() + + +/obj/item/weapon/implantcase/loyalty + name = "implant case - 'Loyalty'" + desc = "A glass case containing a loyalty implant." + +/obj/item/weapon/implantcase/loyalty/New() + imp = new /obj/item/weapon/implant/loyalty(src) + ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/implants/implant_misc.dm b/code/game/objects/items/weapons/implants/implant_misc.dm new file mode 100644 index 00000000000..79b7285e2d4 --- /dev/null +++ b/code/game/objects/items/weapons/implants/implant_misc.dm @@ -0,0 +1,66 @@ +/obj/item/weapon/implant/weapons_auth + name = "firearms authentication implant" + desc = "Lets you shoot your guns" + icon_state = "auth" + origin_tech = "materials=2;magnets=2;programming=2;biotech=5;syndicate=5" + activated = 0 + +/obj/item/weapon/implant/weapons_auth/get_data() + var/dat = {"Implant Specifications:
+ Name: Firearms Authentication Implant
+ Life: 4 hours after death of host
+ Implant Details:
+ Function: Allows operation of implant-locked weaponry, preventing equipment from falling into enemy hands."} + return dat + + +/obj/item/weapon/implant/adrenalin + name = "adrenal implant" + desc = "Removes all stuns and knockdowns." + icon_state = "adrenal" + origin_tech = "materials=2;biotech=4;combat=3;syndicate=4" + uses = 3 + +/obj/item/weapon/implant/adrenalin/get_data() + var/dat = {"Implant Specifications:
+ Name: Cybersun Industries Adrenaline Implant
+ Life: Five days.
+ Important Notes: Illegal
+
+ Implant Details: Subjects injected with implant can activate an injection of medical cocktails.
+ Function: Removes stuns, increases speed, and has a mild healing effect.
+ Integrity: Implant can only be used three times before reserves are depleted."} + return dat + +/obj/item/weapon/implant/adrenalin/activate() + if(uses < 1) return 0 + uses-- + imp_in << "You feel a sudden surge of energy!" + imp_in.SetStunned(0) + imp_in.SetWeakened(0) + imp_in.SetParalysis(0) + imp_in.adjustStaminaLoss(-75) + imp_in.lying = 0 + imp_in.update_canmove() + + imp_in.reagents.add_reagent("synaptizine", 10) + imp_in.reagents.add_reagent("omnizine", 10) + imp_in.reagents.add_reagent("stimulative_agent", 10) + + +/obj/item/weapon/implant/emp + name = "emp implant" + desc = "Triggers an EMP." + icon_state = "emp" + origin_tech = "materials=2;biotech=3;magnets=4;syndicate=4" + uses = 2 + +/obj/item/weapon/implant/emp/activate() + if (src.uses < 1) return 0 + src.uses-- + empulse(imp_in, 3, 5) + +/obj/item/weapon/implant/cortical + name = "cortical stack" + desc = "A fist-sized mass of biocircuits and chips." + icon_state = "implant_evil" \ No newline at end of file diff --git a/code/game/objects/items/weapons/implants/implant_storage.dm b/code/game/objects/items/weapons/implants/implant_storage.dm new file mode 100644 index 00000000000..454c08f9df1 --- /dev/null +++ b/code/game/objects/items/weapons/implants/implant_storage.dm @@ -0,0 +1,57 @@ +/obj/item/weapon/storage/hidden/implant + name = "bluespace pocket" + storage_slots = 2 + max_w_class = 3 + max_combined_w_class = 6 + w_class = 4 + cant_hold = list(/obj/item/weapon/disk/nuclear) + silent = 1 + + +/obj/item/weapon/implant/storage + name = "storage implant" + desc = "Stores up to two big items in a bluespace pocket." + icon_state = "storage" + origin_tech = "materials=2;magnets=4;bluespace=4;syndicate=4" + item_color = "r" + var/obj/item/weapon/storage/hidden/implant/storage + +/obj/item/weapon/implant/storage/New() + ..() + storage = new /obj/item/weapon/storage/hidden/implant(src) + +/obj/item/weapon/implant/storage/activate() + storage.MouseDrop(imp_in) + +/obj/item/weapon/implant/storage/removed(source) + if(..()) + for(var/mob/M in range(1)) + if(M.s_active == storage) + storage.close(M) + for(var/obj/item/I in storage) + storage.remove_from_storage(I, get_turf(source)) + return 1 + +/obj/item/weapon/implant/storage/implant(mob/source) + var/obj/item/weapon/implant/storage/imp_e = locate(src.type) in source + if(imp_e) + imp_e.storage.storage_slots += storage.storage_slots + imp_e.storage.max_combined_w_class += storage.max_combined_w_class + imp_e.storage.contents += storage.contents + + for(var/mob/M in range(1)) + if(M.s_active == storage) + storage.close(M) + storage.show_to(source) + + qdel(src) + return 1 + + return ..() + +/obj/item/weapon/implanter/storage + name = "implanter (storage)" + +/obj/item/weapon/implanter/storage/New() + imp = new /obj/item/weapon/implant/storage(src) + ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/implants/implant_track.dm b/code/game/objects/items/weapons/implants/implant_track.dm new file mode 100644 index 00000000000..d0d1159a9c5 --- /dev/null +++ b/code/game/objects/items/weapons/implants/implant_track.dm @@ -0,0 +1,32 @@ +/obj/item/weapon/implant/tracking + name = "tracking implant" + desc = "Track with this." + activated = 0 + origin_tech = "materials=2;magnets=2;programming=2;biotech=2" + var/id = 1 + + +/obj/item/weapon/implant/tracking/New() + ..() + tracked_implants += src + +/obj/item/weapon/implant/tracking/Destroy() + tracked_implants -= src + return ..() + +/obj/item/weapon/implant/tracking/get_data() + var/dat = {"Implant Specifications:
+ Name: Tracking Beacon
+ Life: 10 minutes after death of host
+ Important Notes: None
+
+ Implant Details:
+ Function: Continuously transmits low power signal. Useful for tracking.
+ Special Features:
+ Neuro-Safe- Specialized shell absorbs excess voltages self-destructing the chip if + a malfunction occurs thereby securing safety of subject. The implant will melt and + disintegrate into bio-safe elements.
+ Integrity: Gradient creates slight risk of being overcharged and frying the + circuitry. As a result neurotoxins can cause massive damage.
+ Implant Specifics:
"} + return dat diff --git a/code/game/objects/items/weapons/implants/implant_traitor.dm b/code/game/objects/items/weapons/implants/implant_traitor.dm new file mode 100644 index 00000000000..fdb30eaae8e --- /dev/null +++ b/code/game/objects/items/weapons/implants/implant_traitor.dm @@ -0,0 +1,80 @@ +/obj/item/weapon/implant/traitor + name = "Mindslave Implant" + desc = "Divide and Conquer" + origin_tech = "programming=5;biotech=5;syndicate=8" + activated = 0 + +/obj/item/weapon/implant/traitor/get_data() + var/dat = {"Implant Specifications:
+ Name: Mind-Slave Implant
+ Life: ???
+ Important Notes: Any humanoid injected with this implant will become loyal to the injector, unless of course the host is already loyal to someone else.
+
+ Implant Details:
+ Function: Contains a small pod of nanobots that manipulate the host's mental functions.
+ Special Features: Diplomacy was never so easy.
+ Integrity: Implant will last so long as the nanobots are inside the bloodstream."} + return dat + +/obj/item/weapon/implant/traitor/implant(mob/M, mob/user) + if(!activated) //So you can't just keep taking it out and putting it back into other people. + var/mob/living/carbon/human/H = M + if(ismindslave(H)) + H.visible_message("[H] seems to resist the implant!", "You feel a strange sensation in your head that quickly dissipates.") + qdel(src) + return -1 + if(..()) + var/list/implanters + var/ref = "\ref[user.mind]" + if(!ishuman(M)) + return 0 + if(!M.mind) + return 0 + if(M == user) + user << "Making yourself loyal to yourself was a great idea! Perhaps even the best idea ever! Actually, you just feel like an idiot." + if(isliving(user)) + var/mob/living/L = user + L.adjustBrainLoss(20) + removed(M) + qdel(src) + return -1 + if(isloyal(H)) + H.visible_message("[H] seems to resist the implant!", "You feel a strange sensation in your head that quickly dissipates.") + removed(M) + qdel(src) + return -1 + H.implanting = 1 + H << "You feel completely loyal to [user.name]." + if(!(user.mind in ticker.mode:implanter)) + ticker.mode:implanter[ref] = list() + implanters = ticker.mode:implanter[ref] + implanters.Add(H.mind) + ticker.mode.implanted.Add(H.mind) + ticker.mode.implanted[H.mind] = user.mind + //ticker.mode:implanter[user.mind] += H.mind + ticker.mode:implanter[ref] = implanters + ticker.mode.traitors += H.mind + H.mind.special_role = "traitor" + H << "You're now completely loyal to [user.name]! You now must lay down your life to protect them and assist in their goals at any cost." + var/datum/objective/protect/p = new + p.owner = H.mind + p.target = user:mind + p.explanation_text = "Obey every order from and protect [user:real_name], the [user:mind:assigned_role=="MODE" ? (user:mind:special_role) : (user:mind:assigned_role)]." + H.mind.objectives += p + for(var/datum/objective/objective in H.mind.objectives) + H << "Objective #1: [objective.explanation_text]" + + ticker.mode.update_traitor_icons_added(user.mind) + ticker.mode.update_traitor_icons_added(H.mind)//handles datahuds/observerhuds + + if(user.mind.som)//do not add if not a traitor..and you just picked up an implanter in the hall... + var/datum/mindslaves/slaved = user.mind.som + H.mind.som = slaved + slaved.serv += H + slaved.add_serv_hud(user.mind,"syndicate")//handles master servent icons + slaved.add_serv_hud(H.mind,"mindslave") + + log_admin("[ckey(user.key)] has mind-slaved [ckey(H.key)].") + activated = 1 + return 1 + return 0 \ No newline at end of file diff --git a/code/game/objects/items/weapons/implants/implantcase.dm b/code/game/objects/items/weapons/implants/implantcase.dm index 742717c1b70..41354136648 100644 --- a/code/game/objects/items/weapons/implants/implantcase.dm +++ b/code/game/objects/items/weapons/implants/implantcase.dm @@ -1,171 +1,101 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 - /obj/item/weapon/implantcase - name = "Glass Case" - desc = "A case containing an implant." + name = "implant case" + desc = "A glass case containing an implant." + icon = 'icons/obj/items.dmi' icon_state = "implantcase-0" item_state = "implantcase" - throw_speed = 1 + throw_speed = 2 throw_range = 5 - w_class = 1.0 + w_class = 1 origin_tech = "materials=1;biotech=2" materials = list(MAT_GLASS=500) var/obj/item/weapon/implant/imp = null - New() - ..() - update() - proc - update() +/obj/item/weapon/implantcase/update_icon() + if(imp) + icon_state = "implantcase-[imp.item_color]" + origin_tech = imp.origin_tech + flags = imp.flags + reagents = imp.reagents + else + icon_state = "implantcase-0" + origin_tech = initial(origin_tech) + flags = initial(flags) + reagents = null - update() - if (src.imp) - src.icon_state = text("implantcase-[]", src.imp.item_color) - src.origin_tech = src.imp.origin_tech +/obj/item/weapon/implantcase/attackby(obj/item/weapon/W, mob/user, params) + ..() + if(istype(W, /obj/item/weapon/pen)) + var/t = stripped_input(user, "What would you like the label to be?", name, null) + if(user.get_active_hand() != W) + return + if(!in_range(src, user) && loc != user) + return + if(t) + name = "implant case - '[t]'" else - src.icon_state = "implantcase-0" - src.origin_tech = initial(src.origin_tech) - return - - - attackby(obj/item/weapon/I as obj, mob/user as mob, params) - ..() - if (istype(I, /obj/item/weapon/pen)) - var/t = input(user, "What would you like the label to be?", text("[]", src.name), null) as text - if (user.get_active_hand() != I) + name = "implant case" + else if(istype(W, /obj/item/weapon/implanter)) + var/obj/item/weapon/implanter/I = W + if(I.imp) + if(imp || I.imp.implanted) return - if((!in_range(src, usr) && src.loc != user)) - return - t = sanitize(copytext(t,1,MAX_MESSAGE_LEN)) - if(t) - src.name = text("Glass Case- '[]'", t) - else - src.name = "Glass Case" - else if(istype(I, /obj/item/weapon/reagent_containers/syringe)) - if(!src.imp) return - if(!src.imp.allow_reagents) return - if(src.imp.reagents.total_volume >= src.imp.reagents.maximum_volume) - user << "\red [src] is full." - else - spawn(5) - I.reagents.trans_to(src.imp, 5) - user << "\blue You inject 5 units of the solution. The syringe now contains [I.reagents.total_volume] units." - else if (istype(I, /obj/item/weapon/implanter)) - if (I:imp) - if ((src.imp || I:imp.implanted)) + I.imp.loc = src + imp = I.imp + I.imp = null + update_icon() + I.update_icon() + else + if(imp) + if(I.imp) return - I:imp.loc = src - src.imp = I:imp - I:imp = null - src.update() - I:update() - else - if (src.imp) - if (I:imp) - return - src.imp.loc = I - I:imp = src.imp - src.imp = null - update() - I:update() - return + imp.loc = I + I.imp = imp + imp = null + update_icon() + I.update_icon() + /*else if(istype(W, /obj/item/ammo_casing/shotgun/implanter)) + var/obj/item/ammo_casing/shotgun/implanter/I = W + if(I.implanter) + src.attackby(I.implanter, user, params) */ // COMING SOON -- c0 + +/obj/item/weapon/implantcase/New() + ..() + update_icon() /obj/item/weapon/implantcase/tracking - name = "Glass Case- 'Tracking'" - desc = "A case containing a tracking implant." - icon = 'icons/obj/items.dmi' - icon_state = "implantcase-b" + name = "implant case - 'Tracking'" + desc = "A glass case containing a tracking implant." - - New() - src.imp = new /obj/item/weapon/implant/tracking( src ) - ..() - return - - - -/obj/item/weapon/implantcase/explosive - name = "Glass Case- 'Explosive'" - desc = "A case containing an explosive implant." - icon = 'icons/obj/items.dmi' - icon_state = "implantcase-r" - - - New() - src.imp = new /obj/item/weapon/implant/explosive( src ) - ..() - return - -/obj/item/weapon/implantcase/dexplosive - name = "Glass Case- 'Death Explosive'" - desc = "A case containing an explosive implant." - icon = 'icons/obj/items.dmi' - icon_state = "implantcase-r" - - - New() - src.imp = new /obj/item/weapon/implant/dexplosive( src ) - ..() - return - -/obj/item/weapon/implantcase/chem - name = "Glass Case- 'Chem'" - desc = "A case containing a chemical implant." - icon = 'icons/obj/items.dmi' - icon_state = "implantcase-b" -/obj/item/weapon/implantcase/chem/New() - - src.imp = new /obj/item/weapon/implant/chem( src ) +/obj/item/weapon/implantcase/tracking/New() + imp = new /obj/item/weapon/implant/tracking(src) ..() - return -/obj/item/weapon/implantcase/loyalty - name = "Glass Case- 'Loyalty'" - desc = "A case containing a loyalty implant." - icon = 'icons/obj/items.dmi' - icon_state = "implantcase-r" +/obj/item/weapon/implantcase/weapons_auth + name = "implant case - 'Firearms Authentication'" + desc = "A glass case containing a firearms authentication implant." +/obj/item/weapon/implantcase/weapons_auth/New() + imp = new /obj/item/weapon/implant/weapons_auth(src) + ..() - New() - src.imp = new /obj/item/weapon/implant/loyalty( src ) - ..() - return +/obj/item/weapon/implantcase/adrenaline + name = "implant case - 'Adrenaline'" + desc = "A glass case containing an adrenaline implant." +/obj/item/weapon/implantcase/adrenaline/New() + imp = new /obj/item/weapon/implant/adrenalin(src) + ..() /obj/item/weapon/implantcase/death_alarm name = "Glass Case- 'Death Alarm'" desc = "A case containing a death alarm implant." - icon = 'icons/obj/items.dmi' - icon_state = "implantcase-b" - New() - src.imp = new /obj/item/weapon/implant/death_alarm( src ) - ..() - return - -/obj/item/weapon/implantcase/freedom - name = "Glass Case- 'Freedom'" - desc = "A case containing a freedom implant." - icon = 'icons/obj/items.dmi' - icon_state = "implantcase-b" - - New() - src.imp = new /obj/item/weapon/implant/freedom( src ) - ..() - return - -/obj/item/weapon/implantcase/adrenaline - name = "Glass Case- 'Adrenaline'" - desc = "A glass case containing an adrenaline implant." - icon = 'icons/obj/items.dmi' - icon_state = "implantcase-b" - - New() - src.imp = new /obj/item/weapon/implant/adrenalin( src ) - ..() - return \ No newline at end of file +/obj/item/weapon/implantcase/death_alarm/New() + imp = new /obj/item/weapon/implant/death_alarm(src) + ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/implants/implantchair.dm b/code/game/objects/items/weapons/implants/implantchair.dm index dc9f95ad322..9a5633c0ba3 100644 --- a/code/game/objects/items/weapons/implants/implantchair.dm +++ b/code/game/objects/items/weapons/implants/implantchair.dm @@ -1,7 +1,7 @@ //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 /obj/machinery/implantchair - name = "Loyalty Implanter" + name = "loyalty implanter" desc = "Used to implant occupants with loyalty implants." icon = 'icons/obj/machines/implantchair.dmi' icon_state = "implantchair" @@ -19,153 +19,148 @@ var/mob/living/carbon/occupant = null var/injecting = 0 - proc - go_out() - put_mob(mob/living/carbon/M as mob) - implant(var/mob/M) - add_implants() - - - New() - ..() - add_implants() - - - attack_hand(mob/user as mob) - user.set_machine(src) - var/health_text = "" - if(src.occupant) - if(src.occupant.health <= -100) - health_text = "Dead" - else if(src.occupant.health < 0) - health_text = "[round(src.occupant.health,0.1)]" - else - health_text = "[round(src.occupant.health,0.1)]" - - var/dat ="Implanter Status
" - - dat +="Current occupant: [src.occupant ? "
Name: [src.occupant]
Health: [health_text]
" : "None"]
" - dat += "Implants: [src.implant_list.len ? "[implant_list.len]" : "Replenish"]
" - if(src.occupant) - dat += "[src.ready ? "Implant" : "Recharging"]
" - user.set_machine(src) - user << browse(dat, "window=implant") - onclose(user, "implant") - - - Topic(href, href_list) - if((get_dist(src, usr) <= 1) || istype(usr, /mob/living/silicon/ai)) - if(href_list["implant"]) - if(src.occupant) - injecting = 1 - go_out() - ready = 0 - spawn(injection_cooldown) - ready = 1 - - if(href_list["replenish"]) - ready = 0 - spawn(replenish_cooldown) - add_implants() - ready = 1 - - src.updateUsrDialog() - src.add_fingerprint(usr) - return - - - attackby(var/obj/item/weapon/G as obj, var/mob/user as mob, params) - if(istype(G, /obj/item/weapon/grab)) - if(!ismob(G:affecting)) - return - for(var/mob/living/carbon/slime/M in range(1,G:affecting)) - if(M.Victim == G:affecting) - usr << "[G:affecting:name] will not fit into the [src.name] because they have a slime latched onto their head." - return - var/mob/M = G:affecting - if(put_mob(M)) - qdel(G) - src.updateUsrDialog() - return - - - go_out(var/mob/M) - if(!( src.occupant )) - return - if(M == occupant) // so that the guy inside can't eject himself -Agouri - return - if (src.occupant.client) - src.occupant.client.eye = src.occupant.client.mob - src.occupant.client.perspective = MOB_PERSPECTIVE - src.occupant.loc = src.loc - if(injecting) - implant(src.occupant) - injecting = 0 - src.occupant = null - icon_state = "implantchair" - return - - - put_mob(mob/living/carbon/M as mob) - if(!iscarbon(M)) - usr << "\red The [src.name] cannot hold this!" - return - if(src.occupant) - usr << "\red The [src.name] is already occupied!" - return - if(M.client) - M.client.perspective = EYE_PERSPECTIVE - M.client.eye = src - M.stop_pulling() - M.loc = src - src.occupant = M - src.add_fingerprint(usr) - icon_state = "implantchair_on" - return 1 - - +/obj/machinery/implantchair/proc + go_out() + put_mob(mob/living/carbon/M) implant(var/mob/M) - if (!istype(M, /mob/living/carbon)) - return - if(!implant_list.len) return - for(var/obj/item/weapon/implant/loyalty/imp in implant_list) - if(!imp) continue - if(istype(imp, /obj/item/weapon/implant/loyalty)) - for (var/mob/O in viewers(M, null)) - O.show_message("\red [M] has been implanted by the [src.name].", 1) - - if(imp.implanted(M)) - imp.loc = M - imp.imp_in = M - imp.implanted = 1 - implant_list -= imp - break - return - - add_implants() - for(var/i=0, iName: [src.occupant]
Health: [health_text]
" : "None"]
" + dat += "Implants: [src.implant_list.len ? "[implant_list.len]" : "Replenish"]
" + if(src.occupant) + dat += "[src.ready ? "Implant" : "Recharging"]
" + user.set_machine(src) + user << browse(dat, "window=implant") + onclose(user, "implant") + + +/obj/machinery/implantchair/Topic(href, href_list) + if(..()) return + if(href_list["implant"]) + if(src.occupant) + injecting = 1 + go_out() + ready = 0 + spawn(injection_cooldown) + ready = 1 - verb - get_out() - set name = "Eject occupant" - set category = "Object" - set src in oview(1) - if(usr.stat != 0) - return - src.go_out(usr) - add_fingerprint(usr) + if(href_list["replenish"]) + ready = 0 + spawn(replenish_cooldown) + add_implants() + ready = 1 + + src.updateUsrDialog() + return + + +/obj/machinery/implantchair/attackby(obj/item/weapon/W, mob/user, params) + if(istype(W, /obj/item/weapon/grab)) + var/obj/item/weapon/grab/G = W + if(!ismob(G.affecting)) return - - - move_inside() - set name = "Move Inside" - set category = "Object" - set src in oview(1) - if(usr.stat != 0 || stat & (NOPOWER|BROKEN)) - return - put_mob(usr) + var/mob/M = G.affecting + if(M.buckled_mob) + usr << "[M] will not fit into [src] because they have a slime latched onto their head." return + if(put_mob(M)) + qdel(G) + src.updateUsrDialog() + return + + +/obj/machinery/implantchair/go_out(mob/M) + if(!( src.occupant )) + return + if(M == occupant) // so that the guy inside can't eject himself -Agouri + return + if (src.occupant.client) + src.occupant.client.eye = src.occupant.client.mob + src.occupant.client.perspective = MOB_PERSPECTIVE + src.occupant.loc = src.loc + if(injecting) + implant(src.occupant) + injecting = 0 + src.occupant = null + icon_state = "implantchair" + return + + +/obj/machinery/implantchair/put_mob(mob/living/carbon/M) + if(!iscarbon(M)) + usr << "The [src.name] cannot hold this!" + return + if(src.occupant) + usr << "The [src.name] is already occupied!" + return + if(M.client) + M.client.perspective = EYE_PERSPECTIVE + M.client.eye = src + M.stop_pulling() + M.loc = src + src.occupant = M + src.add_fingerprint(usr) + icon_state = "implantchair_on" + return 1 + + +/obj/machinery/implantchair/implant(mob/M) + if (!istype(M, /mob/living/carbon)) + return + if(!implant_list.len) return + for(var/obj/item/weapon/implant/loyalty/imp in implant_list) + if(!imp) continue + if(istype(imp, /obj/item/weapon/implant/loyalty)) + M.visible_message("[M] has been implanted by the [src.name].") + + if(imp.implant(M)) + implant_list -= imp + break + return + + +/obj/machinery/implantchair/add_implants() + for(var/i=0, i[user] is attemping to implant [M].") + + var/turf/T = get_turf(M) + if(T && (M == user || do_after(user, 50, target = M))) + if(user && M && (get_turf(M) == T) && src && imp) + if(imp.implant(M, user)) + if (M == user) + user << "You implant yourself." + else + M.visible_message("[user] has implanted [M].", "[user] implants you.") + imp = null + update_icon() + +/obj/item/weapon/implanter/attackby(obj/item/weapon/W, mob/user, params) + ..() + if(istype(W, /obj/item/weapon/pen)) + var/t = stripped_input(user, "What would you like the label to be?", name, null) + if(user.get_active_hand() != W) + return + if(!in_range(src, user) && loc != user) + return + if(t) + name = "implanter ([t])" + else + name = "implanter" + /obj/item/weapon/implanter/New() ..() - update() - -/obj/item/weapon/implanter/proc/update() - - -/obj/item/weapon/implanter/update() - if (src.imp) - src.icon_state = "implanter1" - src.origin_tech = src.imp.origin_tech - else - src.icon_state = "implanter0" - src.origin_tech = initial(src.origin_tech) - return - - -/obj/item/weapon/implanter/attack(mob/M as mob, mob/user as mob) - if (!istype(M, /mob/living/carbon)) - return - if (user && src.imp) - for (var/mob/O in viewers(M, null)) - O.show_message("\red [user] is attemping to implant [M].", 1) - - var/turf/T1 = get_turf(M) - if (T1 && ((M == user) || do_after(user, 50, target = M))) - if(user && M && (get_turf(M) == T1) && src && src.imp) - for (var/mob/O in viewers(M, null)) - O.show_message("\red [M] has been implanted by [user].", 1) - - M.attack_log += text("\[[time_stamp()]\] Implanted with [src.name] ([src.imp.name]) by [key_name(user)]") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] ([src.imp.name]) to implant [key_name(M)]") - msg_admin_attack("[key_name_admin(user)] implanted [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])") - - user.show_message("\red You implanted the implant into [M].") - if(src.imp.implanted(M, user)) - src.imp.loc = M - src.imp.imp_in = M - src.imp.implanted = 1 - if (ishuman(M)) - var/mob/living/carbon/human/H = M - var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) - affected.implants += src.imp - imp.part = affected - H.sec_hud_set_implants() - M:implanting = 0 - src.imp = null - update() + spawn(1) + update_icon() -/obj/item/weapon/implanter/traitor - name = "implanter (Mindslave)" - desc = "Divide and Conquer." - - New() - src.imp = new /obj/item/weapon/implant/traitor(src) - ..() - update() - return - -/obj/item/weapon/implanter/loyalty - name = "implanter (Loyalty)" - -/obj/item/weapon/implanter/loyalty/New() - src.imp = new /obj/item/weapon/implant/loyalty( src ) - ..() - update() - return - -/obj/item/weapon/implanter/dexplosive - name = "implanter (Microbomb)" - -/obj/item/weapon/implanter/dexplosive/New() - src.imp = new /obj/item/weapon/implant/dexplosive( src ) - ..() - update() - return - -/obj/item/weapon/implanter/explosive - name = "implanter (Explosive)" - -/obj/item/weapon/implanter/explosive/New() - src.imp = new /obj/item/weapon/implant/explosive( src ) - ..() - update() - return /obj/item/weapon/implanter/adrenalin - name = "implanter (Adrenaline)" + name = "implanter (adrenalin)" /obj/item/weapon/implanter/adrenalin/New() - src.imp = new /obj/item/weapon/implant/adrenalin(src) - ..() - update() - return - -/obj/item/weapon/implanter/compressed - name = "implanter (Compressed)" - icon_state = "cimplanter1" - - var/list/forbidden_types=list( - // /obj/item/weapon/storage/bible // VG #11 - Recursion. - ) - -/obj/item/weapon/implanter/compressed/New() - imp = new /obj/item/weapon/implant/compressed( src ) - ..() - update() - return - -/obj/item/weapon/implanter/compressed/update() - if (imp) - var/obj/item/weapon/implant/compressed/c = imp - if(!c.scanned) - icon_state = "cimplanter1" - else - icon_state = "cimplanter2" - else - icon_state = "cimplanter0" - return - -/obj/item/weapon/implanter/compressed/attack(mob/M as mob, mob/user as mob) - // Attacking things in your hands tends to make this fuck up. - if(!istype(M)) - return - var/obj/item/weapon/implant/compressed/c = imp - if (!c) return - if (c.scanned == null) - user << "Please scan an object with the implanter first." - return + imp = new /obj/item/weapon/implant/adrenalin(src) ..() -/obj/item/weapon/implanter/compressed/afterattack(var/obj/item/I, mob/user as mob) - if(is_type_in_list(I,forbidden_types)) - user << "\red A red light flickers on the implanter." - return - if(istype(I) && imp) - var/obj/item/weapon/implant/compressed/c = imp - if (c.scanned) - user << "\red Something is already scanned inside the implant!" - return - if(user) - user.unEquip(I) - user.update_icons() //update our overlays - c.scanned = I - c.scanned.loc = c - update() - -/obj/item/weapon/implanter/deadman - name = "implanter (Deadman)" - desc = "Switch it." - - New() - src.imp = new /obj/item/weapon/implant/deadman(src) - ..() - update() - return - -/obj/item/weapon/implanter/death_alarm - name = "implanter (Death Alarm)" - desc = "Announces the death of the implanted person over radio" - - New() - src.imp = new /obj/item/weapon/implant/death_alarm(src) - ..() - update() - return /obj/item/weapon/implanter/emp name = "implanter (EMP)" - New() - src.imp = new /obj/item/weapon/implant/emp(src) - ..() - update() - return +/obj/item/weapon/implanter/emp/New() + imp = new /obj/item/weapon/implant/emp(src) + ..() -/obj/item/weapon/implanter/freedom - name = "implanter (Freedom)" +/obj/item/weapon/implanter/traitor + name = "implanter (Mindslave)" - New() - src.imp = new /obj/item/weapon/implant/freedom(src) - ..() - update() - return +/obj/item/weapon/implanter/traitor/New() + imp = new /obj/item/weapon/implant/traitor(src) + ..() -/obj/item/weapon/implanter/uplink - name = "implanter (Uplink)" - - New() - src.imp = new /obj/item/weapon/implant/uplink(src) - ..() - update() - return \ No newline at end of file diff --git a/code/game/objects/items/weapons/implants/implantfreedom.dm b/code/game/objects/items/weapons/implants/implantfreedom.dm deleted file mode 100644 index 978b6eb237b..00000000000 --- a/code/game/objects/items/weapons/implants/implantfreedom.dm +++ /dev/null @@ -1,73 +0,0 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 - -/obj/item/weapon/implant/freedom - name = "freedom" - desc = "Use this to escape from those evil Red Shirts." - item_color = "r" - var/activation_emote = "chuckle" - origin_tech = "materials=2;magnets=3;biotech=3;syndicate=4" - var/uses = 4 - - - New() - src.activation_emote = pick("blink", "blink_r", "eyebrow", "chuckle", "twitch_s", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink") - ..() - return - - - trigger(emote, mob/living/carbon/source as mob) - if (src.uses < 1) return 0 - if (emote == src.activation_emote) - src.uses-- - source << "You feel a faint click." - if (source.handcuffed) - var/obj/item/weapon/W = source.handcuffed - source.handcuffed = null - if(source.buckled && source.buckled.buckle_requires_restraints) - source.buckled.unbuckle_mob() - source.update_inv_handcuffed() - if (source.client) - source.client.screen -= W - if (W) - W.loc = source.loc - dropped(source) - if (W) - W.layer = initial(W.layer) - if (source.legcuffed) - var/obj/item/weapon/W = source.legcuffed - source.legcuffed = null - source.update_inv_legcuffed() - if (source.client) - source.client.screen -= W - if (W) - W.loc = source.loc - dropped(source) - if (W) - W.layer = initial(W.layer) - return - - - implanted(mob/living/carbon/source) - source.mind.store_memory("Freedom implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", 0, 0) - source << "The implanted freedom implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate." - return 1 - - - get_data() - var/dat = {" -Implant Specifications:
-Name: Freedom Beacon
-Life: optimum 5 uses
-Important Notes: Illegal
-
-Implant Details:
-Function: Transmits a specialized cluster of signals to override handcuff locking -mechanisms
-Special Features:
-Neuro-Scan- Analyzes certain shadow signals in the nervous system
-Integrity: The battery is extremely weak and commonly after injection its -life can drive down to only 1 use.
-No Implant Specifics"} - return dat - - diff --git a/code/game/objects/items/weapons/implants/implantpad.dm b/code/game/objects/items/weapons/implants/implantpad.dm index 4d8b07abc63..98aca2efe5d 100644 --- a/code/game/objects/items/weapons/implants/implantpad.dm +++ b/code/game/objects/items/weapons/implants/implantpad.dm @@ -6,11 +6,11 @@ icon = 'icons/obj/items.dmi' icon_state = "implantpad-0" item_state = "electronic" - throw_speed = 1 + throw_speed = 3 throw_range = 5 - w_class = 2.0 + w_class = 2 var/obj/item/weapon/implantcase/case = null - + /obj/item/weapon/implantpad/Destroy() if(case) dropcase() @@ -22,7 +22,7 @@ else src.icon_state = "implantpad-0" return - + /obj/item/weapon/implantpad/proc/addcase(mob/user as mob, obj/item/weapon/implantcase/C as obj) if(!user || !C) return @@ -33,8 +33,8 @@ C.forceMove(src) case = C update_icon() - -/obj/item/weapon/implantpad/proc/dropcase(mob/user as mob) + +/obj/item/weapon/implantpad/proc/dropcase(mob/user as mob) if(!case) user << "There's no implant in the pad!" return @@ -45,7 +45,7 @@ case = null update_icon() return - + case.forceMove(get_turf(src)) case = null update_icon() @@ -54,10 +54,10 @@ set category = "Object" set name = "Remove Implant" set src in usr - + if (usr.stat || usr.restrained()) return - + dropcase(usr) /obj/item/weapon/implantpad/attackby(obj/item/weapon/implantcase/C as obj, mob/user as mob, params) @@ -103,7 +103,7 @@ T.id = min(100, T.id) T.id = max(1, T.id) else if(href_list["removecase"]) - dropcase(user) - + dropcase(user) + attack_self(user) return 1 diff --git a/code/game/objects/items/weapons/implants/implantuplink.dm b/code/game/objects/items/weapons/implants/implantuplink.dm index 6e7fac76a6c..3ccea8aee20 100644 --- a/code/game/objects/items/weapons/implants/implantuplink.dm +++ b/code/game/objects/items/weapons/implants/implantuplink.dm @@ -1,25 +1,35 @@ /obj/item/weapon/implant/uplink - name = "uplink" + name = "uplink implant" desc = "Summon things." + icon = 'icons/obj/radio.dmi' + icon_state = "radio" origin_tech = "materials=2;magnets=4;programming=4;biotech=4;syndicate=8;bluespace=5" - var/activation_emote = "chuckle" /obj/item/weapon/implant/uplink/New() - activation_emote = pick("blink", "blink_r", "eyebrow", "chuckle", "twitch_s", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink") hidden_uplink = new(src) hidden_uplink.uses = 10 ..() - return -/obj/item/weapon/implant/uplink/implanted(mob/source) - activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch_s", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink") - source.mind.store_memory("Uplink implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", 0, 0) - source << "The implanted uplink implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate." - hidden_uplink.uplink_owner="[source]" - return 1 +/obj/item/weapon/implant/uplink/implant(mob/source) + var/obj/item/weapon/implant/imp_e = locate(src.type) in source + if(imp_e && imp_e != src) + imp_e.hidden_uplink.uses += hidden_uplink.uses + qdel(src) + return 1 + + if(..()) + hidden_uplink.uplink_owner="[source.key]" + return 1 + return 0 + +/obj/item/weapon/implant/uplink/activate() + if(hidden_uplink) + hidden_uplink.check_trigger(imp_in) -/obj/item/weapon/implant/uplink/trigger(emote, mob/source as mob) - if(hidden_uplink && usr == source) // Let's not have another people activate our uplink - hidden_uplink.check_trigger(source, emote, activation_emote) - return \ No newline at end of file +/obj/item/weapon/implanter/uplink + name = "implanter (uplink)" + +/obj/item/weapon/implanter/uplink/New() + imp = new /obj/item/weapon/implant/uplink(src) + ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/kitchen.dm b/code/game/objects/items/weapons/kitchen.dm index 2fbd6589562..d6d0c8cf000 100644 --- a/code/game/objects/items/weapons/kitchen.dm +++ b/code/game/objects/items/weapons/kitchen.dm @@ -25,6 +25,7 @@ flags = CONDUCT origin_tech = "materials=1" attack_verb = list("attacked", "stabbed", "poked") + hitsound = 'sound/weapons/bladeslice.ogg' sharp = 0 var/loaded //Descriptive string for currently loaded food object. @@ -110,8 +111,8 @@ if ((CLUMSY in user.mutations) && prob(50)) user << "\red You accidentally cut yourself with the [src]." user.take_organ_damage(20) + playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1) return - playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1) return ..() /obj/item/weapon/kitchen/utensil/pknife @@ -121,14 +122,6 @@ force = 10.0 throwforce = 10.0 -/obj/item/weapon/kitchen/utensil/knife/attack(target as mob, mob/living/user as mob) - if ((CLUMSY in user.mutations) && prob(50)) - user << "\red You somehow managed to cut yourself with the [src]." - user.take_organ_damage(20) - return - playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1) - return ..() - /* * Kitchen knives */ @@ -148,6 +141,7 @@ materials = list(MAT_METAL=12000) origin_tech = "materials=1" attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + hitsound = 'sound/weapons/bladeslice.ogg' suicide_act(mob/user) viewers(user) << pick("[user] is slitting \his wrists with the [src.name]! It looks like \he's trying to commit suicide.", \ @@ -190,21 +184,18 @@ materials = list(MAT_METAL=12000) origin_tech = "materials=1" attack_verb = list("cleaved", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + hitsound = 'sound/weapons/bladeslice.ogg' sharp = 1 edge = 1 /obj/item/weapon/butch/meatcleaver name = "Meat Cleaver" icon_state = "mcleaver" + item_state = "butch" desc = "A huge thing used for chopping and chopping up meat. This includes clowns and clown-by-products." force = 25.0 throwforce = 15.0 no_embed = 1 - -/obj/item/weapon/butch/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) - playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1) - return ..() - /* * Rolling Pins */ diff --git a/code/game/objects/items/weapons/lighters.dm b/code/game/objects/items/weapons/lighters.dm index d40799ef1b9..d80c28704ad 100644 --- a/code/game/objects/items/weapons/lighters.dm +++ b/code/game/objects/items/weapons/lighters.dm @@ -9,7 +9,7 @@ item_state = "lighter-g" var/icon_on = "lighter-g-on" var/icon_off = "lighter-g" - w_class = 1 + w_class = 2 throwforce = 4 flags = CONDUCT slot_flags = SLOT_BELT diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index c442b998991..040a42b4cb8 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -42,6 +42,10 @@ w_class = initial(w_class) playsound(user, 'sound/weapons/saberoff.ogg', 35, 1) //changed it from 50% volume to 35% because deafness user << "[src] can now be concealed." + if(istype(user,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = user + H.update_inv_l_hand() + H.update_inv_r_hand() add_fingerprint(user) return @@ -173,9 +177,9 @@ // Updating overlays, copied from welder code. // I tried calling attack_self twice, which looked cool, except it somehow didn't update the overlays!! if(user.r_hand == src) - user.update_inv_r_hand(0) + user.update_inv_r_hand() else if(user.l_hand == src) - user.update_inv_l_hand(0) + user.update_inv_l_hand() else user << "It's already fabulous!" diff --git a/code/game/objects/items/weapons/scrolls.dm b/code/game/objects/items/weapons/scrolls.dm index ba66e57f19e..8458058c131 100644 --- a/code/game/objects/items/weapons/scrolls.dm +++ b/code/game/objects/items/weapons/scrolls.dm @@ -54,6 +54,10 @@ if(!((user == loc || (in_range(src, user) && istype(src.loc, /turf))))) return + if(thearea.tele_proof && !istype(thearea, /area/wizard_station)) + user << "A mysterious force disrupts your arcane spell matrix, and you remain where you are." + return + var/datum/effect/system/harmless_smoke_spread/smoke = new /datum/effect/system/harmless_smoke_spread() smoke.set_up(5, 0, user.loc) smoke.attach(user) diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index 975a77eeca1..f460aaa1b47 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -158,13 +158,17 @@ icon = 'icons/obj/cigarettes.dmi' icon_state = "cigpacket" item_state = "cigpacket" - w_class = 1 + w_class = 2 throwforce = 2 slot_flags = SLOT_BELT storage_slots = 6 - can_hold = list("/obj/item/clothing/mask/cigarette") + max_combined_w_class = 6 + can_hold = list("/obj/item/clothing/mask/cigarette", + "/obj/item/weapon/lighter", + "/obj/item/weapon/match") cant_hold = list("/obj/item/clothing/mask/cigarette/cigar", - "/obj/item/clothing/mask/cigarette/pipe") + "/obj/item/clothing/mask/cigarette/pipe", + "/obj/item/weapon/lighter/zippo") icon_type = "cigarette" var/list/unlaced_cigarettes = list() // Cigarettes that haven't received reagents yet var/default_reagents = list("nicotine" = 15) // List of reagents to pre-generate for each cigarette @@ -206,15 +210,38 @@ return if(istype(M) && M == user && user.zone_sel.selecting == "mouth" && contents.len > 0 && !user.wear_mask) - var/obj/item/clothing/mask/cigarette/C = contents[contents.len] - if(!istype(C)) return - lace_cigarette(C) - user.equip_to_slot_if_possible(C, slot_wear_mask) - user << "You take a cigarette out of the pack." - update_icon() + var/got_cig = 0 + for(var/num=1, num <= contents.len, num++) + var/obj/item/I = contents[num] + if(istype(I, /obj/item/clothing/mask/cigarette)) + var/obj/item/clothing/mask/cigarette/C = I + lace_cigarette(C) + user.equip_to_slot_if_possible(C, slot_wear_mask) + user << "You take \a [C.name] out of the pack." + update_icon() + got_cig = 1 + break + if(!got_cig) + user << "There are no smokables in the pack!" else ..() +/obj/item/weapon/storage/fancy/cigarettes/can_be_inserted(obj/item/W as obj, stop_messages = 0) + if(istype(W, /obj/item/weapon/match)) + var/obj/item/weapon/match/M = W + if(M.lit == 1) + if(!stop_messages) + usr << "Putting a lit [W] in [src] probably isn't a good idea." + return 0 + if(istype(W, /obj/item/weapon/lighter)) + var/obj/item/weapon/lighter/L = W + if(L.lit == 1) + if(!stop_messages) + usr << "Putting [W] in [src] while lit probably isn't a good idea." + return 0 + //if we get this far, handle the insertion checks as normal + .=..() + /obj/item/weapon/storage/fancy/cigarettes/dromedaryco name = "\improper DromedaryCo packet" desc = "A packet of six imported DromedaryCo cancer sticks. A label on the packaging reads, \"Wouldn't a slow death make a change?\"" diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index c18af6f7218..772dc76d46c 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -56,6 +56,7 @@ new /obj/item/weapon/implanter/emp(src) new /obj/item/weapon/implanter/adrenalin(src) new /obj/item/weapon/implanter/explosive(src) + new /obj/item/weapon/implanter/storage(src) return if("hacker") @@ -86,42 +87,6 @@ desc = "A sleek, sturdy box" icon_state = "box_of_doom" -/obj/item/weapon/storage/box/syndie_kit/imp_freedom - name = "Freedom Implant (with injector)" - -/obj/item/weapon/storage/box/syndie_kit/imp_freedom/New() - ..() - var/obj/item/weapon/implanter/O = new(src) - O.imp = new /obj/item/weapon/implant/freedom(O) - O.update() - return - -/obj/item/weapon/storage/box/syndie_kit/imp_compress - name = "box (C)" - -/obj/item/weapon/storage/box/syndie_kit/imp_compress/New() - new /obj/item/weapon/implanter/compressed(src) - ..() - return - -/obj/item/weapon/storage/box/syndie_kit/imp_explosive - name = "box (E)" - -/obj/item/weapon/storage/box/syndie_kit/imp_explosive/New() - new /obj/item/weapon/implanter/explosive(src) - ..() - return - -/obj/item/weapon/storage/box/syndie_kit/imp_uplink - name = "Uplink Implant (with injector)" - -/obj/item/weapon/storage/box/syndie_kit/imp_uplink/New() - ..() - var/obj/item/weapon/implanter/O = new(src) - O.imp = new /obj/item/weapon/implant/uplink(O) - O.update() - return - /obj/item/weapon/storage/box/syndie_kit/space name = "Boxed Space Suit and Helmet" can_hold = list("/obj/item/clothing/suit/space/syndicate/black/red", "/obj/item/clothing/head/helmet/space/syndicate/black/red") @@ -164,24 +129,6 @@ new /obj/item/ammo_box/a357(src) return -/obj/item/weapon/storage/box/syndie_kit/imp_adrenal - name = "boxed adrenal implant (with injector)" - - New() - ..() - var/obj/item/weapon/implanter/O = new(src) - O.imp = new /obj/item/weapon/implant/adrenalin(O) - O.update() - -/obj/item/weapon/storage/box/syndie_kit/mindslave - name = "box (MS)" - - New() - ..() - var/obj/item/weapon/implanter/O = new(src) - O.imp = new /obj/item/weapon/implant/traitor(O) - O.update() - /obj/item/weapon/storage/box/syndie_kit/boolets name = "Shotgun shells" diff --git a/code/game/objects/items/weapons/swords_axes_etc.dm b/code/game/objects/items/weapons/swords_axes_etc.dm index 876f0930a34..63f10e1d574 100644 --- a/code/game/objects/items/weapons/swords_axes_etc.dm +++ b/code/game/objects/items/weapons/swords_axes_etc.dm @@ -97,6 +97,9 @@ w_class = 2 force = 0 //not so robust now attack_verb = list("hit", "poked") - + if(istype(user,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = user + H.update_inv_l_hand() + H.update_inv_r_hand() playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, 1) add_fingerprint(user) diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm index 6fcc67e1e67..61663a82fb4 100644 --- a/code/game/objects/items/weapons/teleportation.dm +++ b/code/game/objects/items/weapons/teleportation.dm @@ -66,7 +66,7 @@ Frequency: temp += "[W.code]: [TB.x], [TB.y], [TB.z]
" temp += "Located Implants:
" - for (var/obj/item/weapon/implant/tracking/T in tracking_implants) + for (var/obj/item/weapon/implant/tracking/T in tracked_implants) if (!T.implanted || !T.imp_in) continue diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index d47424d3489..be567173078 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -241,7 +241,6 @@ sleep(2) new /obj/item/weapon/storage/briefcase(src) new /obj/item/weapon/storage/firstaid/adv(src) - new /obj/item/weapon/gun/projectile/revolver/detective(src) new /obj/item/weapon/storage/belt/security/sec(src) new /obj/item/weapon/grenade/flashbang(src) new /obj/item/device/flash(src) diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm index 7c6de0f828f..d422d25dfd2 100644 --- a/code/game/objects/structures/inflatable.dm +++ b/code/game/objects/structures/inflatable.dm @@ -111,6 +111,13 @@ if(health <= 0) deflate(1) +/obj/structure/inflatable/AltClick() + if(usr.stat || usr.restrained()) + return + if(!Adjacent(usr)) + return + deflate() + /obj/structure/inflatable/proc/deflate(var/violent=0) playsound(loc, 'sound/machines/hiss.ogg', 75, 1) if(violent) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 6a3ee1f4312..1afa2d95504 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -42,24 +42,28 @@ /obj/structure/table/update_icon() if(smooth && !flipped) + icon_state = initial(icon_state) smooth_icon(src) smooth_icon_neighbors(src) if(flipped) + clear_smooth_overlays() + var/type = 0 - var/tabledirs = 0 + var/subtype = null for(var/direction in list(turn(dir,90), turn(dir,-90)) ) var/obj/structure/table/T = locate(/obj/structure/table,get_step(src,direction)) if (T && T.flipped) type++ - tabledirs |= direction + if(type == 1) + subtype = direction == turn(dir,90) ? "-" : "+" var/base = "table" if (istype(src, /obj/structure/table/woodentable)) base = "wood" if (istype(src, /obj/structure/table/reinforced)) base = "rtable" - icon_state = "[base]flip[type]" + icon_state = "[base]flip[type][type == 1 ? subtype : ""]" return 1 diff --git a/code/game/response_team.dm b/code/game/response_team.dm index 68457089d09..b17e51fef19 100644 --- a/code/game/response_team.dm +++ b/code/game/response_team.dm @@ -248,6 +248,7 @@ var/send_emergency_team var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(M) L.imp_in = M L.implanted = 1 + M.sec_hud_set_implants() switch(officer_type) if("Engineer") diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index b6cc60c82ed..0896a6e5488 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -34,7 +34,7 @@ var/global/nologevent = 0 usr << "You seem to be selecting a mob that doesn't exist anymore." return - if(!check_rights(R_ADMIN|R_MOD)) + if(!check_rights(R_ADMIN|R_MOD)) return var/body = "Options for [M.key]" @@ -48,32 +48,32 @@ var/global/nologevent = 0 else body += " \[Heal\] " - body += "

\[ " - body += "VV - " - body += "TP - " - body += "PM - " - body += "SM - " - body += "[admin_jump_link(M, src)]\]
" - - body += "Mob type: [M.type]
" - if(M.client) - if(M.client.related_accounts_cid.len) - body += "Related accounts by CID: [list2text(M.client.related_accounts_cid, " - ")]
" - if(M.client.related_accounts_ip.len) - body += "Related accounts by IP: [list2text(M.client.related_accounts_ip, " - ")]

" - - body += "Kick | " - body += "Warn | " - body += "Ban | " - body += "Jobban | " - body += "Appearance Ban | " - body += "Notes | " - if(M.client) - if(M.client.check_watchlist(M.client.ckey)) - body += "Remove from Watchlist | " - body += "Edit Watchlist Reason " - else - body += "Add to Watchlist " + body += "

\[ " + body += "VV - " + body += "TP - " + body += "PM - " + body += "SM - " + body += "[admin_jump_link(M, src)]\]
" + + body += "Mob type: [M.type]
" + if(M.client) + if(M.client.related_accounts_cid.len) + body += "Related accounts by CID: [list2text(M.client.related_accounts_cid, " - ")]
" + if(M.client.related_accounts_ip.len) + body += "Related accounts by IP: [list2text(M.client.related_accounts_ip, " - ")]

" + + body += "Kick | " + body += "Warn | " + body += "Ban | " + body += "Jobban | " + body += "Appearance Ban | " + body += "Notes | " + if(M.client) + if(M.client.check_watchlist(M.client.ckey)) + body += "Remove from Watchlist | " + body += "Edit Watchlist Reason " + else + body += "Add to Watchlist " if(M.client) body += "| Prison | " @@ -212,21 +212,21 @@ var/global/nologevent = 0 /datum/admins/proc/PlayerNotes() set category = "Admin" set name = "Player Notes" - + if(!check_rights(R_ADMIN|R_MOD)) return - + show_note() /datum/admins/proc/show_player_notes(var/key as text) set category = "Admin" set name = "Show Player Notes" - + if(!check_rights(R_ADMIN|R_MOD)) return - + show_note(key) - + /datum/admins/proc/access_news_network() //MARKER set category = "Event" set name = "Access Newscaster Network" @@ -234,10 +234,10 @@ var/global/nologevent = 0 if(!check_rights(R_EVENT)) return - + if (!istype(src,/datum/admins)) src = usr.client.holder - + var/dat dat = text("Admin Newscaster

Admin Newscaster Unit

") @@ -473,7 +473,7 @@ var/global/nologevent = 0 onclose(usr, "admincaster_main") /datum/admins/proc/Jobbans() - if(!check_rights(R_BAN)) + if(!check_rights(R_BAN)) return var/dat = "Job Bans!
" @@ -486,7 +486,7 @@ var/global/nologevent = 0 usr << browse(dat, "window=ban;size=400x400") /datum/admins/proc/Game() - if(!check_rights(R_ADMIN)) + if(!check_rights(R_ADMIN)) return var/dat = {" @@ -515,10 +515,10 @@ var/global/nologevent = 0 set category = "Server" set name = "Restart" set desc = "Restarts the world." - - if(!check_rights(R_SERVER)) + + if(!check_rights(R_SERVER)) return - + var/delay = input("What delay should the restart have (in seconds)?", "Restart Delay", 5) as num|null if(isnull(delay)) return @@ -534,8 +534,8 @@ var/global/nologevent = 0 set category = "Special Verbs" set name = "Announce" set desc="Announce your desires to the world" - - if(!check_rights(R_ADMIN)) + + if(!check_rights(R_ADMIN)) return var/message = input("Global message to send:", "Admin Announce", null, null) as message|null @@ -609,10 +609,10 @@ var/global/nologevent = 0 set category = "Server" set desc="Start the round RIGHT NOW" set name="Start Now" - + if(!check_rights(R_SERVER)) - return - + return + if(!ticker) alert("Unable to start the game as it is not set up.") return @@ -630,10 +630,10 @@ var/global/nologevent = 0 set category = "Server" set desc="People can't enter" set name="Toggle Entering" - + if(!check_rights(R_SERVER)) - return - + return + enter_allowed = !( enter_allowed ) if (!( enter_allowed )) world << "New players may no longer enter the game." @@ -648,10 +648,10 @@ var/global/nologevent = 0 set category = "Event" set desc="People can't be AI" set name="Toggle AI" - + if(!check_rights(R_EVENT)) - return - + return + config.allow_ai = !( config.allow_ai ) if (!( config.allow_ai )) world << "The AI job is no longer chooseable." @@ -668,8 +668,8 @@ var/global/nologevent = 0 set name="Toggle Respawn" if(!check_rights(R_SERVER)) - return - + return + abandon_allowed = !( abandon_allowed ) if (abandon_allowed) world << "You may now respawn." @@ -684,10 +684,10 @@ var/global/nologevent = 0 set category = "Event" set desc="Toggle alien mobs" set name="Toggle Aliens" - + if(!check_rights(R_EVENT)) - return - + return + aliens_allowed = !aliens_allowed log_admin("[key_name(usr)] toggled aliens to [aliens_allowed].") message_admins("[key_name_admin(usr)] toggled aliens [aliens_allowed ? "on" : "off"].") @@ -698,9 +698,9 @@ var/global/nologevent = 0 set desc="Delay the game start/end" set name="Delay" - if(!check_rights(R_SERVER)) + if(!check_rights(R_SERVER)) return - + if (!ticker || ticker.current_state != GAME_STATE_PREGAME) ticker.delay_end = !ticker.delay_end log_admin("[key_name(usr)] [ticker.delay_end ? "delayed the round end" : "has made the round end normally"].") @@ -760,7 +760,7 @@ var/global/nologevent = 0 set desc = "(atom path) Spawn an atom" set name = "Spawn" - if(!check_rights(R_SPAWN)) + if(!check_rights(R_SPAWN)) return var/list/types = typesof(/atom) @@ -794,8 +794,8 @@ var/global/nologevent = 0 set category = "Admin" set desc = "Edit mobs's memory and role" set name = "Show Traitor Panel" - - if(!check_rights(R_ADMIN|R_MOD)) + + if(!check_rights(R_ADMIN|R_MOD)) return if(!istype(M)) @@ -812,10 +812,10 @@ var/global/nologevent = 0 set category = "Server" set desc="Guests can't enter" set name="Toggle Guests" - - if(!check_rights(R_SERVER)) - return - + + if(!check_rights(R_SERVER)) + return + guests_allowed = !( guests_allowed ) if (!( guests_allowed )) world << "Guests may no longer enter the game." @@ -849,7 +849,7 @@ var/global/nologevent = 0 S.laws.show_laws(usr) if(!ai_number) usr << "No AI's located." //Just so you know the thing is actually working and not just ignoring you. - + log_admin("[key_name(usr)] checked the AI laws") message_admins("[key_name_admin(usr)] checked the AI laws") @@ -857,8 +857,8 @@ var/global/nologevent = 0 set category = "Admin" set name = "Update Mob Sprite" set desc = "Should fix any mob sprite update errors." - - if(!check_rights(R_ADMIN)) + + if(!check_rights(R_ADMIN)) return if(istype(H)) @@ -932,8 +932,8 @@ var/gamma_ship_location = 1 // 0 = station , 1 = space C << message kicked_client_names.Add("[C.ckey]") del(C) - return kicked_client_names - + return kicked_client_names + //returns 1 to let the dragdrop code know we are trapping this event //returns 0 if we don't plan to trap the event /datum/admins/proc/cmd_ghost_drag(var/mob/dead/observer/frommob, var/mob/living/tomob) @@ -971,4 +971,3 @@ var/gamma_ship_location = 1 // 0 = station , 1 = space qdel(frommob) return 1 - \ No newline at end of file diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 798dd02b85f..038c9a27b3f 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -520,12 +520,9 @@ client/proc/one_click_antag() limb.status &= ~(ORGAN_DESTROYED | ORGAN_ROBOT) //Now apply cortical stack. - var/obj/item/organ/external/E = new_vox.get_organ("head") var/obj/item/weapon/implant/cortical/I = new(new_vox) I.imp_in = new_vox I.implanted = 1 - I.part = E - E.implants += I cortical_stacks += I ticker.mode.traitors += new_vox.mind diff --git a/code/modules/admin/verbs/striketeam.dm b/code/modules/admin/verbs/striketeam.dm index d34b998b39c..955d40c9724 100644 --- a/code/modules/admin/verbs/striketeam.dm +++ b/code/modules/admin/verbs/striketeam.dm @@ -160,8 +160,7 @@ var/global/sent_strike_team = 0 var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(src)//Here you go Deuryn L.imp_in = src L.implanted = 1 - - + sec_hud_set_implants() var/obj/item/weapon/card/id/W = new(src) W.name = "[real_name]'s ID Card" diff --git a/code/modules/admin/verbs/vox_raiders.dm b/code/modules/admin/verbs/vox_raiders.dm index 33854109bc4..c5e370f06f7 100644 --- a/code/modules/admin/verbs/vox_raiders.dm +++ b/code/modules/admin/verbs/vox_raiders.dm @@ -63,9 +63,6 @@ var/global/vox_tick = 1 var/obj/item/weapon/implant/cortical/I = new(src) I.imp_in = src I.implanted = 1 - var/obj/item/organ/external/affected = src.get_organ("head") - affected.implants += I - I.part = affected if(ticker.mode && ( istype(ticker.mode,/datum/game_mode/vox/heist) ) ) var/datum/game_mode/vox/heist/M = ticker.mode diff --git a/code/modules/awaymissions/exile.dm b/code/modules/awaymissions/exile.dm index d0cdce5b7f4..4e6a69d591b 100644 --- a/code/modules/awaymissions/exile.dm +++ b/code/modules/awaymissions/exile.dm @@ -1,51 +1,44 @@ -//////Exile implants will allow you to use the station gate, but not return home. This will allow security to exile badguys/for badguys to exile their kill targets//////// +//Exile implants will allow you to use the station gate, but not return home. +//This will allow security to exile badguys/for badguys to exile their kill targets + +/obj/item/weapon/implant/exile + name = "exile implant" + desc = "Prevents you from returning from away missions" + origin_tech = "materials=2;biotech=3;magnets=2;bluespace=3" + activated = 0 + +/obj/item/weapon/implant/exile/get_data() + var/dat = {"Implant Specifications:
+ Name: Nanotrasen Employee Exile Implant
+ Implant Details: The onboard gateway system has been modified to reject entry by individuals containing this implant
"} + return dat /obj/item/weapon/implanter/exile - name = "implanter-exile" + name = "implanter (exile)" /obj/item/weapon/implanter/exile/New() - src.imp = new /obj/item/weapon/implant/exile( src ) + imp = new /obj/item/weapon/implant/exile( src ) ..() - update() - return - - -/obj/item/weapon/implant/exile - name = "exile" - desc = "Prevents you from returning from away missions" - - get_data() - var/dat = {" -Implant Specifications:
-Name: Nanotrasen Employee Exile Implant
-Implant Details: The onboard gateway system has been modified to reject entry by individuals containing this implant
"} - return dat /obj/item/weapon/implantcase/exile - name = "\improper Glass Case- 'Exile'" - desc = "A case containing an exile implant." - icon = 'icons/obj/items.dmi' - icon_state = "implantcase-r" + name = "implant case - 'Exile'" + desc = "A glass case containing an exile implant." - - New() - src.imp = new /obj/item/weapon/implant/exile( src ) - ..() - return +/obj/item/weapon/implantcase/exile/New() + imp = new /obj/item/weapon/implant/exile(src) + ..() /obj/structure/closet/secure_closet/exile name = "exile implants" req_access = list(access_hos) - New() - ..() - sleep(2) - new /obj/item/weapon/implanter/exile(src) - new /obj/item/weapon/implantcase/exile(src) - new /obj/item/weapon/implantcase/exile(src) - new /obj/item/weapon/implantcase/exile(src) - new /obj/item/weapon/implantcase/exile(src) - new /obj/item/weapon/implantcase/exile(src) - return \ No newline at end of file +/obj/structure/closet/secure_closet/exile/New() + ..() + new /obj/item/weapon/implanter/exile(src) + new /obj/item/weapon/implantcase/exile(src) + new /obj/item/weapon/implantcase/exile(src) + new /obj/item/weapon/implantcase/exile(src) + new /obj/item/weapon/implantcase/exile(src) + new /obj/item/weapon/implantcase/exile(src) \ No newline at end of file diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 37dd3326f92..1ecae4518ed 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -80,6 +80,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts var/ooccolor = "#b82e00" var/be_special = list() //Special role selection var/UI_style = "Midnight" + var/nanoui_fancy = TRUE var/toggles = TOGGLES_DEFAULT var/sound = SOUND_DEFAULT var/UI_style_color = "#ffffff" @@ -389,6 +390,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts dat += "
" dat += "

General Settings

" dat += "UI Style: [UI_style]
" + dat += "Fancy NanoUI: [(nanoui_fancy) ? "Yes" : "No"]
" dat += "Custom UI settings:
" dat += "Color: [UI_style_color]
__

" dat += "Alpha (transparency): [UI_style_alpha]
" @@ -1488,6 +1490,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts else UI_style = "Midnight" + if("nanoui") + nanoui_fancy = !nanoui_fancy + 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 @@ -1566,6 +1571,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts return 1 /datum/preferences/proc/copy_to(mob/living/carbon/human/character) + character.change_species(species) // Yell at me if this causes everything to melt if(be_random_name) real_name = random_name(gender,species) @@ -1641,7 +1647,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts else if(status == "mechanical") I.robotize() - if(disabilities & DISABILITY_FLAG_FAT && character.species.flags & CAN_BE_FAT)//character.species.flags & CAN_BE_FAT) + if(disabilities & DISABILITY_FLAG_FAT && character.species.flags & CAN_BE_FAT) character.mutations += FAT character.mutations += OBESITY if(disabilities & DISABILITY_FLAG_NEARSIGHTED) diff --git a/code/modules/client/preferences_mysql.dm b/code/modules/client/preferences_mysql.dm index fe5deb793e1..9b873baec73 100644 --- a/code/modules/client/preferences_mysql.dm +++ b/code/modules/client/preferences_mysql.dm @@ -10,7 +10,8 @@ toggles, sound, randomslot, - volume + volume, + nanoui_fancy FROM [format_table_name("player")] WHERE ckey='[C.ckey]'"} ) @@ -34,6 +35,7 @@ sound = text2num(query.item[8]) randomslot = text2num(query.item[9]) volume = text2num(query.item[10]) + nanoui_fancy = text2num(query.item[11]) //Sanitize ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor)) @@ -46,6 +48,7 @@ UI_style_alpha = sanitize_integer(UI_style_alpha, 0, 255, initial(UI_style_alpha)) randomslot = sanitize_integer(randomslot, 0, 1, initial(randomslot)) volume = sanitize_integer(volume, 0, 100, initial(volume)) + nanoui_fancy = sanitize_integer(nanoui_fancy, 0, 1, initial(nanoui_fancy)) return 1 /datum/preferences/proc/save_preferences(client/C) @@ -67,7 +70,8 @@ toggles='[toggles]', sound='[sound]', randomslot='[randomslot]', - volume='[volume]' + volume='[volume]', + nanoui_fancy='[nanoui_fancy]' WHERE ckey='[C.ckey]'"} ) diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index f462bce2ee2..856106ba48f 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -330,6 +330,21 @@ BLIND // can't see anything "Vox" = 'icons/mob/species/vox/shoes.dmi' ) +/obj/item/clothing/shoes/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/weapon/match) && src.loc == user) + var/obj/item/weapon/match/M = I + if(M.lit == 0) + M.lit = 1 + M.icon_state = "match_lit" + processing_objects.Add(M) + M.update_icon() + user << "You strike the [M] along your [src] to light it." + else if(M.lit == 1) + M.dropped() + user << "You crush the [M] into the bottom of your [src], extinguishing it." + return + else + ..() /obj/item/proc/negates_gravity() return 0 diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index 8fe35a95901..30252e49772 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -76,7 +76,7 @@ /obj/item/clothing/head/HoS/beret name = "head of security beret" desc = "A robust beret for the Head of Security, for looking stylish while not sacrificing protection." - icon_state = "hosberetblack" + icon_state = "beret_hos_black" /obj/item/clothing/head/warden name = "warden's police hat" @@ -95,25 +95,25 @@ /obj/item/clothing/head/beret/sec name = "security beret" desc = "A beret with the security insignia emblazoned on it. For officers that are more inclined towards style than safety." - icon_state = "beret_badge" + icon_state = "beret_officer" armor = list(melee = 30, bullet = 25, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0) strip_delay = 60 /obj/item/clothing/head/beret/sec/warden name = "warden's beret" desc = "A special beret with the Warden's insignia emblazoned on it. For wardens with class." - icon_state = "wardenberet" + icon_state = "beret_warden" armor = list(melee = 60, bullet = 5, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0) /obj/item/clothing/head/beret/eng name = "engineering beret" desc = "A beret with the engineering insignia emblazoned on it. For engineers that are more inclined towards style than safety." - icon_state = "e_beret_badge" + icon_state = "beret_engineering" /obj/item/clothing/head/beret/atmos name = "atmospherics beret" desc = "A beret for those who have shown immaculate proficienty in piping. Or plumbing." - icon_state = "a_beret_badge" + icon_state = "beret_atmospherics" //Medical /obj/item/clothing/head/surgery diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index c739e9bde9f..7c353ed8c82 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -277,18 +277,18 @@ /obj/item/clothing/head/beret/purple name = "Pierson Family Beret" desc = " A purple beret, with a small golden crescent moon sewn onto it." - icon_state = "purpleberet" + icon_state = "beret_purple" item_state = "purpleberet" /obj/item/clothing/head/beret/centcom/officer name = "officers beret" desc = "A black beret adorned with the shield—a silver kite shield with an engraved sword—of the Nanotrasen security forces, announcing to the world that the wearer is a defender of Nanotrasen." - icon_state = "centcomofficerberet" + icon_state = "beret_centcom_officer" /obj/item/clothing/head/beret/centcom/captain name = "captains beret" desc = "A white beret adorned with the shield—a cobalt kite shield with an engraved sword—of the Nanotrasen security forces, worn only by those captaining a vessel of the Nanotrasen Navy." - icon_state = "centcomcaptain" + icon_state = "beret_centcom_captain" /obj/item/clothing/head/sombrero name = "sombrero" diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index dcd7114196a..bfa2b3232b3 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -63,7 +63,7 @@ /obj/item/clothing/head/helmet/space/deathsquad/beret name = "officer's beret" desc = "An armored beret commonly used by special operations officers." - icon_state = "beret_badge" + icon_state = "beret_officer" armor = list(melee = 65, bullet = 55, laser = 35,energy = 20, bomb = 30, bio = 30, rad = 30) /obj/item/clothing/suit/space/deathsquad/officer diff --git a/code/modules/clothing/spacesuits/rig.dm b/code/modules/clothing/spacesuits/rig.dm index bc6d6f995cf..1fde42aac94 100644 --- a/code/modules/clothing/spacesuits/rig.dm +++ b/code/modules/clothing/spacesuits/rig.dm @@ -19,12 +19,14 @@ "Tajaran" = 'icons/mob/species/tajaran/helmet.dmi', "Skrell" = 'icons/mob/species/skrell/helmet.dmi', "Vox" = 'icons/mob/species/vox/helmet.dmi', + "Vulpkanin" = 'icons/mob/species/vulpkanin/helmet.dmi', ) sprite_sheets_obj = list( "Unathi" = 'icons/obj/clothing/species/unathi/hats.dmi', "Tajaran" = 'icons/obj/clothing/species/tajaran/hats.dmi', "Skrell" = 'icons/obj/clothing/species/skrell/hats.dmi', "Vox" = 'icons/obj/clothing/species/vox/hats.dmi', + "Vulpkanin" = 'icons/obj/clothing/species/vulpkanin/hats.dmi', ) /obj/item/clothing/head/helmet/space/rig/attack_self(mob/user) @@ -62,12 +64,14 @@ "Tajaran" = 'icons/mob/species/tajaran/suit.dmi', "Skrell" = 'icons/mob/species/skrell/suit.dmi', "Vox" = 'icons/mob/species/vox/suit.dmi', + "Vulpkanin" = 'icons/mob/species/vulpkanin/suit.dmi', ) sprite_sheets_obj = list( "Unathi" = 'icons/obj/clothing/species/unathi/suits.dmi', "Tajaran" = 'icons/obj/clothing/species/tajaran/suits.dmi', "Skrell" = 'icons/obj/clothing/species/skrell/suits.dmi', "Vox" = 'icons/obj/clothing/species/vox/suits.dmi', + "Vulpkanin" = 'icons/obj/clothing/species/vulpkanin/suits.dmi', ) //Breach thresholds, should ideally be inherited by most (if not all) hardsuits. diff --git a/code/modules/computer3/computers/prisoner.dm b/code/modules/computer3/computers/prisoner.dm index e3cfba6e673..f9a4c6f45d5 100644 --- a/code/modules/computer3/computers/prisoner.dm +++ b/code/modules/computer3/computers/prisoner.dm @@ -46,8 +46,6 @@ if(M.z == ZLEVEL_STATION && !istype(M.loc, /turf/space)) var/turf/mob_loc = get_turf(M) loc_display = mob_loc.loc - if(T.malfunction) - loc_display = pick(teleportlocs) dat += "ID: [T.id] | Location: [loc_display]
" dat += "(Send Message) |
" dat += "********************************
" diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 1fc98d4bc60..6304c606300 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -157,10 +157,10 @@ if("Kluysfluff1") src.icon_state = "Kluysfluff2" usr << "The fibre unfolds into a jacket." - else if("Kluysfluff2") + if("Kluysfluff2") src.icon_state = "Kluysfluff3" usr << "The fibre unfolds into a coat." - else if("Kluysfluff3") + if("Kluysfluff3") src.icon_state = "Kluysfluff1" usr << "The fibre gets sucked back into its holder." else diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 03af198e808..fcf786745a6 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -169,7 +169,8 @@ var/list/event_last_fired = list() new /datum/event_meta(EVENT_LEVEL_MODERATE, "Flux Anomaly", /datum/event/anomaly/anomaly_flux, 50, list(ASSIGNMENT_ENGINEER = 50)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Gravitational Anomaly", /datum/event/anomaly/anomaly_grav, 200), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Revenant", /datum/event/revenant, 150), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Swarmer Spawn", /datum/event/spawn_swarmer, 150, is_one_shot = 1) + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Swarmer Spawn", /datum/event/spawn_swarmer, 150, is_one_shot = 1), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Morph Spawn", /datum/event/spawn_morph, 0, is_one_shot = 1) ) /datum/event_container/major diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 5d3ea0522f9..014c0623c84 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -307,13 +307,14 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp //var/datum/atom_hud/A = huds[DATA_HUD_SECURITY_ADVANCED] //var/adding_hud = (usr in A.hudusers) ? 0 : 1 - for(var/datum/atom_hud/H in huds) - if(istype(H, /datum/atom_hud/antag))// || istype(H, /datum/atom_hud/data/human/security/advanced)) - if(!M.antagHUD) + + for(var/datum/atom_hud/antag/H in (huds)) + //if(istype(H, /datum/atom_hud/antag))// || istype(H, /datum/atom_hud/data/human/security/advanced)) + if(!M.antagHUD) //(adding_hud) ? H.add_hud_to(usr) : H.remove_hud_from(usr) - H.add_hud_to(usr) - else - H.remove_hud_from(usr) + H.add_hud_to(usr) + else + H.remove_hud_from(usr) if(!M.antagHUD) usr << "AntagHud Toggled ON" M.antagHUD = 1 diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index a18f2fab8d0..265c7697de2 100644 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -19,10 +19,11 @@ var/list/syllables // Used when scrambling text for a non-speaker. var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string. var/follow = 0 // Applies to HIVEMIND languages - should a follow link be included for dead mobs? + var/english_names = 0 // Do we want English names by default, no matter what? var/list/scramble_cache = list() /datum/language/proc/get_random_name(var/gender, name_count=2, syllable_count=4) - if(!syllables || !syllables.len) + if(!syllables || !syllables.len || english_names) if(gender==FEMALE) return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names)) else @@ -283,6 +284,7 @@ key = "9" flags = RESTRICTED syllables = list("blah","blah","blah","bleh","meh","neh","nah","wah") + english_names = 1 //TODO flag certain languages to use the mob-type specific say_quote and then get rid of these. /datum/language/common/get_spoken_verb(var/msg_end) @@ -302,6 +304,7 @@ key = "1" flags = RESTRICTED syllables = list("tao","shi","tzu","yi","com","be","is","i","op","vi","ed","lec","mo","cle","te","dis","e") + english_names = 1 /datum/language/human/get_spoken_verb(var/msg_end) switch(msg_end) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 9a9c50c7269..72970927dfe 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -743,4 +743,30 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, handcuffed, legcuffed, back, - wear_mask) \ No newline at end of file + wear_mask) + +/mob/living/carbon/proc/uncuff() + if (handcuffed) + var/obj/item/weapon/W = handcuffed + handcuffed = null + if (buckled && buckled.buckle_requires_restraints) + buckled.unbuckle_mob() + update_inv_handcuffed() + if (client) + client.screen -= W + if (W) + W.loc = loc + W.dropped(src) + if (W) + W.layer = initial(W.layer) + if (legcuffed) + var/obj/item/weapon/W = legcuffed + legcuffed = null + update_inv_legcuffed() + if (client) + client.screen -= W + if (W) + W.loc = loc + W.dropped(src) + if (W) + W.layer = initial(W.layer) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index c25a9b7129c..c69f902c85a 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -23,7 +23,10 @@ set_species(delay_icon_update = 1) if(species) - name = species.get_random_name(gender) + real_name = species.get_random_name(gender) + name = real_name + if(mind) + mind.name = real_name var/datum/reagents/R = new/datum/reagents(330) reagents = R @@ -455,14 +458,6 @@ var/armor_block = run_armor_check(affecting, "melee") apply_damage(damage, BRUTE, affecting, armor_block) -/mob/living/carbon/human/proc/is_loyalty_implanted() - for(var/L in contents) - if(istype(L, /obj/item/weapon/implant/loyalty)) - for(var/obj/item/organ/external/O in organs) - if(L in O.implants) - return 1 - return 0 - /mob/living/carbon/human/attack_slime(mob/living/carbon/slime/M as mob) if(M.Victim) return // can't attack while eating! @@ -1874,87 +1869,3 @@ for(var/obj/item/clothing/C in src) //If they have some clothing equipped that lets them see reagents, they can see reagents if(C.scan_reagents) return 1 - -// ugh this is so hackish -// but why don't we have a proc for this already -/proc/create_human_for_client_from_prefs(var/client/C) - - var/turf/start = pick(latejoin) - - var/mob/living/carbon/human/new_character - - var/datum/species/chosen_species - if(C.prefs.species) - chosen_species = all_species[C.prefs.species] - if(chosen_species) - // Have to recheck admin due to no usr at roundstart. Latejoins are fine though. - if(is_alien_whitelisted(C, chosen_species) || check_rights_for(C, R_ADMIN)) - - new_character = new(start, C.prefs.species) - - if(!new_character) - new_character = new(start) - - new_character.lastarea = get_area(start) - - var/datum/language/chosen_language - if(C.prefs.language) - chosen_language = all_languages[C.prefs.language] - if(chosen_language) - if(is_alien_whitelisted(C, C.prefs.language) || !config.usealienwhitelist || !(chosen_language.flags & WHITELISTED)) - new_character.add_language(C.prefs.language) - if(ticker.random_players || appearance_isbanned(new_character)) - C.prefs.random_character() - C.prefs.real_name = random_name(new_character.gender) - C.prefs.copy_to(new_character) - - src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // MAD JAMS cant last forever yo - - var/datum/mind/M = new/datum/mind(C.key) - M.active = 0 - M.original = new_character - M.current = new_character - M.transfer_to(new_character) //won't transfer key since the mind is not active - - new_character.name = C.prefs.real_name - new_character.dna.ready_dna(new_character) - new_character.dna.b_type = C.prefs.b_type - - if(C.prefs.disabilities & DISABILITY_FLAG_NEARSIGHTED) - new_character.dna.SetSEState(GLASSESBLOCK,1,1) - new_character.disabilities |= NEARSIGHTED - - if(C.prefs.disabilities & DISABILITY_FLAG_FAT) - new_character.mutations += FAT - new_character.overeatduration = 600 // Max overeat - - if(C.prefs.disabilities & DISABILITY_FLAG_EPILEPTIC) - new_character.dna.SetSEState(EPILEPSYBLOCK,1,1) - new_character.disabilities |= EPILEPSY - - if(C.prefs.disabilities & DISABILITY_FLAG_DEAF) - new_character.dna.SetSEState(DEAFBLOCK,1,1) - new_character.sdisabilities |= DEAF - - if(C.prefs.disabilities & DISABILITY_FLAG_BLIND) - new_character.dna.SetSEState(BLINDBLOCK,1,1) - new_character.sdisabilities |= BLIND - - if(C.prefs.disabilities & DISABILITY_FLAG_MUTE) - new_character.dna.SetSEState(MUTEBLOCK,1,1) - new_character.sdisabilities |= MUTE - - chosen_species.handle_dna(new_character) - - domutcheck(new_character) - new_character.dna.UpdateSE() - new_character.sync_organ_dna() //just fucking incase I guess - - // Do the initial caching of the player's body icons. - new_character.force_update_limbs() - new_character.update_eyes() - new_character.regenerate_icons() - - new_character.key = C.key //Manually transfer the key to log them in - - return new_character \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 1ea23ebf53a..a5dc8f87f3b 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -281,7 +281,7 @@ emp_act glasses.add_blood(src) update_inv_glasses(0) - if("chest")//Easier to score a stun but lasts less time + if("upper body")//Easier to score a stun but lasts less time if(stat == CONSCIOUS && I.force && prob(I.force + 10)) visible_message("[src] has been knocked down!", \ "[src] has been knocked down!") diff --git a/code/modules/mob/living/carbon/human/species/monkey.dm b/code/modules/mob/living/carbon/human/species/monkey.dm index e1212758309..72d1a3a0e52 100644 --- a/code/modules/mob/living/carbon/human/species/monkey.dm +++ b/code/modules/mob/living/carbon/human/species/monkey.dm @@ -41,8 +41,8 @@ if(prob(1)) H.emote(pick("scratch","jump","roll","tail")) -datum/species/monkey/get_random_name(var/gender) - return +/datum/species/monkey/get_random_name() + return "[lowertext(name)] ([rand(100,999)])" /datum/species/monkey/handle_post_spawn(var/mob/living/carbon/human/H) H.real_name = "[lowertext(name)] ([rand(100,999)])" @@ -98,7 +98,7 @@ datum/species/monkey/get_random_name(var/gender) greater_form = "Tajaran" default_language = "Farwa" flesh_color = "#AFA59E" - base_color = "#333333" + base_color = "#000000" tail = "farwatail" reagent_tag = PROCESS_ORG @@ -113,7 +113,7 @@ datum/species/monkey/get_random_name(var/gender) greater_form = "Vulpkanin" default_language = "Wolpin" flesh_color = "#966464" - base_color = "#BE8264" + base_color = "#000000" tail = "wolpintail" reagent_tag = PROCESS_ORG @@ -146,7 +146,7 @@ datum/species/monkey/get_random_name(var/gender) greater_form = "Unathi" default_language = "Stok" flesh_color = "#34AF10" - base_color = "#066000" + base_color = "#000000" reagent_tag = PROCESS_ORG bodyflags = FEET_CLAWS | HAS_TAIL diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm index ae06c2b8553..453d0f0c4f3 100644 --- a/code/modules/mob/living/carbon/human/species/station.dm +++ b/code/modules/mob/living/carbon/human/species/station.dm @@ -200,7 +200,7 @@ flags = NO_SCAN | IS_WHITELISTED clothing_flags = HAS_SOCKS dietflags = DIET_OMNI - bodyflags = HAS_TAIL | TAIL_WAGGING + bodyflags = HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED blood_color = "#2299FC" flesh_color = "#808D11" diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 8102635157e..e4f2e957394 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -106,33 +106,35 @@ Please contact me on #coderbus IRC. ~Carn x //Human Overlays Indexes///////// #define MUTANTRACE_LAYER 1 -#define MARKINGS_LAYER 2 -#define MUTATIONS_LAYER 3 -#define DAMAGE_LAYER 4 -#define UNIFORM_LAYER 5 -#define ID_LAYER 6 -#define SHOES_LAYER 7 -#define GLOVES_LAYER 8 -#define EARS_LAYER 9 -#define SUIT_LAYER 10 -#define GLASSES_LAYER 11 -#define BELT_LAYER 12 //Possible make this an overlay of somethign required to wear a belt? -#define TAIL_LAYER 13 //bs12 specific. this hack is probably gonna come back to haunt me -#define SUIT_STORE_LAYER 14 -#define BACK_LAYER 15 -#define HAIR_LAYER 16 //TODO: make part of head layer? -#define HEAD_ACCESSORY_LAYER 17 -#define FHAIR_LAYER 18 -#define FACEMASK_LAYER 19 -#define HEAD_LAYER 20 -#define COLLAR_LAYER 21 -#define HANDCUFF_LAYER 22 -#define LEGCUFF_LAYER 23 -#define L_HAND_LAYER 24 -#define R_HAND_LAYER 25 -#define TARGETED_LAYER 26 //BS12: Layer for the target overlay from weapon targeting system -#define FIRE_LAYER 27 //If you're on fire -#define TOTAL_LAYERS 27 +#define TAIL_UNDERLIMBS_LAYER 2 +#define LIMBS_LAYER 3 +#define MARKINGS_LAYER 4 +#define MUTATIONS_LAYER 5 +#define DAMAGE_LAYER 6 +#define UNIFORM_LAYER 7 +#define ID_LAYER 8 +#define SHOES_LAYER 9 +#define GLOVES_LAYER 10 +#define EARS_LAYER 11 +#define SUIT_LAYER 12 +#define GLASSES_LAYER 13 +#define BELT_LAYER 14 //Possible make this an overlay of somethign required to wear a belt? +#define SUIT_STORE_LAYER 15 +#define BACK_LAYER 16 +#define TAIL_LAYER 17 //bs12 specific. this hack is probably gonna come back to haunt me +#define HAIR_LAYER 18 //TODO: make part of head layer? +#define HEAD_ACCESSORY_LAYER 19 +#define FHAIR_LAYER 20 +#define FACEMASK_LAYER 21 +#define HEAD_LAYER 22 +#define COLLAR_LAYER 23 +#define HANDCUFF_LAYER 24 +#define LEGCUFF_LAYER 25 +#define L_HAND_LAYER 26 +#define R_HAND_LAYER 27 +#define TARGETED_LAYER 28 //BS12: Layer for the target overlay from weapon targeting system +#define FIRE_LAYER 29 //If you're on fire +#define TOTAL_LAYERS 29 @@ -323,6 +325,8 @@ var/global/list/damage_icon_parts = list() //END CACHED ICON GENERATION. stand_icon.Blend(base_icon,ICON_OVERLAY) + if(src.species.bodyflags & TAIL_OVERLAPPED) // If the user's species is flagged to have a tail that needs to be overlapped by limbs... + overlays_standing[LIMBS_LAYER] = image(stand_icon) // Diverts limbs to their own layer so they can overlay things (i.e. tails). //Underwear if(underwear && species.clothing_flags & HAS_UNDERWEAR) @@ -1009,46 +1013,145 @@ var/global/list/damage_icon_parts = list() /mob/living/carbon/human/proc/update_tail_layer(var/update_icons=1) - overlays_standing[TAIL_LAYER] = null + overlays_standing[TAIL_UNDERLIMBS_LAYER] = null // SEW direction icons, overlayed by LIMBS_LAYER. + overlays_standing[TAIL_LAYER] = null // This will be one of two things: + // If the species' tail is overlapped by limbs, this will be only the N direction icon so tails can still appear on the outside of uniforms and such. + // Otherwise, since the user's tail isn't overlapped by limbs, it will be a full icon with all directions. if(body_accessory) if(body_accessory.try_restrictions(src)) var/icon/accessory_s = new/icon("icon" = body_accessory.icon, "icon_state" = body_accessory.icon_state) accessory_s.Blend(rgb(r_skin, g_skin, b_skin), body_accessory.blend_mode) - overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) + if(src.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... + // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. + var/icon/temp1 = new /icon('icons/mob/body_accessory.dmi',"accessory_none_s") + if(src.species.name in body_accessory.allowed_species) + var/icon/temp = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "[species.tail]_delay") + temp1 = temp + else + var/icon/temp = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "vulptail_delay") + temp1 = temp + temp1.Insert(new/icon(accessory_s,dir=SOUTH),dir=SOUTH) + temp1.Insert(new/icon(accessory_s,dir=EAST),dir=EAST) + temp1.Insert(new/icon(accessory_s,dir=WEST),dir=WEST) + + overlays_standing[TAIL_UNDERLIMBS_LAYER] = image(temp1, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) + + // Creates a blank icon, and copies accessory_s' north direction sprite into it + // before passing that to the tail layer that overlays uniforms and such. + var/icon/temp2 = new /icon('icons/mob/body_accessory.dmi',"accessory_none_s") + if(src.species.name in body_accessory.allowed_species) + var/icon/temp = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "[species.tail]_delay") + temp2 = temp + else + var/icon/temp = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "vulptail_delay") + temp2 = temp + + temp2.Insert(new/icon(accessory_s,dir=NORTH),dir=NORTH) + + overlays_standing[TAIL_LAYER] = image(temp2, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) + else // Otherwise, since the user's tail isn't overlapped by limbs, go ahead and use default icon generation. + overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) else if(species.tail && species.bodyflags & HAS_TAIL) //no tailless tajaran if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space)) var/icon/tail_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_s") tail_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) - overlays_standing[TAIL_LAYER] = image(tail_s) + if(src.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... + // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. + var/icon/temp1 = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_delay") + temp1.Insert(new/icon(tail_s,dir=SOUTH),dir=SOUTH) + temp1.Insert(new/icon(tail_s,dir=EAST),dir=EAST) + temp1.Insert(new/icon(tail_s,dir=WEST),dir=WEST) + + overlays_standing[TAIL_UNDERLIMBS_LAYER] = image(temp1) + + // Creates a blank icon, and copies accessory_s' north direction sprite into it + // before passing that to the tail layer that overlays uniforms and such. + var/icon/temp2 = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_delay") + temp2.Insert(new/icon(tail_s,dir=NORTH),dir=NORTH) + + overlays_standing[TAIL_LAYER] = image(temp2) + else // Otherwise, since the user's tail isn't overlapped by limbs, go ahead and use default icon generation. + overlays_standing[TAIL_LAYER] = image(tail_s) if(update_icons) update_icons() /mob/living/carbon/human/proc/start_tail_wagging(var/update_icons=1) - overlays_standing[TAIL_LAYER] = null + overlays_standing[TAIL_UNDERLIMBS_LAYER] = null // SEW direction icons, overlayed by LIMBS_LAYER. + overlays_standing[TAIL_LAYER] = null // This will be one of two things: + // If the species' tail is overlapped by limbs, this will be only the N direction icon so tails can still appear on the outside of uniforms and such. + // Otherwise, since the user's tail isn't overlapped by limbs, it will be a full icon with all directions. if(body_accessory) var/icon/accessory_s = new/icon("icon" = body_accessory.get_animated_icon(), "icon_state" = body_accessory.get_animated_icon_state()) accessory_s.Blend(rgb(r_skin, g_skin, b_skin), body_accessory.blend_mode) - overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) + if(src.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... + // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. + var/icon/temp1 = new /icon('icons/mob/body_accessory.dmi',"accessory_none_s") + if(body_accessory.allowed_species) + if(src.species.name in body_accessory.allowed_species) + var/icon/temp = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "[species.tail]_delay") + temp1 = temp + else + var/icon/temp = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "vulptail_delay") + temp1 = temp + + temp1.Insert(accessory_s,dir=SOUTH) + temp1.Insert(accessory_s,dir=EAST) + temp1.Insert(accessory_s,dir=WEST) + + overlays_standing[TAIL_UNDERLIMBS_LAYER] = image(temp1, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) + + // Creates a blank icon, and copies accessory_s' north direction sprite into it + // before passing that to the tail layer that overlays uniforms and such. + var/icon/temp2 = new /icon('icons/mob/body_accessory.dmi',"accessory_none_s") + if(src.species.name in body_accessory.allowed_species) // If the user's species is in the list of allowed species for the currently selected body accessory, use the appropriate animation timing blank + var/icon/temp = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "[species.tail]_delay") + temp2 = temp + else // Else if the user's species is not in the list of allowed species for the currently selected body accessory, this point must have been reached by admin-override. Use vulpkanin timings as default. + var/icon/temp = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "vulptail_delay") + temp2 = temp + + temp2.Insert(accessory_s,dir=NORTH) + + overlays_standing[TAIL_LAYER] = image(temp2, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) + else // Otherwise, since the user's tail isn't overlapped by limbs, go ahead and use default icon generation. + overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) else if(species.tail && species.bodyflags & HAS_TAIL) var/icon/tailw_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]w_s") tailw_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) - overlays_standing[TAIL_LAYER] = image(tailw_s) + if(src.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... + // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. + var/icon/temp1 = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_delay") + temp1.Insert(tailw_s,dir=SOUTH) + temp1.Insert(tailw_s,dir=EAST) + temp1.Insert(tailw_s,dir=WEST) + + overlays_standing[TAIL_UNDERLIMBS_LAYER] = image(temp1) + + // Creates a blank icon, and copies accessory_s' north direction sprite into it + // before passing that to the tail layer that overlays uniforms and such. + var/icon/temp2 = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_delay") + temp2.Insert(tailw_s,dir=NORTH) + + overlays_standing[TAIL_LAYER] = image(temp2) + else // Otherwise, since the user's tail isn't overlapped by limbs, go ahead and use default icon generation. + overlays_standing[TAIL_LAYER] = image(tailw_s) if(update_icons) update_icons() /mob/living/carbon/human/proc/stop_tail_wagging(var/update_icons=1) + overlays_standing[TAIL_UNDERLIMBS_LAYER] = null overlays_standing[TAIL_LAYER] = null update_tail_layer(update_icons) //just trigger a full update for normal stationary sprites @@ -1114,11 +1217,12 @@ var/global/list/damage_icon_parts = list() //Human Overlays Indexes///////// #undef MUTANTRACE_LAYER +#undef TAIL_UNDERLIMBS_LAYER +#undef LIMBS_LAYER #undef MARKINGS_LAYER #undef MUTATIONS_LAYER #undef DAMAGE_LAYER #undef UNIFORM_LAYER -#undef TAIL_LAYER #undef ID_LAYER #undef SHOES_LAYER #undef GLOVES_LAYER @@ -1129,6 +1233,7 @@ var/global/list/damage_icon_parts = list() #undef BELT_LAYER #undef SUIT_STORE_LAYER #undef BACK_LAYER +#undef TAIL_LAYER #undef HAIR_LAYER #undef HEAD_LAYER #undef HEAD_ACCESSORY_LAYER diff --git a/code/modules/mob/living/carbon/superheroes.dm b/code/modules/mob/living/carbon/superheroes.dm index 7200ac6fa04..d98a72f8e98 100644 --- a/code/modules/mob/living/carbon/superheroes.dm +++ b/code/modules/mob/living/carbon/superheroes.dm @@ -91,9 +91,6 @@ var/obj/item/weapon/implant/freedom/L = new/obj/item/weapon/implant/freedom(H) L.imp_in = H L.implanted = 1 - var/obj/item/organ/external/affected = H.organs_by_name["head"] - affected.implants += L - L.part = affected return 1 diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm index dd908d25d1e..1a3c52ad8be 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm @@ -25,7 +25,8 @@ /obj/item/weapon/rack_parts, /obj/item/weapon/camera_assembly, /obj/item/weapon/tank, - /obj/item/weapon/circuitboard + /obj/item/weapon/circuitboard, + /obj/item/stack/tile/light ) //Item currently being held. diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 44d29f118b7..47bc5b31b8f 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -680,7 +680,7 @@ /mob/living/simple_animal/parrot/Poly name = "Poly" desc = "Poly the Parrot. An expert on quantum cracker theory." - speak = list("Poly wanna cracker!", ":e Check the singlo, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN HARDSUITS?",":e OH GOD ITS FREE CALL THE SHUTTLE") + speak = list("Poly wanna cracker!", ":e Check the singlo, you chucklefucks!",":e Check the tesla, you shits!",":e STOP HOT-WIRING THE ENGINE, FUCKING CHRIST!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN HARDSUITS?",":e OH GOD ITS FREE CALL THE SHUTTLE") /mob/living/simple_animal/parrot/Poly/New() ears = new /obj/item/device/radio/headset/headset_eng(src) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 59afc38f1cd..399ae068586 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -102,6 +102,9 @@ handle_automated_speech() . = 1 + handle_state_icons() + +/mob/living/simple_animal/proc/handle_state_icons() if(resting && icon_resting && stat != DEAD) icon_state = icon_resting else if(stat != DEAD) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 29b803a6bea..2a8363ad16f 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -178,6 +178,12 @@ proc/isovermind(A) return 1 return 0 +/proc/ismindslave(A) //Checks to see if the person contains a mindslave implant, then checks that the implant is actually inside of them + for(var/obj/item/weapon/implant/traitor/T in A) + if(T && T.implanted) + return 1 + return 0 + proc/isAntag(A) if(istype(A, /mob/living/carbon)) var/mob/living/carbon/C = A diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index 6c2dd25dcd8..7eb20df76ea 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -211,16 +211,6 @@ datum/preferences preview_icon.Blend(new /icon(icobase, "groin_[g]"), ICON_OVERLAY) preview_icon.Blend(new /icon(icobase, "head_[g]"), ICON_OVERLAY) - for(var/name in list("r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","l_arm","l_hand")) - if(organ_data[name] == "amputated") continue - if(organ_data[name] == "cyborg") - var/datum/robolimb/R - if(rlimb_data[name]) R = all_robolimbs[rlimb_data[name]] - if(!R) R = basic_robolimb - preview_icon.Blend(icon(R.icon, "[name]"), ICON_OVERLAY) // This doesn't check gendered_icon. Not an issue while only limbs can be robotic. - continue - preview_icon.Blend(new /icon(icobase, "[name]"), ICON_OVERLAY) - //Tail if(current_species && (current_species.bodyflags & HAS_TAIL)) var/tail_icon @@ -237,6 +227,16 @@ datum/preferences var/icon/temp = new /icon("icon" = tail_icon, "icon_state" = tail_icon_state) preview_icon.Blend(temp, ICON_OVERLAY) + for(var/name in list("r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","l_arm","l_hand")) + if(organ_data[name] == "amputated") continue + if(organ_data[name] == "cyborg") + var/datum/robolimb/R + if(rlimb_data[name]) R = all_robolimbs[rlimb_data[name]] + if(!R) R = basic_robolimb + preview_icon.Blend(icon(R.icon, "[name]"), ICON_OVERLAY) // This doesn't check gendered_icon. Not an issue while only limbs can be robotic. + continue + preview_icon.Blend(new /icon(icobase, "[name]"), ICON_OVERLAY) + // Skin color if(current_species && (current_species.bodyflags & HAS_SKIN_COLOR)) preview_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index 1a411b55d70..ce2a34259ea 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -398,6 +398,11 @@ icon_state = "ipc_eight" species_allowed = list("Machine") + ipc_screen_rainbow + name = "rainbow IPC screen" + icon_state = "ipc_rainbow" + species_allowed = list("Machine") + ipc_screen_goggles name = "goggles IPC screen" icon_state = "ipc_goggles" @@ -1081,6 +1086,11 @@ icon_state = "male_grey" gender = MALE + male_grey + name = "Mens Grey Alt" + icon_state = "male_greyalt" + gender = MALE + male_green name = "Mens Green" icon_state = "male_green" @@ -1091,11 +1101,36 @@ icon_state = "male_blue" gender = MALE + male_red + name = "Mens Red" + icon_state = "male_red" + gender = MALE + male_black name = "Mens Black" icon_state = "male_black" gender = MALE + male_black_alt + name = "Mens Black Alt" + icon_state = "male_blackalt" + gender = MALE + + male_striped + name = "Mens Striped" + icon_state = "male_stripe" + gender = MALE + + male_heart + name = "Mens Hearts" + icon_state = "male_hearts" + gender = MALE + + male_kinky + name = "Mens Kinky" + icon_state = "male_kinky" + gender = MALE + male_mankini name = "Mankini" icon_state = "male_mankini" @@ -1106,11 +1141,26 @@ icon_state = "female_red" gender = FEMALE + female_green + name = "Ladies Green" + icon_state = "female_green" + gender = FEMALE + female_white name = "Ladies White" icon_state = "female_white" gender = FEMALE + female_whiter + name = "Ladies Whiter" + icon_state = "female_whiter" + gender = FEMALE + + female_whitealt + name = "Ladies White Alt" + icon_state = "female_whitealt" + gender = FEMALE + female_yellow name = "Ladies Yellow" icon_state = "female_yellow" @@ -1121,16 +1171,46 @@ icon_state = "female_blue" gender = FEMALE + female_babyblue + name = "Ladies Baby Blue" + icon_state = "female_babyblue" + gender = FEMALE + female_black name = "Ladies Black" icon_state = "female_black" gender = FEMALE + female_blacker + name = "Ladies Blacker" + icon_state = "female_blacker" + gender = FEMALE + + female_blackalt + name = "Ladies Black Alt" + icon_state = "female_blackalt" + gender = FEMALE + female_kinky name = "Ladies Kinky" icon_state = "female_kinky" gender = FEMALE + female_babydoll + name = "Ladies Full Grey" + icon_state = "female_babydoll" + gender = FEMALE + + female_pink + name = "Ladies Pink" + icon_state = "female_pink" + gender = FEMALE + + female_thong + name = "Ladies Thong" + icon_state = "female_thong" + gender = FEMALE + //////////////////////////// // Undershirt Definitions // //////////////////////////// @@ -1155,6 +1235,11 @@ icon_state = "shirt_black" gender = NEUTER +/datum/sprite_accessory/undershirt/shirt_blacker + name = "Blacker Shirt" + icon_state = "shirt_blacker" + gender = NEUTER + /datum/sprite_accessory/undershirt/shirt_grey name = "Grey Shirt" icon_state = "shirt_grey" @@ -1206,6 +1291,16 @@ icon_state = "shirt_corgi" gender = NEUTER +/datum/sprite_accessory/undershirt/shirt_clown + name = "Clown Shirt" + icon_state = "shirt_clown" + gender = NEUTER + +/datum/sprite_accessory/undershirt/shirt_alien + name = "Alien Shirt" + icon_state = "shirt_alien" + gender = NEUTER + /datum/sprite_accessory/undershirt/shirt_jack name = "Union Jack Shirt" icon_state = "shirt_jack" @@ -1350,6 +1445,21 @@ //tanktops +/datum/sprite_accessory/undershirt/tank_redtop + name = "Red Crop-Top" + icon_state = "tank_redtop" + gender = FEMALE + +/datum/sprite_accessory/undershirt/tank_whitetop + name = "White Crop-Top" + icon_state = "tank_whitetop" + gender = FEMALE + +/datum/sprite_accessory/undershirt/tank_midriff + name = "White Mid Tank-Top" + icon_state = "tank_midriff" + gender = FEMALE + /datum/sprite_accessory/undershirt/tank_white name = "White Tank-Top" icon_state = "tank_white" @@ -1360,15 +1470,32 @@ icon_state = "tank_black" gender = NEUTER +/datum/sprite_accessory/undershirt/tank_blacker + name = "Blacker Tank-Top" + icon_state = "tank_blacker" + gender = NEUTER + /datum/sprite_accessory/undershirt/tank_grey name = "Grey Tank-Top" icon_state = "tank_grey" gender = NEUTER +/datum/sprite_accessory/undershirt/tank_red + name = "Red Tank-Top" + icon_state = "tank_red" + gender = NEUTER + /datum/sprite_accessory/undershirt/tank_fire name = "Fire Tank-Top" icon_state = "tank_fire" gender = NEUTER + +/datum/sprite_accessory/undershirt/tank_stripes + name = "Striped Tank-Top" + icon_state = "tank_stripes" + gender = NEUTER + + //end tanktops /////////////////////// diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index 57ebadb21a9..cddb25bd118 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -186,7 +186,15 @@ nanoui is used to open and update nano browser uis "autoUpdateContent" = auto_update_content, "showMap" = show_map, "mapZLevel" = map_z_level, - "user" = list("name" = user.name) + "user" = list( + "name" = user.name, + "fancy" = user.client.prefs.nanoui_fancy + ), + "window" = list( + "width" = width, + "height" = height, + "ref" = window_id + ) ) return config_data @@ -334,7 +342,6 @@ nanoui is used to open and update nano browser uis /datum/nanoui/proc/get_html() // before the UI opens, add the layout files based on the layout key - add_stylesheet("layout_[layout_key].css") add_template("layout", "layout_[layout_key].tmpl") var/head_content = "" diff --git a/code/modules/projectiles/guns/energy/blueshield.dm b/code/modules/projectiles/guns/energy/blueshield.dm new file mode 100644 index 00000000000..1ba9e26eba1 --- /dev/null +++ b/code/modules/projectiles/guns/energy/blueshield.dm @@ -0,0 +1,37 @@ +/obj/item/weapon/gun/energy/blueshield + name = "advanced stun revolver" + desc = "An advanced stun revolver with the capacity to shoot both electrodes and lasers." + icon_state = "bsgun_stun" + item_state = "gun" + modifystate = "bsgun_stun" + force = 7 + fire_sound = 'sound/weapons/gunshot.ogg' + charge_cost = 2000 + projectile_type = "/obj/item/projectile/energy/electrode" + fire_delay = 15 + var/fire_mode = 0 // 0 for taser, 1 for lethals. + +/obj/item/weapon/gun/energy/blueshield/attack_self(mob/living/user as mob) + if(!fire_mode) + fire_mode = 1 + charge_cost = 1000 + fire_delay = 0 + + fire_sound = 'sound/weapons/Laser.ogg' + projectile_type = "/obj/item/projectile/beam" + modifystate = "bsgun_kill" + + user << "You adjust [src.name] to the kill setting." + + else + fire_mode = 0 + charge_cost = 2000 + fire_delay = 15 + + projectile_type = "/obj/item/projectile/energy/electrode" + fire_sound = 'sound/weapons/gunshot.ogg' + modifystate = "bsgun_stun" + + user << "You adjust [src.name] to the stun setting." + + update_icon() \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/pulse.dm b/code/modules/projectiles/guns/energy/pulse.dm index fbf71b120ed..e063a6b3bdf 100644 --- a/code/modules/projectiles/guns/energy/pulse.dm +++ b/code/modules/projectiles/guns/energy/pulse.dm @@ -80,6 +80,9 @@ item_state = "gun" cell_type = "/obj/item/weapon/stock_parts/cell/pulse/pistol" +/obj/item/weapon/gun/energy/pulse_rifle/pistol/isHandgun() + return 1 + /obj/item/weapon/gun/energy/pulse_rifle/pistol/m1911 name = "\improper M1911-P" desc = "A compact pulse core in a classic handgun frame for Nanotrasen officers. It's not the size of the gun, it's the size of the hole it puts through people." diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index f69b903b3be..d73f7ffee1a 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -74,6 +74,9 @@ if (chambered) user << "A [chambered.BB ? "live" : "spent"] one is in the chamber." +/obj/item/weapon/gun/projectile/shotgun/isHandgun() //You cannot, in fact, holster a shotgun. + return 0 + // RIOT SHOTGUN // /obj/item/weapon/gun/projectile/shotgun/riot //for spawn in the armory @@ -160,6 +163,9 @@ else user << "[src] is empty." +/obj/item/weapon/gun/projectile/revolver/doublebarrel/isHandgun() //contrary to popular opinion, double barrels are not, shockingly, handguns + return 0 + // IMPROVISED SHOTGUN // /obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index a516e906e83..b632503f012 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -1679,9 +1679,10 @@ return Expand() /obj/item/weapon/reagent_containers/food/snacks/monkeycube/proc/Expand() - visible_message("[src] expands!") - new/mob/living/carbon/human(get_turf(src),monkey_type) - qdel(src) + if(isnull(gcDestroyed)) + visible_message("[src] expands!") + new/mob/living/carbon/human(get_turf(src),monkey_type) + qdel(src) /obj/item/weapon/reagent_containers/food/snacks/monkeycube/proc/Unwrap(mob/user) icon_state = "monkeycube" diff --git a/code/modules/security_levels/security levels.dm b/code/modules/security_levels/security levels.dm index 051d7b502cf..61b0d3ce0dc 100644 --- a/code/modules/security_levels/security levels.dm +++ b/code/modules/security_levels/security levels.dm @@ -31,36 +31,44 @@ if(SEC_LEVEL_GREEN) security_announcement_down.Announce("All threats to the station have passed. All weapons need to be holstered and privacy laws are once again fully enforced.","Attention! Security level lowered to green.") security_level = SEC_LEVEL_GREEN - + + var/obj/machinery/computer/communications/CC = locate(/obj/machinery/computer/communications,world) + if(CC) + CC.post_status("alert", "outline") + for(var/obj/machinery/firealarm/FA in world) if((FA.z in config.contact_levels)) FA.overlays = list() - FA.overlays += image('icons/obj/monitors.dmi', "overlay_green") - + FA.overlays += image('icons/obj/monitors.dmi', "overlay_green") + if(SEC_LEVEL_BLUE) if(security_level < SEC_LEVEL_BLUE) security_announcement_up.Announce("The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible and random searches are permitted.","Attention! Security level elevated to blue.") else security_announcement_down.Announce("The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed.","Attention! Security level lowered to blue.") security_level = SEC_LEVEL_BLUE - + + var/obj/machinery/computer/communications/CC = locate(/obj/machinery/computer/communications,world) + if(CC) + CC.post_status("alert", "outline") + for(var/obj/machinery/firealarm/FA in world) if((FA.z in config.contact_levels)) FA.overlays = list() FA.overlays += image('icons/obj/monitors.dmi', "overlay_blue") - + if(SEC_LEVEL_RED) if(security_level < SEC_LEVEL_RED) security_announcement_up.Announce("There is an immediate and serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised.","Attention! Code Red!") else security_announcement_down.Announce("The station's self-destruct mechanism has been deactivated, but there is still an immediate and serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised.","Attention! Code Red!") security_level = SEC_LEVEL_RED - + var/obj/machinery/door/airlock/highsecurity/red/R = locate(/obj/machinery/door/airlock/highsecurity/red) in world if(R && (R.z in config.station_levels)) R.locked = 0 R.update_icon() - + var/obj/machinery/computer/communications/CC = locate(/obj/machinery/computer/communications,world) if(CC) CC.post_status("alert", "redalert") @@ -69,27 +77,27 @@ if((FA.z in config.contact_levels)) FA.overlays = list() FA.overlays += image('icons/obj/monitors.dmi', "overlay_red") - + if(SEC_LEVEL_GAMMA) security_announcement_up.Announce("Central Command has ordered the Gamma security level on the station. Security is to have weapons equipped at all times, and all civilians are to immediately seek their nearest head for transportation to a secure location. The station's Gamma armory has been unlocked and is ready for use.","Attention! Gamma security level activated!") security_level = SEC_LEVEL_GAMMA - + move_gamma_ship() - + if(security_level < SEC_LEVEL_RED) for(var/obj/machinery/door/airlock/highsecurity/red/R in world) if((R.z in config.station_levels)) R.locked = 0 R.update_icon() - + for(var/obj/machinery/door/airlock/hatch/gamma/H in world) if((H.z in config.station_levels)) H.locked = 0 H.update_icon() - + var/obj/machinery/computer/communications/CC = locate(/obj/machinery/computer/communications,world) if(CC) - CC.post_status("alert", "redalert") + CC.post_status("alert", "gammaalert") for(var/obj/machinery/firealarm/FA in world) if((FA.z in config.contact_levels)) @@ -100,10 +108,10 @@ if(SEC_LEVEL_EPSILON) security_announcement_up.Announce("Central Command has ordered the Epsilon security level on the station. Consider all contracts terminated.","Attention! Epsilon security level activated!") security_level = SEC_LEVEL_EPSILON - + var/obj/machinery/computer/communications/CC = locate(/obj/machinery/computer/communications,world) if(CC) - CC.post_status("alert", "redalert") + CC.post_status("alert", "epsilonalert") for(var/obj/machinery/firealarm/FA in world) if((FA.z in config.contact_levels)) @@ -113,16 +121,16 @@ if(SEC_LEVEL_DELTA) security_announcement_up.Announce("The station's self-destruct mechanism has been engaged. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill.","Attention! Delta security level reached!") security_level = SEC_LEVEL_DELTA - + var/obj/machinery/computer/communications/CC = locate(/obj/machinery/computer/communications,world) if(CC) - CC.post_status("alert", "redalert") - + CC.post_status("alert", "deltaalert") + for(var/obj/machinery/firealarm/FA in world) if((FA.z in config.contact_levels)) FA.overlays = list() FA.overlays += image('icons/obj/monitors.dmi', "overlay_delta") - + else return diff --git a/code/modules/surgery/organs/blood.dm b/code/modules/surgery/organs/blood.dm index 40466818695..60dd2f1f10c 100644 --- a/code/modules/surgery/organs/blood.dm +++ b/code/modules/surgery/organs/blood.dm @@ -138,10 +138,6 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 var/word = pick("dizzy","woosey","faint") src << "\red You feel extremely [word]" if(0 to BLOOD_VOLUME_SURVIVE) - // There currently is a strange bug here. If the mob is not below -100 health - // when death() is called, apparently they will be just fine, and this way it'll - // spam deathgasp. Adjusting toxloss ensures the mob will stay dead. - toxloss += 300 // just to be safe! death() // Without enough blood you slowly go hungry. diff --git a/code/world.dm b/code/world.dm index 5c9e86d963f..5f60f4aa5cf 100644 --- a/code/world.dm +++ b/code/world.dm @@ -210,6 +210,15 @@ var/world_topic_spam_protect_time = world.timeofday return show_player_info_irc(input["notes"]) + else if (copytext(T,1,9) == "announce") + var/input[] = params2list(T) + if(config.comms_password) + if(input["key"] != config.comms_password) + return "Bad Key" + else + for(var/client/C in clients) + C << "PR: [input["announce"]]" + /world/Reboot(var/reason, var/feedback_c, var/feedback_r, var/time) if (reason == 1) //special reboot, do none of the normal stuff if(usr) diff --git a/html/changelog.html b/html/changelog.html index e9d8690a977..909ef42baf8 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -55,6 +55,144 @@ -->
+

20 January 2016

+

DarkPyrolord updated:

+
    +
  • Adds in hardsuit sprites for Vulpkanin
  • +
+

FalseIncarnate updated:

+
    +
  • Allowed cheap lighters and individual matches to be put into cigarette packages at the cost of cigarette space.
  • +
  • Matches can now be lit and put out by striking the match on your shoes. Good for if you lose that matchbox, or want to just feel cool.
  • +
+

Fox McCloud updated:

+
    +
  • Fixes brute damage on weapons not knocking people down.
  • +
  • Tweaks implant behavior to be more consistent and unified.
  • +
  • Lowers the pAI cooldown from 60 seconds to 5 seconds.
  • +
  • Raw telecrystal can now be used to charge uplink implants.
  • +
  • Fixes being unable to holster the pulse pistol
  • +
  • Fixes being able to holster shotguns
  • +
+

KasparoVy updated:

+
    +
  • Improved shading on all Vulpkanin hardsuit tails.
  • +
  • Vulpkanin hardsuit helmet respriting (colour tweaks).
  • +
  • Vulpkanin hardsuit helmets with proper flashlight-on sprites.
  • +
+

Tastyfish updated:

+
    +
  • The ID computer Access Report printout now separates the access list with commas so it's actually readable.
  • +
  • The ID computer Access Report printout isn't blank if you don't have an authorization card in anymore.
  • +
  • In the supply ordering & shuttle consoles, one can now cancel an order at either the Reason or Amount input dialogs.
  • +
  • Table flipping uses correct sprites.
  • +
+

TheDZD updated:

+
    +
  • Adds world.Topic() handling so that users are notified in-game when pull requests are opened, closed, or merged on the Github repo.
  • +
+ +

18 January 2016

+

Crazylemon updated:

+
    +
  • New classes of shapeshifters have been sighted around the NSS Cyberiad...
  • +
  • Wizards now can't teleport to other antag spawn points.
  • +
  • Removes an extruding pixel from the left-facing IPC glider monitor sprite.
  • +
  • Ragin' Mages now spawn every 7 minutes, instead of 5. Admins can further adjust this by modifying the 'delay_per_mage' variable.
  • +
  • Ragin' Mages are now made with 100% less in-use souls (Apprentices won't have their consciousness yoinked).
  • +
  • It takes half an hour for the REAL chaos of ragin' mages to start, for at least a semblance of normality.
  • +
+

Dave The Headcrab updated:

+
    +
  • Adds the advanced energy revolver, toggles between taser and laser modes.
  • +
  • Removes the detective's revolver from the blueshield's locker.
  • +
  • Changes the taser the blueshield starts with into an advanced energy revolver.
  • +
+

Deanthelis updated:

+
    +
  • Added the ability for the Magnetic Gripper to pick up and place light tiles.
  • +
+

Fethas updated:

+
    +
  • Readds the hud icon showing up for master and servent
  • +
  • adds mindslave datum hud thingy based on TGs gang huds
  • +
+

Fox McCloud updated:

+
    +
  • Fixes not being able to add/remove Weapon Permit from IDs.
  • +
  • Fixes the energy sword being invisible in-hand when turned on.
  • +
  • Fixes the telebaton being invisible in-hand when extended.
  • +
  • Fixes eye-stabbing not having an attack animation or hitsound.
  • +
  • Fixes some kitchen utensils playing the wrong hit-sound and playing twice in some cases.
  • +
  • Fixes the butcher cleaver sprite being backwards.
  • +
  • Fixes the telebaton sprite being missing from the side.
  • +
  • Fixes the meat cleaver being invisible in-hand.
  • +
  • Corrects some grammatical descriptive errors for the elite syndicate hardsuit.
  • +
  • completely overhauls implants to TG's standards.
  • +
  • Adds storage implant.
  • +
  • Adds microbomb and macrobomb implants.
  • +
  • Adds in support for removing implants directly into cases.
  • +
  • Removes Bay style explosive implants.
  • +
  • Removes compressed matter implants.
  • +
  • Tweaks the uplink to reflect removal of the old implants and inclusion of the new.
  • +
  • Fixes/cuts down on the lag caused by monkey cubes.
  • +
+

Jey updated:

+
    +
  • Inflatable walls and door can now be deflated by altclicking them
  • +
  • Fixed lag from expanding multiple monkeycubes at once.
  • +
+

KasparoVy updated:

+
    +
  • Adds blank icons with standardized timings for species tail wagging, used in icon generation.
  • +
  • Fixes tails overlapping arms/limbs + gloves, etc. when facing EAST or WEST.
  • +
  • Ensures tails will overlap stuff as normal only when facing NORTH so as to avoid unwanted interference with the base sprite.
  • +
  • Tails now appear in ID cards, overlays things correctly.
  • +
  • Tails now overlay and are overlaid by things correctly in preview icons.
  • +
  • Modifies the positioning of tail icon generation in the ID card preview icon generation file.
  • +
  • Modifies the positioning of tail icon generation in the player preferences preview icon generation file.
  • +
  • Breaks limb generation into its own layer, breaks tail generation into a second layer that can be overlaid by limbs.
  • +
  • If the user's species is flagged to have a tail that is overlapped, TAIL_LAYER will now overlay the NORTH direction sprite of a tail now, while TAIL_UNDERLIMBS_LAYER gets all remaining directions. Otherwise icons are generated in the traditional manner.
  • +
  • Adjusts the Unathi right arm east direction and animated tail sprites, recolouring a random pixel and fixing a floating tail respectively.
  • +
  • Adjusts position of tail layer such that tails' north direction sprites will overlay backpacks (more importantly, satchel straps).
  • +
  • Accommodates admin-overrides to the body_accessory species check by setting the default animation template to Vulpkanin.
  • +
  • Adjusts north-direction Unathi static tail sprite, now attaches to the body in the correct location.
  • +
  • Adds some TG underwear.
  • +
  • Adds an NV science goggles worn sprite.
  • +
  • Ports Bay/TG berets.
  • +
  • Adjusts beret sprite, recolours strange orange pixels.
  • +
  • Adjusts NV science goggles object icon. Removed strange border and centered it.
  • +
  • Ports Polaris' PRs 761 and 778, brings over Ragnie's awesome Ward-Takahashi prosthetics.
  • +
+

Kyep updated:

+
    +
  • Changing level to gamma/delta/epsilon now displays a special gamma/delta/epsilon sprite on status monitors
  • +
  • Changing level to green/blue now clears the status monitors, so they no longer show higher alert levels after the level is changed
  • +
+

NTSAM updated:

+
    +
  • Added a rainbow IPC screen.
  • +
+

PPI updated:

+
    +
  • Modifies the effective time limit to activate the Nuclear Challenge as Nukeops from two minutes to seven minutes
  • +
+

Tastyfish updated:

+
    +
  • The QM now actually has a QM stamp instead of a fake one, as well as an approved and denied stamp.
  • +
  • New area named 'Genetics Maintenance' solidifying/relabelling the confusing area between the morge and Mech Bay as being fully maintenance again, but working correctly and with proper doors.
  • +
  • Fixed a few maintenance door names to be in parity to the rest of the station.
  • +
  • Added the ability to print the records photo of a crew member from a security records console. Useful for Wanted notices!
  • +
+

Tigercat2000 updated:

+
    +
  • You can no longer use the gibber for monkies.
  • +
  • Cleaned up gibber.dm styling.
  • +
  • The fire alarm now uses NanoUI, with color coded alert levels.
  • +
  • Upgraded NanoUI (again), fancy FontAwesome icons.
  • +
  • Didn't add any butts. Yet.
  • +
+

13 January 2016

Fox McCloud updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 0da7cceab4e..f880e8a82b7 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -106,3 +106,139 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. Tastyfish: - tweak: NT Rep fountain pens and magistrate gold pens can now write in 5 different colors. The IAA gets a cheap plastic equivalent. +2016-01-18: + Crazylemon: + - rscadd: New classes of shapeshifters have been sighted around the NSS Cyberiad... + - bugfix: Wizards now can't teleport to other antag spawn points. + - bugfix: Removes an extruding pixel from the left-facing IPC glider monitor sprite. + - tweak: Ragin' Mages now spawn every 7 minutes, instead of 5. Admins can further + adjust this by modifying the 'delay_per_mage' variable. + - bugfix: Ragin' Mages are now made with 100% less in-use souls (Apprentices won't + have their consciousness yoinked). + - tweak: It takes half an hour for the REAL chaos of ragin' mages to start, for + at least a semblance of normality. + Dave The Headcrab: + - rscadd: Adds the advanced energy revolver, toggles between taser and laser modes. + - rscdel: Removes the detective's revolver from the blueshield's locker. + - tweak: Changes the taser the blueshield starts with into an advanced energy revolver. + Deanthelis: + - rscadd: Added the ability for the Magnetic Gripper to pick up and place light + tiles. + Fethas: + - bugfix: Readds the hud icon showing up for master and servent + - rscadd: adds mindslave datum hud thingy based on TGs gang huds + Fox McCloud: + - bugfix: Fixes not being able to add/remove Weapon Permit from IDs. + - bugfix: Fixes the energy sword being invisible in-hand when turned on. + - bugfix: Fixes the telebaton being invisible in-hand when extended. + - bugfix: Fixes eye-stabbing not having an attack animation or hitsound. + - bugfix: Fixes some kitchen utensils playing the wrong hit-sound and playing twice + in some cases. + - bugfix: Fixes the butcher cleaver sprite being backwards. + - bugfix: Fixes the telebaton sprite being missing from the side. + - bugfix: Fixes the meat cleaver being invisible in-hand. + - spellcheck: Corrects some grammatical descriptive errors for the elite syndicate + hardsuit. + - rscadd: completely overhauls implants to TG's standards. + - rscadd: Adds storage implant. + - rscadd: Adds microbomb and macrobomb implants. + - rscadd: Adds in support for removing implants directly into cases. + - rscdel: Removes Bay style explosive implants. + - rscdel: Removes compressed matter implants. + - tweak: Tweaks the uplink to reflect removal of the old implants and inclusion + of the new. + - bugfix: Fixes/cuts down on the lag caused by monkey cubes. + Jey: + - tweak: Inflatable walls and door can now be deflated by altclicking them + - bugfix: Fixed lag from expanding multiple monkeycubes at once. + KasparoVy: + - imageadd: Adds blank icons with standardized timings for species tail wagging, + used in icon generation. + - bugfix: Fixes tails overlapping arms/limbs + gloves, etc. when facing EAST or + WEST. + - bugfix: Ensures tails will overlap stuff as normal only when facing NORTH so as + to avoid unwanted interference with the base sprite. + - bugfix: Tails now appear in ID cards, overlays things correctly. + - bugfix: Tails now overlay and are overlaid by things correctly in preview icons. + - tweak: Modifies the positioning of tail icon generation in the ID card preview + icon generation file. + - tweak: Modifies the positioning of tail icon generation in the player preferences + preview icon generation file. + - tweak: Breaks limb generation into its own layer, breaks tail generation into + a second layer that can be overlaid by limbs. + - tweak: If the user's species is flagged to have a tail that is overlapped, TAIL_LAYER + will now overlay the NORTH direction sprite of a tail now, while TAIL_UNDERLIMBS_LAYER + gets all remaining directions. Otherwise icons are generated in the traditional + manner. + - tweak: Adjusts the Unathi right arm east direction and animated tail sprites, + recolouring a random pixel and fixing a floating tail respectively. + - tweak: Adjusts position of tail layer such that tails' north direction sprites + will overlay backpacks (more importantly, satchel straps). + - tweak: Accommodates admin-overrides to the body_accessory species check by setting + the default animation template to Vulpkanin. + - tweak: Adjusts north-direction Unathi static tail sprite, now attaches to the + body in the correct location. + - rscadd: Adds some TG underwear. + - rscadd: Adds an NV science goggles worn sprite. + - rscadd: Ports Bay/TG berets. + - tweak: Adjusts beret sprite, recolours strange orange pixels. + - tweak: Adjusts NV science goggles object icon. Removed strange border and centered + it. + - rscadd: Ports Polaris' PRs 761 and 778, brings over Ragnie's awesome Ward-Takahashi + prosthetics. + Kyep: + - rscadd: Changing level to gamma/delta/epsilon now displays a special gamma/delta/epsilon + sprite on status monitors + - bugfix: Changing level to green/blue now clears the status monitors, so they no + longer show higher alert levels after the level is changed + NTSAM: + - rscadd: Added a rainbow IPC screen. + PPI: + - tweak: Modifies the effective time limit to activate the Nuclear Challenge as + Nukeops from two minutes to seven minutes + Tastyfish: + - rscadd: The QM now actually has a QM stamp instead of a fake one, as well as an + approved and denied stamp. + - rscadd: New area named 'Genetics Maintenance' solidifying/relabelling the confusing + area between the morge and Mech Bay as being fully maintenance again, but working + correctly and with proper doors. + - spellcheck: Fixed a few maintenance door names to be in parity to the rest of + the station. + - rscadd: Added the ability to print the records photo of a crew member from a security + records console. Useful for Wanted notices! + Tigercat2000: + - rscdel: You can no longer use the gibber for monkies. + - spellcheck: Cleaned up gibber.dm styling. + - rscadd: The fire alarm now uses NanoUI, with color coded alert levels. + - tweak: Upgraded NanoUI (again), fancy FontAwesome icons. + - wip: Didn't add any butts. Yet. +2016-01-20: + DarkPyrolord: + - rscadd: Adds in hardsuit sprites for Vulpkanin + FalseIncarnate: + - rscadd: Allowed cheap lighters and individual matches to be put into cigarette + packages at the cost of cigarette space. + - rscadd: Matches can now be lit and put out by striking the match on your shoes. + Good for if you lose that matchbox, or want to just feel cool. + Fox McCloud: + - bugfix: Fixes brute damage on weapons not knocking people down. + - tweaks: Tweaks implant behavior to be more consistent and unified. + - tweak: Lowers the pAI cooldown from 60 seconds to 5 seconds. + - rscadd: Raw telecrystal can now be used to charge uplink implants. + - bugfix: Fixes being unable to holster the pulse pistol + - bugfix: Fixes being able to holster shotguns + KasparoVy: + - tweak: Improved shading on all Vulpkanin hardsuit tails. + - tweak: Vulpkanin hardsuit helmet respriting (colour tweaks). + - rscadd: Vulpkanin hardsuit helmets with proper flashlight-on sprites. + Tastyfish: + - tweak: The ID computer Access Report printout now separates the access list with + commas so it's actually readable. + - bugfix: The ID computer Access Report printout isn't blank if you don't have an + authorization card in anymore. + - rscadd: In the supply ordering & shuttle consoles, one can now cancel an order + at either the Reason or Amount input dialogs. + - bugfix: Table flipping uses correct sprites. + TheDZD: + - rscadd: Adds world.Topic() handling so that users are notified in-game when pull + requests are opened, closed, or merged on the Github repo. diff --git a/html/changelogs/AutoChangeLog-pr-3297.yml b/html/changelogs/AutoChangeLog-pr-3297.yml new file mode 100644 index 00000000000..6ec85f85392 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3297.yml @@ -0,0 +1,5 @@ +author: Tastyfish +delete-after: True +changes: + - rscadd: "Poly has taken a seminar on the latest trends in engine operations." + - rscadd: "Player-controller parrots can now hear their headsets." diff --git a/html/changelogs/AutoChangeLog-pr-3305.yml b/html/changelogs/AutoChangeLog-pr-3305.yml new file mode 100644 index 00000000000..8dd8c60a9a9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3305.yml @@ -0,0 +1,5 @@ +author: Fox McCloud +delete-after: True +changes: + - rscdel: "Removes Vampire HUD" + - tweak: "moves the Vampire blood counter to a more easy to see location" diff --git a/html/changelogs/AutoChangeLog-pr-3314.yml b/html/changelogs/AutoChangeLog-pr-3314.yml new file mode 100644 index 00000000000..0e2e2aab2e6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3314.yml @@ -0,0 +1,4 @@ +author: Fox McCloud +delete-after: True +changes: + - bugfix: "Fixes unnecessary toxin damage being dealt on severe bloodloss" diff --git a/html/changelogs/AutoChangeLog-pr-3318.yml b/html/changelogs/AutoChangeLog-pr-3318.yml new file mode 100644 index 00000000000..4ef10030f9a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3318.yml @@ -0,0 +1,4 @@ +author: Fox McCloud +delete-after: True +changes: + - bugfix: "Fixes human mobs not receiving proper random names" diff --git a/html/changelogs/Jey-monkeycubefix.yml b/html/changelogs/Jey-monkeycubefix.yml deleted file mode 100644 index 5a70c2dfaaa..00000000000 --- a/html/changelogs/Jey-monkeycubefix.yml +++ /dev/null @@ -1,35 +0,0 @@ -################################ -# Example Changelog File -# -# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. -# -# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) -# When it is, any changes listed below will disappear. -# -# Valid Prefixes: -# bugfix -# wip (For works in progress) -# tweak -# soundadd -# sounddel -# rscadd (general adding of nice things) -# rscdel (general deleting of nice things) -# imageadd -# imagedel -# spellcheck (typo fixes) -# experiment -################################# - -# Your name. Remove the quotation mark and put in your name when copy+pasting the example changelog. -author: Jey - -# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. -delete-after: True - -# Any changes you've made. See valid prefix list above. -# INDENT WITH TWO SPACES. NOT TABS. SPACES. -# SCREW THIS UP AND IT WON'T WORK. -# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. -# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. -changes: - - bugfix: "Fixed lag from expanding multiple monkeycubes at once." diff --git a/html/changelogs/KasparoVy-PR-TBD.yml b/html/changelogs/KasparoVy-PR-TBD.yml deleted file mode 100644 index bec680e01d6..00000000000 --- a/html/changelogs/KasparoVy-PR-TBD.yml +++ /dev/null @@ -1,35 +0,0 @@ -################################ -# Example Changelog File -# -# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. -# -# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) -# When it is, any changes listed below will disappear. -# -# Valid Prefixes: -# bugfix -# wip (For works in progress) -# tweak -# soundadd -# sounddel -# rscadd (general adding of nice things) -# rscdel (general deleting of nice things) -# imageadd -# imagedel -# spellcheck (typo fixes) -# experiment -################################# - -# Your name. Remove the quotation mark and put in your name when copy+pasting the example changelog. -author: KasparoVy - -# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. -delete-after: True - -# Any changes you've made. See valid prefix list above. -# INDENT WITH TWO SPACES. NOT TABS. SPACES. -# SCREW THIS UP AND IT WON'T WORK. -# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. -# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. -changes: - - rscadd: "Ports Polaris' PRs 761 and 778, brings over Ragnie's awesome Ward-Takahashi prosthetics." diff --git a/icons/effects/species.dmi b/icons/effects/species.dmi index e339fbbdce1..7096b2d360a 100644 Binary files a/icons/effects/species.dmi and b/icons/effects/species.dmi differ diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index 47a0c11e9b2..4b839a4bf66 100644 Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ diff --git a/icons/mob/body_accessory.dmi b/icons/mob/body_accessory.dmi index f79b4c262f1..92068cd07ac 100644 Binary files a/icons/mob/body_accessory.dmi and b/icons/mob/body_accessory.dmi differ diff --git a/icons/mob/eyes.dmi b/icons/mob/eyes.dmi index 1ddea3482f5..d7cfb2d1889 100644 Binary files a/icons/mob/eyes.dmi and b/icons/mob/eyes.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index 240314dbb85..a1abbab88fa 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index b7486d89af9..9b2a74768d1 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi index ffecceda82e..7eec478d96b 100644 Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ diff --git a/icons/mob/human_races/r_lizard.dmi b/icons/mob/human_races/r_lizard.dmi index b351428779d..457e50b204e 100644 Binary files a/icons/mob/human_races/r_lizard.dmi and b/icons/mob/human_races/r_lizard.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index 0bd148505c7..db12504dfc7 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 91976e05514..fdbfca0615c 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/screen1_Vampire.dmi b/icons/mob/screen1_Vampire.dmi deleted file mode 100644 index 6a30aa697d8..00000000000 Binary files a/icons/mob/screen1_Vampire.dmi and /dev/null differ diff --git a/icons/mob/species/tajaran/helmet.dmi b/icons/mob/species/tajaran/helmet.dmi index 5fd99d65ec5..daee56b2e14 100644 Binary files a/icons/mob/species/tajaran/helmet.dmi and b/icons/mob/species/tajaran/helmet.dmi differ diff --git a/icons/mob/species/vulpkanin/helmet.dmi b/icons/mob/species/vulpkanin/helmet.dmi new file mode 100644 index 00000000000..06dc34ff68e Binary files /dev/null and b/icons/mob/species/vulpkanin/helmet.dmi differ diff --git a/icons/mob/species/vulpkanin/suit.dmi b/icons/mob/species/vulpkanin/suit.dmi new file mode 100644 index 00000000000..31b6d96f4cd Binary files /dev/null and b/icons/mob/species/vulpkanin/suit.dmi differ diff --git a/icons/mob/underwear.dmi b/icons/mob/underwear.dmi index 1f22d1f159b..ad2327aab2d 100644 Binary files a/icons/mob/underwear.dmi and b/icons/mob/underwear.dmi differ diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi index bce4c3851a8..894d49a9adf 100644 Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index e16c5188681..a7c70887251 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/species/vulpkanin/hats.dmi b/icons/obj/clothing/species/vulpkanin/hats.dmi new file mode 100644 index 00000000000..ee64e02158f Binary files /dev/null and b/icons/obj/clothing/species/vulpkanin/hats.dmi differ diff --git a/icons/obj/clothing/species/vulpkanin/suits.dmi b/icons/obj/clothing/species/vulpkanin/suits.dmi new file mode 100644 index 00000000000..22617558677 Binary files /dev/null and b/icons/obj/clothing/species/vulpkanin/suits.dmi differ diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi index 0ceb1f7d7f0..d2eca5637a7 100644 Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ diff --git a/icons/obj/implants.dmi b/icons/obj/implants.dmi new file mode 100644 index 00000000000..8dc2f08fdcb Binary files /dev/null and b/icons/obj/implants.dmi differ diff --git a/icons/obj/status_display.dmi b/icons/obj/status_display.dmi index 0a26d3bc58c..a2dbd15e2f0 100644 Binary files a/icons/obj/status_display.dmi and b/icons/obj/status_display.dmi differ diff --git a/nano/Gulpfile.coffee b/nano/Gulpfile.coffee index fbd8abd45fc..a8c604a2280 100644 --- a/nano/Gulpfile.coffee +++ b/nano/Gulpfile.coffee @@ -5,11 +5,14 @@ s = # Project Paths input = - fonts: "**/*.{eot,woff2}" + fonts: "**/*.{eot,woff2}" + images: "images" + layouts: "layouts/" scripts: - lib: "scripts/libraries" - main: "scripts/nano" + lib: "scripts/libraries" + main: "scripts/nano" styles: "styles" + templates: "templates/" output = dir: "assets" @@ -20,6 +23,7 @@ output = ### Pacakages ### bower = require "main-bower-files" +child_process = require "child_process" del = require "del" gulp = require "gulp" merge = require "merge-stream" @@ -45,12 +49,28 @@ gulp.task "default", ["fonts", "scripts", "styles"] gulp.task "clean", -> del glob output.dir +gulp.task "watch", -> + gulp.watch [glob input.images], ["reload"] + gulp.watch [glob input.layouts], ["reload"] + gulp.watch [glob input.scripts.lib], ["reload"] + gulp.watch [glob input.scripts.main], ["reload"] + gulp.watch [glob input.styles], ["reload"] + gulp.watch [glob input.templates], ["reload"] + +gulp.task "reload", ["default"], -> + child_process.exec "reload.bat", (err, stdout, stderr) -> + return console.log err if err + + gulp.task "fonts", ["clean"], -> gulp.src bower input.fonts .pipe gulp.dest output.dir gulp.task "scripts", ["clean"], -> lib = gulp.src glob input.scripts.lib + etc = gulp.src bower "**/*.js" + + merged = merge lib, etc .pipe g.order(["jquery.js", "jquery*.js", "*.js"]) @@ -66,15 +86,13 @@ gulp.task "scripts", ["clean"], -> .pipe g.if(s.min, g.uglify().on('error', util.log)) .pipe gulp.dest output.dir - merge lib, main - gulp.task "styles", ["clean"], -> lib = gulp.src bower "**/*.css" .pipe g.replace("../fonts/", "") main = gulp.src glob input.styles .pipe g.filter(["*.less", "!_*.less"]) - .pipe g.less() + .pipe g.less({paths: [input.images]}) .pipe g.postcss([ p.autoprefixer({browsers: ["last 2 versions", "ie >= 8"]}), p.gradient, diff --git a/nano/assets/libraries.min.js b/nano/assets/libraries.min.js index a7a9d42ff80..047902609a2 100644 --- a/nano/assets/libraries.min.js +++ b/nano/assets/libraries.min.js @@ -1,5 +1,5 @@ -!function(e,t){"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){function n(e){var t="length"in e&&e.length,n=oe.type(e);return"function"===n||oe.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e}function i(e,t,n){if(oe.isFunction(t))return oe.grep(e,function(e,i){return!!t.call(e,i,e)!==n});if(t.nodeType)return oe.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(de.test(t))return oe.filter(t,e,n);t=oe.filter(t,e)}return oe.grep(e,function(e){return oe.inArray(e,t)>=0!==n})}function o(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}function r(e){var t=xe[e]={};return oe.each(e.match(be)||[],function(e,n){t[n]=!0}),t}function s(){he.addEventListener?(he.removeEventListener("DOMContentLoaded",a,!1),e.removeEventListener("load",a,!1)):(he.detachEvent("onreadystatechange",a),e.detachEvent("onload",a))}function a(){(he.addEventListener||"load"===event.type||"complete"===he.readyState)&&(s(),oe.ready())}function l(e,t,n){if(void 0===n&&1===e.nodeType){var i="data-"+t.replace(Ne,"-$1").toLowerCase();if(n=e.getAttribute(i),"string"==typeof n){try{n="true"===n?!0:"false"===n?!1:"null"===n?null:+n+""===n?+n:Ce.test(n)?oe.parseJSON(n):n}catch(o){}oe.data(e,t,n)}else n=void 0}return n}function u(e){var t;for(t in e)if(("data"!==t||!oe.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}function c(e,t,n,i){if(oe.acceptData(e)){var o,r,s=oe.expando,a=e.nodeType,l=a?oe.cache:e,u=a?e[s]:e[s]&&s;if(u&&l[u]&&(i||l[u].data)||void 0!==n||"string"!=typeof t)return u||(u=a?e[s]=Q.pop()||oe.guid++:s),l[u]||(l[u]=a?{}:{toJSON:oe.noop}),("object"==typeof t||"function"==typeof t)&&(i?l[u]=oe.extend(l[u],t):l[u].data=oe.extend(l[u].data,t)),r=l[u],i||(r.data||(r.data={}),r=r.data),void 0!==n&&(r[oe.camelCase(t)]=n),"string"==typeof t?(o=r[t],null==o&&(o=r[oe.camelCase(t)])):o=r,o}}function f(e,t,n){if(oe.acceptData(e)){var i,o,r=e.nodeType,s=r?oe.cache:e,a=r?e[oe.expando]:oe.expando;if(s[a]){if(t&&(i=n?s[a]:s[a].data)){oe.isArray(t)?t=t.concat(oe.map(t,oe.camelCase)):t in i?t=[t]:(t=oe.camelCase(t),t=t in i?[t]:t.split(" ")),o=t.length;for(;o--;)delete i[t[o]];if(n?!u(i):!oe.isEmptyObject(i))return}(n||(delete s[a].data,u(s[a])))&&(r?oe.cleanData([e],!0):ne.deleteExpando||s!=s.window?delete s[a]:s[a]=null)}}}function d(){return!0}function p(){return!1}function h(){try{return he.activeElement}catch(e){}}function g(e){var t=We.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function m(e,t){var n,i,o=0,r=typeof e.getElementsByTagName!==_e?e.getElementsByTagName(t||"*"):typeof e.querySelectorAll!==_e?e.querySelectorAll(t||"*"):void 0;if(!r)for(r=[],n=e.childNodes||e;null!=(i=n[o]);o++)!t||oe.nodeName(i,t)?r.push(i):oe.merge(r,m(i,t));return void 0===t||t&&oe.nodeName(e,t)?oe.merge([e],r):r}function v(e){Pe.test(e.type)&&(e.defaultChecked=e.checked)}function y(e,t){return oe.nodeName(e,"table")&&oe.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function b(e){return e.type=(null!==oe.find.attr(e,"type"))+"/"+e.type,e}function x(e){var t=Ye.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function w(e,t){for(var n,i=0;null!=(n=e[i]);i++)oe._data(n,"globalEval",!t||oe._data(t[i],"globalEval"))}function T(e,t){if(1===t.nodeType&&oe.hasData(e)){var n,i,o,r=oe._data(e),s=oe._data(t,r),a=r.events;if(a){delete s.handle,s.events={};for(n in a)for(i=0,o=a[n].length;o>i;i++)oe.event.add(t,n,a[n][i])}s.data&&(s.data=oe.extend({},s.data))}}function _(e,t){var n,i,o;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!ne.noCloneEvent&&t[oe.expando]){o=oe._data(t);for(i in o.events)oe.removeEvent(t,i,o.handle);t.removeAttribute(oe.expando)}"script"===n&&t.text!==e.text?(b(t).text=e.text,x(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),ne.html5Clone&&e.innerHTML&&!oe.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Pe.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}function C(t,n){var i,o=oe(n.createElement(t)).appendTo(n.body),r=e.getDefaultComputedStyle&&(i=e.getDefaultComputedStyle(o[0]))?i.display:oe.css(o[0],"display");return o.detach(),r}function N(e){var t=he,n=Ze[e];return n||(n=C(e,t),"none"!==n&&n||(Je=(Je||oe("